0

I am building an API that takes all products from the Craft Commerce Commerce_ProductModel. In this I am using the Element API plugin to build it out. I am running on Craft 2 latest version.

I have so far built out the JSON API and it's returning what I need with the following code:

'api/allproducts' => [
    'elementType' => 'Commerce_Product',
    'criteria' => [
        'search' => buildSearchQuery(craft()->request->getParam('types'))
    ],
    'transformer' => function(Commerce_ProductModel $product) {

        $mergedProductData = [];

        $title = $product->title;
        $url = UrlHelper::getUrl($product->url);
        $brand = (string)$product->productBrand[0];
        $designer = (string)$product->productDesigner[0];
        $num_decimals = (intval($product->defaultVariant->price) == $product->defaultVariant->price) ? 0 :2;
        $price = number_format($product->defaultVariant->price,$num_decimals);

        $frontImage = $product->productImages[0];
        $frontImages = [];

        if ($frontImage)
        {
            craft()->config->set('generateTransformsBeforePageLoad', true);

            if (craft()->plugins->getPlugin('Imager'))
            {
                $transformedImages = craft()->imager->transformImage(
                    $frontImage,
                    array(
                        array(
                            'width' => 1170,
                        ),
                        array(
                            'width' => 780,
                            'jpegQuality' => 65,
                        ),
                        array(
                            'width' => 390,
                            'jpegQuality' => 65,
                        ),
                    ),
                    array(
                        'ratio' => 16/9,
                        'position' => 'bottom-right',
                        'jpegQuality' => 80,
                    ),
                    array(
                        'fillTransforms' => true,
                    )
                );

                $frontImages[] = craft()->imager->srcset($transformedImages);

            } else {
                $frontImages[] = $frontImage->getUrl(['width' => 390, 'height' => 294]);
            }
        }

        $mergedProductData[] = [
            'id' => $product->id,
            'title' => $title,
            'productImage' => $frontImages,
            'body' => (string) $product->body,
            'brand' => $brand,
            'designer' => $designer,
            'url' => $url
        ];

        return [
            'title' => $title,
            'id' => $product->id,
            'frontImage' => $frontImages,
            'type' => $product->type->name,
            'designer' => $designer,
            'brand' => $brand,
            'price' => $price,
            'url' => $url,
            'isInWishlist' => craft()->like->isLike($product->id),
            'quickViewJson' => $mergedProductData
        ];
    },
],

This is great, its returning what I need and its nothing more but I am trying to return search values against it by looking for the product type form the Commerce_ProductModel and its hard to figure out.

What I ideally want to do is run a URL query like so:

/api/allproducts?types[]=New&types[]=Tables

In the code above there is this function that I was given by another developer that allows you to build queries like the URL above.

buildSearchQuery(craft()->request->getParam('types'))

In this I want to be able to query any product type from Craft Commerce so it only returns products of these types. The function is below:

function buildSearchQuery($input) {

    $query = "";
    $i = 0;

    foreach ($input as $value) {

        if($i > 0) {
            $query .= " OR ";
        }

        $query .= "title:*$value* OR body:*$value*";
        $i++;
    }

    return $query;
}

Can anyone shed any light on how this can be done at all?

1

Products can be queried by the product types type (a handle or ProductTypeModel) or typeId the ID of the type.

In a template this would look like:

craft.commerce.products.typeId([1,3,4]).find()

or

craft.commerce.products.type(['new','another']).find()

This is as per the parameter value syntax: https://craftcms.com/docs/templating/elementcriteriamodel#parameter-value-syntax

So in an element criteria query syntax in PHP it would look like this:

'criteria' => [
  'type' => ['New','Another']
],

or

'criteria' => [
  'typeId' => [1,2]
],

or

'criteria' => [
  'type' => craft()->commerce_productTypes->getAllProductTypes()[0]
],

The example you can was to build a query string for the search element criteria param, which could optionally be another criteria if you wanted.

1
  • Hi Luke, thanks for the detailed explanation. I just need a little clarity about using my search criteria for the url. If the structure of the url above that I showed was used in my search criteria how could we build the queries in? Would I add it into the function? buildSearchQuery()
    – M dunbavan
    Sep 26 '17 at 18:58

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.