2

I have a vocabulary (channel) with two levels. An article node can be added to the first or second level (via field_channel). The hierarchy looks like:

  • channel-1
    • subchannel-1.1
    • subchannel-1.2
    • subchannel-1.3
  • channel-2 (i.e. [node/1, node/2])
    • subchannel-2.1 (i.e. [node/4, node/5])
    • subchannel-2.2 (i.e. [node/6])

I want to filter all nodes that belongs to a term of level 1 (the ones which where assigned directly to the term and the ones which where assigned to one of its child terms).

In other words, filtering all nodes for a given channel (i.e. channel-2) should contain the nodes assigned to that channel directly and all nodes assigned to a sub-channel whose parent channels is that channel. In the example all nodes from 1 to 6.

The JSON:API request looks like:

{{base_url}}/node/article?
include=field_channel,field_channel.parent&
fields[node--article]=title,field_channel&
fields[taxonomy_term--channel]=name,parent&
filter[or-group][group][conjunction]=OR&
filter[channel][condition][path]=field_channel.name&
filter[channel][condition][value]=channel-2&
filter[channel][condition][memberOf]=or-group&
filter[channel-parent][condition][path]=field_channel.parent.name&
filter[channel-parent][condition][value]=channel-2&
filter[channel-parent][condition][memberOf]=or-group    

I don't see the error, but it only contains the nodes matching the channel-parent condition. If I remove that condition, the ones matching the channel condition are there. What is wrong with the request.

I also tried the short form:

{{base_url}}/node/article?
fields[node--article]=title,field_channel&
include=field_channel,field_channel.parent&
fields[taxonomy_term--channel]=name,parent&
filter[or-group][group][conjunction]=OR&
filter[field_channel.name][value]=channel-2&
filter[field_channel.name][memberOf]=or-group&
filter[field_channel.parent.name][value]=channel-2&
filter[field_channel.parent.name][memberOf]=or-group

Which gives me an error in the where clause (the empty group at the beginning):

WHERE (() and (taxonomy_term_field_data.name LIKE :db_condition_placeholder_0 ESCAPE '\\')

BTW: The example could be easily build by using the drupal thunder distribution.

5
  • I have a similar JSON request to your first example and it works without issue. The only difference I saw was that I explicitly set the condition operator, but eliminating that had no effect. I'm thinking the root cause of your problem lies elsewhere.
    – beltouche
    Mar 19, 2020 at 13:43
  • Can you post your code for your query build?
    – dwcdev
    Mar 19, 2020 at 21:23
  • @dwcdev Actually there is no code for the query build.
    – LarS
    Mar 20, 2020 at 13:32
  • What are you using to build the query?
    – dwcdev
    Mar 22, 2020 at 9:33
  • I used Postman. It is transforming the keys and values directly into a query. The query seems valid, doesn't it? {{base_url}} gets replaced with example.lndo.site/jsonapi, my local Lando development environment. As there is an SQL-Error JSON:API accepts the query and processes it, but with that empty group, which I don't know where it comes from.
    – LarS
    Mar 23, 2020 at 12:36

1 Answer 1

0

As the problem may appear for entity types other than taxonomy-terms I briefly explain how to investigate the issue:

I found, that the same query worked well for the admin user, but not for the limited jsonapi consumer. Granting taxonomy related permissions helped, when the jsonapi consumer had the permission "administer taxonomy", which led me to the following hook_jsonapi_ENTITY_TYPE_filter_access implementation in docroot/core/modules/jsonapi/jsonapi.module

/**
 * Implements hook_jsonapi_ENTITY_TYPE_filter_access() for 'taxonomy_term'.
 */
function jsonapi_jsonapi_taxonomy_term_filter_access(EntityTypeInterface $entity_type, AccountInterface $account) {
  // @see \Drupal\taxonomy\TermAccessControlHandler::checkAccess()
  return ([
    JSONAPI_FILTER_AMONG_ALL => AccessResult::allowedIfHasPermission($account, 'administer taxonomy'),
    JSONAPI_FILTER_AMONG_PUBLISHED => AccessResult::allowedIfHasPermission($account, 'access content'),
  ]);
}

Then I implemented the same hook in my custom module with custom permissions and now it works as expected.

I had problems with filtering on paragraphs in past, which has a similar solution, see issue on paragraphs module It is not possible to filter paragraphs via JSON:API.

Looking at hook_jsonapi_ENTITY_TYPE_filter_access() implementations in jsonapi.module suggests that this problem might occur for other entities if the api consumer does not have the corresponding permissions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.