I have an AJAX GET call that should count all the products matching three different taxonomies.

  • Product families
  • Sectors of application
  • Liquids suitable for the product

so in the form the user could select pumps, agriculture, diesel and the controller called should count the products that matches all those criteria.

I get the solution in the templating engine:

{% set relationParams = ['and', id1, id2, id3 ] %}
{% set products = craft.entries.section('products').relatedTo(relationParams) %}

But something is not working as expected in the controller:

        $prodCriteria = craft()->elements->getCriteria(ElementType::Entry)->section('products');

        $prodCriteria->relatedTo = array(
            'targetElement' => $catIds // Where $catIds is an array of ids
        $products = $prodCriteria->count();

        $this->returnJson( $products );    

It seems like relatedTo behave like an or operator. Also, is it possible to make the relatedTo behave in a more complex way, like, I want to use or for product families and and for other taxonomies?

2 Answers 2


You need to pass an array of element IDs, where the first index is "and" – just like in your template (Twig) code – to targetElement. Basically, this just means that you need to prepend the string "and" to your array of IDs.

Something like this should do it:


$prodCriteria->relatedTo = array(
    'targetElement' => array_merge(['and'], $catIds),
  • Once again, beaten by Mats.
    – Brad Bell
    Sep 25, 2017 at 23:18
  • 1
    Actually, I think you beat me by about 10 seconds. And I edited my answer :) Sep 25, 2017 at 23:21

Completely untested, but I believe what you're looking for is:

array_unshift($catIds , 'and');

$prodCriteria->relatedTo = array(
    'targetElement' => $catIds // Where $catIds is an array of ids

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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