1

How to add swatch data in Layered navigation aggregations in Graphql? Magento provides swatch data to filters [LayerFilter] but this is DEPRECATED so we use aggregations for the filter.

Below query is working

{
  products(filter: {category_id: {eq: "4"}}) {
    filters {
      name
      filter_items_count
      filter_items{
        label
        value_string
        items_count
        ... on SwatchLayerFilterItemInterface {
            swatch_data {
               type
               value
        }
      }
    }
  }
}
}

For Aggregation filter layered navigation not working(Swatch Data)

{
  products(filter: {category_id: {eq: "4"}}) {
  aggregations {
    attribute_code
    count
    label
    options {
    label
    value
    count
      ...on SwatchLayerFilterItemInterface {
        swatch_data {
          type
          value
        }
      }
    }
  }
  }
} 

Anyone idea about this? Can anyone help me with this?

1 Answer 1

6

I have override aggregations GraphQL API. Below code is working for me

File:-Custom/Module/registration.php

use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
    ComponentRegistrar::MODULE, 
    'Custom_Module', 
    __DIR__);

File:-Custom/Module/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Custom_Module" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Store"/>
            <module name="Magento_Catalog"/>
            <module name="Magento_CatalogInventory"/>
        </sequence>
    </module>
</config>

File: Custom/Module/etc/schema.graphqls

interface AggregationOptionInterface {
    swatch_data: SwatchData @doc(description: "Data required to render swatch filter item")
}
type SwatchData {
    type: String @doc(description: "Type of swatch filter item: 1 - text, 2 - image")
    value: String @doc(description: "Value for swatch item (text or image link)")
}

File:-Custom/Module/etc/graphql/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\LayerBuilder" type="Custom\Module\DataProvider\Product\LayeredNavigation\DataProviderAggregationPlugin"/>
</config>

File:-Custom/Module/DataProvider/Product/LayeredNavigation/DataProviderAggregationPlugin.php

<?php

namespace Custom\Module\DataProvider\Product\LayeredNavigation;

use Magento\Eav\Model\Config;
use Magento\Framework\Api\Search\AggregationInterface;
use Magento\Swatches\Block\LayeredNavigation\RenderLayered;
use Magento\Swatches\Helper\Data;
use Psr\Log\LoggerInterface;
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\LayerBuilder;
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\LayerBuilderInterface;
use Magento\Framework\Exception\LocalizedException;

class DataProviderAggregationPlugin extends LayerBuilder implements LayerBuilderInterface
{

    private $builders;
    protected $_logger;
    protected $eavConfig;
    private $swatchHelper;
    private $renderLayered;

    public function __construct(
        array $builders,
        LoggerInterface $logger,
        Config $eavConfig,
        Data $swatchHelper,
        RenderLayered $renderLayered
    )
    {
        $this->builders = $builders;
        $this->_logger = $logger;
        $this->eavConfig = $eavConfig;
        $this->swatchHelper = $swatchHelper;
        $this->renderLayered = $renderLayered;
    }

    public function build(
        AggregationInterface $aggregation,
        ?int $storeId
    ): array
    {
        $layers = [];
        foreach ($this->builders as $builder) {
            $layers[] = $builder->build($aggregation, $storeId);
        }
        $layers = \array_merge(...$layers);
        foreach ($layers as $key => $value) {
            $attribute = $this->eavConfig->getAttribute('catalog_product', $layers[$key]['attribute_code']);
            if ($this->swatchHelper->isSwatchAttribute($attribute)) {
                for ($i = 0; $i < count($layers[$key]['options']); $i++) {
                    $hashcodeData = $this->swatchHelper->getSwatchesByOptionsId([$layers[$key]['options'][$i]['value']]);
                    $typeName = $this->getswatchType($hashcodeData[$layers[$key]['options'][$i]['value']]['type']);

                    $temp = [
                        'type' => $typeName,
                        'value' => $hashcodeData[$layers[$key]['options'][$i]['value']]['value']
                    ];

                    $layers[$key]['options'][$i]['swatch_data'] = $temp;
                }
            }
        }

        return \array_filter($layers);
    }

    public function getswatchType($valueType)
    {
        switch ($valueType) {
            case 0:
                return 'TextSwatchData';
            case 1:
                return 'ColorSwatchData';
            case 2:
                return 'ImageSwatchData';
            break;
        }
    }
}

GraphQL Request:-

{
  products(filter: {category_id: {eq: "2"}}) {
    aggregations {
      attribute_code
      count
      label
      options {
        label
        value
        count
        swatch_data{
          value
          type
        }
      }
    }
  }
}

GraphQL Response:

{
  "data": {
    "products": {
      "aggregations": [
        {
          "attribute_code": "color",
          "count": 7,
          "label": "Color",
          "options": [
            {
              "label": "Red",
              "value": "5437",
              "count": 5,
              "swatch_data": {
                "value": "#eb0c0c",
                "type": "ColorSwatchData"
              }
            },
            {
              "label": "Blue",
              "value": "5438",
              "count": 3,
              "swatch_data": {
                "value": "#0d4aff",
                "type": "ColorSwatchData"
              }
            }
          ]
        },
        {
          "attribute_code": "texture",
          "count": 6,
          "label": "Texture",
          "options": [
            {
              "label": "model2",
              "value": "5432",
              "count": 5,
              "swatch_data": {
                "value": "/t/1/t1.jpeg",
                "type": "ImageSwatchData"
              }
            },
            {
              "label": "model3",
              "value": "5433",
              "count": 2,
              "swatch_data": {
                "value": "/t/3/t30.jpeg",
                "type": "ImageSwatchData"
              }
            }
          ]
        }
      ]
    }
  }
}

Your Answer

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

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