KQL Plugin: custom page model method not allowed in api context

KQL Plugin: I have setup a Page Model Method filterChildrenByCategories, which works fine in PHP, but via kql I get the Following error, any ideas whats wrong? in mentioned file “interceptor.php” there is a method allowedMethods() which return emtpy array :thinking:

{
    "status": "error",
    "message": "The method \"ProjectsPage::filterChildrenByCategories()\" is not allowed in the API context",
    "code": 403,
    "exception": "Kirby\\Exception\\PermissionException",
    "key": "error.permission",
    "file": "../site/plugins/kql/src/Kql/Interceptors/Interceptor.php",
    "line": 38,
    "details": [],
    "route": "query"
}

My Request Body:

{
  "query": "page('projekte').filterChildrenByCategories('foo,bar')",
  "select": {
    "geodata": "page.content.geodata.yaml",
    "id": true,
    "url": true,
    "title": true,
    "text": "page.text.markdown",
    "images": {
      "query": "page.images",
      "select": {
        "url": true
      }
    }
  }
}

The Model:

<?php 

class ProjectsPage extends Page {
  public function filterChildrenByCategories($string = '') {
    $this->string = $string; 
    
    return $this->children()->filterBy(function($project) {
      if ($this->string === '') {
        return $project;
      }
      $project_category_array = $project->category()->split();
      $argument_string_array = explode(',', $this->string);

      foreach ($argument_string_array as $el) {
        if (in_array($el, $project_category_array)) {
          return $project;
        }
      }
    });
  }
}

edit:
page method can be replaced by @texnixe solution:

question about permission in kql remains

I can get it to work, when I hardcode, my method name in site/plugins/kql/src/Kql/Interceptors/Cms/Model.php in allowedMethodsForModels() return value, but is there a better way, via custom plugin or config.php?

While I can’t answer your question I wonder why you need this model method at all instead of:

"query": "page('projekte').children.filterBy('category', 'in', ['foo', 'bar'], ',')"

Thank you for your reply

I need to match pages which can have multiple categories in a type: multiselect (or tags) field, against multiple categories (‘OR’ Filter) where

[X] cat1
[ ] cat2
[X] cat3
[ ] cat4

which I have stored in a js object of categories { name: cat${id}, selected: true }, which I mapped to a string:

cat1, cat3

to be able to use it in a single query (via kql plugin)

it should match:

title: page1
category: cat1, cat2

it also should match

title: page2
category: cat3, cat4, foo

and not match

title: page3
category: cat2, bar

I am not sure how to match with native filter methods, so I came up which the page method and custom filter, domyou have another idea or can put me in right direction?

thanks

That is exactly what the above query does. It will return all results that have either foo or bar in their list of categories.

1 Like

perfect, thank you, I tried this filter against array, but somehow I got it wrong and gave up on it

I leave this thread unsolved for the KQL issue, it’s still of interest to me and maybe helps others in the future

thanks again

I have a feeling that KQL doesn’t allow custom methods as they may be potentially destructive. You might want to add a feature request in the kql repo and reference it here.

make sense

from github readme:

No mutations

KQL only offers access to data in your site. It does not support any mutations. All destructive methods are blocked and cannot be accessed in queries.