I am looking for some assistance with the Element API plugin. I need to filter on the bannerPageCategories field which is a multi select checkbox field. The value will be passed via a querystring value. I can filter on a field with a single value but how do I do this for fields which has an array of values.

Any suggestions will be greatly appreciated.

Sample code and json response is below.

Json Response:

    {
      title:"Test Banner 4",
      url:"http://localhost:8888/banners/test-banner-4",
      jsonUrl:"http://localhost:8888/api/banners/17",
      content:"Test.", 
       page-categories:[
       {
         label:"ADSL",
         value:"adsl",
         selected:true
       },
       {
        label:"Fibre",
        value:"fibre",
        selected:true
       }
    ],
   campaignId:"sHKJJK",
   targetUrl:"http://xyx.xaws.co.za",
   image1:"//xyx.xaws.co.za/dev/images/banners/banner-lg.png",
   image2:"//xyx.xaws.co.za/dev/images/banners/banner-md.png",
   image3:"//xyx.xaws.co.za/dev/images/banners/banner-sm.png",
   date_published:"2018-05-22T14:06:05+02:00",
   date_modified:"2018-05-22T14:06:05+02:00"
  }

Code:

    'api/banners' => function () {
        \Craft::$app->response->headers->set('Access-Control-Allow-Origin', '*');
        $target = \Craft::$app->request->getQueryParam('target');
        $campaign = \Craft::$app->request->getQueryParam('campaign');
        return [
            'elementType' => Entry::class,
            'criteria' => [
                'section' => 'banners',
                'bannerPageCategories' => $target,
                'campaignId' => $campaign              
            ],
            'transformer' => function (Entry $entry) {
                $image1 = $entry->image1->first();
                $image2 = $entry->image2->first();
                $image3 = $entry->image3->first();

                return [
                    'title' => $entry->title,
                    'url' => $entry->url,
                    'jsonUrl' => UrlHelper::url("api/banners/{$entry->id}"),
                    'content' => $entry->htmlcontent,
                    'page-categories' => $entry->bannerPageCategories,
                    'campaignId' => $entry->campaignId,
                    'targetUrl' => $entry->targetUrl,
                    'image1' => $image1 ? $image1->url : null,
                    'image2' => $image2 ? $image2->url : null,
                    'image3' => $image3 ? $image3->url : null,
                    'date_published' => $entry->postDate->format(\DateTime::ATOM),
                    'date_modified' => $entry->dateUpdated->format(\DateTime::ATOM),
                ];
            },
        ];
    },

Many thanks!

up vote 2 down vote accepted

When you wrap your term in asterisks, e.g. *news*, the generated SQL for this query parameter uses a LIKE operator for the ANDWHERE condition is uses (see Element Queries).

Make sure that the values for the Select field don’t overlap (sportnews and news both matching *news*).

'bannerPageCategories' => "*{$target}*"
  • Thanks @carics, much appreciated. I am still a noob with craft. Based on the combination of your answer and Robins answer I ended up using : 'bannerPageCategories' => ['=', "{$target}"],. – Ray May 22 at 19:09

The value is stored as a serialized array in your database, in your case your would have to filter for the string "["adsl","fibre"]" (the order is the same like you specified in the field)

You can as well insert an array

['and',  '*adsl*', '*fibre*']

or

['or',  '*adsl*', '*fibre*']
  • Thanks Robin. I ended up going with 'bannerPageCategories' => ['=', "{$target}"], which seemed to do the trick. – Ray May 22 at 19:10

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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