Question

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?

Was it helpful?

Solution

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"
              }
            }
          ]
        }
      ]
    }
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top