integration_documentation:plugin:en:integration:shopware_6:extension

integration_documentation:plugin:en:integration:shopware_6:extension

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
integration_documentation:plugin:en:integration:shopware_6:extension [2022/06/21 13:59]
tobi
integration_documentation:plugin:en:integration:shopware_6:extension [2022/12/13 13:42] (current)
tobi
Line 15: Line 15:
  
 </​markdown>​ </​markdown>​
-<note tip>​Please make sure to use the same major version as the base Findologic plugin. This means that ''​2.x''​ is compatible with ''​2.x''​ and ''​3.x''​ is compatible with ''​3.x'',​ etc.</​note>​+<note tip>​Please make sure to use the same major version as the base Findologic plugin. This means that ''​3.x''​ is compatible with ''​3.x''​ and ''​4.x''​ is compatible with ''​4.x'',​ etc.</​note>​
 <​markdown>​ <​markdown>​
  
Line 25: Line 25:
  
 By default the extension plugin decorates the `AttributeAdapter` and `DefaultPropertiesAdapter`,​ which are responsible to generate the attributes and properties of a product. By default the extension plugin decorates the `AttributeAdapter` and `DefaultPropertiesAdapter`,​ which are responsible to generate the attributes and properties of a product.
-Any adapter in `FINDOLOGIC\FinSearch\Export\Adapters` can be decorated.+Any adapter in `FINDOLOGIC\Shopware6Common\Export\Adapters` can be decorated. The original files are located within `vendor/​findologic/​shopware6-common/​src/​Export/​Adapters`.
  
 `src/​Resources/​config/​services.xml` `src/​Resources/​config/​services.xml`
Line 38: Line 38:
         <service         <service
             id="​FINDOLOGIC\ExtendFinSearch\Export\Adapters\AttributeAdapter"​             id="​FINDOLOGIC\ExtendFinSearch\Export\Adapters\AttributeAdapter"​
-            decorates="​FINDOLOGIC\FinSearch\Export\Adapters\AttributeAdapter"​+            decorates="​FINDOLOGIC\Shopware6Common\Export\Adapters\AttributeAdapter"​
             public="​true"​             public="​true"​
             decoration-on-invalid="​ignore"​             decoration-on-invalid="​ignore"​
 +            autowire="​true"​
         >         >
-            <​argument ​type="service" ​id="​service_container"​ /> +            <​argument ​key="$dynamicProductGroupService" type="​service"​ id="​FINDOLOGIC\FinSearch\Export\Services\DynamicProductGroupService" /> 
-            <​argument ​type="​service"​ id="​FINDOLOGIC\FinSearch\Struct\Config" /> +            <​argument ​key="​$catUrlBuilderService" ​type="​service"​ id="FINDOLOGIC\FinSearch\Export\Services\CatUrlBuilderService" /> 
-            <​argument type="​service"​ id="Shopware\Core\Framework\Adapter\Translation\Translator" /> +            <​argument ​key="$translator" type="​service"​ id="Shopware\Core\Framework\Adapter\Translation\Translator" />
-            <​argument ​type="service" ​id="​fin_search.sales_channel_context"​ /> +
-            <​argument ​type="​service"​ id="FINDOLOGIC\FinSearch\Export\UrlBuilderService"​ /> +
-            <​argument type="​service"​ id="​fin_search.export_context" />+
         </​service>​         </​service>​
  
         <service         <service
             id="​FINDOLOGIC\ExtendFinSearch\Export\Adapters\DefaultPropertiesAdapter"​             id="​FINDOLOGIC\ExtendFinSearch\Export\Adapters\DefaultPropertiesAdapter"​
-            decorates="​FINDOLOGIC\FinSearch\Export\Adapters\DefaultPropertiesAdapter"​+            decorates="​FINDOLOGIC\Shopware6Common\Export\Adapters\DefaultPropertiesAdapter"​
             public="​true"​             public="​true"​
             decoration-on-invalid="​ignore"​             decoration-on-invalid="​ignore"​
 +            autowire="​true"​
         >         >
-            <​argument ​type="service" ​id="​FINDOLOGIC\FinSearch\Struct\Config"​ /> +            <​argument ​key="$translator" type="​service"​ id="​Shopware\Core\Framework\Adapter\Translation\Translator"​ />
-            <​argument type="​service"​ id="​fin_search.sales_channel_context"​ /> +
-            <​argument ​type="​service"​ id="​Shopware\Core\Framework\Adapter\Translation\Translator"​ />+
         </​service>​         </​service>​
  
Line 78: Line 75:
  
 use FINDOLOGIC\Export\Data\Attribute;​ use FINDOLOGIC\Export\Data\Attribute;​
-use FINDOLOGIC\FinSearch\Export\Adapters\AttributeAdapter as OriginalAttributeAdapter;​ +use FINDOLOGIC\Shopware6Common\Export\Adapters\AttributeAdapter as OriginalAttributeAdapter;​ 
-use Shopware\Core\Content\Product\ProductEntity;​+use Vin\ShopwareSdk\Data\Entity\Product\ProductEntity;​
  
 class AttributeAdapter extends OriginalAttributeAdapter class AttributeAdapter extends OriginalAttributeAdapter
Line 110: Line 107:
  
 use FINDOLOGIC\Export\Data\Property;​ use FINDOLOGIC\Export\Data\Property;​
-use FINDOLOGIC\FinSearch\Export\Adapters\DefaultPropertiesAdapter as OriginalDefaultPropertiesAdapter;​ +use FINDOLOGIC\Shopware6Common\Export\Adapters\DefaultPropertiesAdapter as OriginalDefaultPropertiesAdapter;​ 
-use Shopware\Core\Content\Product\ProductEntity;​+use Vin\ShopwareSdk\Data\Entity\Product\ProductEntity;​
  
 class DefaultPropertiesAdapter extends OriginalDefaultPropertiesAdapter class DefaultPropertiesAdapter extends OriginalDefaultPropertiesAdapter
Line 210: Line 207:
  
 use FINDOLOGIC\Export\Data\Property;​ use FINDOLOGIC\Export\Data\Property;​
-use FINDOLOGIC\FinSearch\Export\Adapters\AdapterFactory;​ +use FINDOLOGIC\Shopware6Common\Export\Adapters\AdapterFactory;​ 
-use FINDOLOGIC\FinSearch\Export\Events\AfterItemBuildEvent;​ +use FINDOLOGIC\Shopware6Common\Export\Events\AfterItemBuildEvent;​ 
-use FINDOLOGIC\FinSearch\Export\Events\AfterVariantAdaptEvent;​ +use FINDOLOGIC\Shopware6Common\Export\Events\AfterVariantAdaptEvent;​ 
-use FINDOLOGIC\FinSearch\Export\Events\BeforeItemAdaptEvent+use FINDOLOGIC\Shopware6Common\Export\Events\BeforeItemAdaptEvent;​
-use Shopware\Core\Content\Product\ProductEntity;+
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;​ use Symfony\Component\EventDispatcher\EventSubscriberInterface;​
 +use Vin\ShopwareSdk\Data\Entity\Product\ProductEntity;​
  
 class ProductSubscriber implements EventSubscriberInterface class ProductSubscriber implements EventSubscriberInterface
Line 232: Line 229:
     {     {
         return [         return [
-            BeforeItemAdaptEvent::​NAME => '​beforeItemAdapt',​ 
             AfterVariantAdaptEvent::​NAME => '​afterVariantAdapted',​             AfterVariantAdaptEvent::​NAME => '​afterVariantAdapted',​
             AfterItemBuildEvent::​NAME => '​afterItemCompleted'​             AfterItemBuildEvent::​NAME => '​afterItemCompleted'​
         ];         ];
-    } 
- 
-    public function beforeItemAdapt() 
-    { 
-        $this->​variantData = []; 
     }     }
  
Line 263: Line 254:
             );             );
         }         }
 +        ​
 +        $this->​variantData = [];
     }     }
 } }
Line 282: Line 275:
         >         >
             <tag name="​kernel.event_subscriber"​ />             <tag name="​kernel.event_subscriber"​ />
-            <​argument type="​service"​ id="​FINDOLOGIC\FinSearch\Export\Adapters\AdapterFactory"​ />+            <​argument type="​service"​ id="​FINDOLOGIC\Shopware6Common\Export\Adapters\AdapterFactory"​ />
         </​service>​         </​service>​
  
Line 301: Line 294:
     $this->​variantData[] = [     $this->​variantData[] = [
         '​name'​ => $this->​getName($product),​         '​name'​ => $this->​getName($product),​
-        'image' => $this->getImageUrl($product),+        'url' => $this->getUrl($product),
         '​price'​ => $this->​getPrice($product)         '​price'​ => $this->​getPrice($product)
     ];     ];
Line 315: Line 308:
 } }
  
-private function ​getImageUrl(ProductEntity $productEntity):​ string+private function ​getUrl(ProductEntity $productEntity):​ string
 { {
-    $images ​= $this->​adapterFactory->​getUrlAdapter()->​adapt($productEntity);​+    $url = $this->​adapterFactory->​getUrlAdapter()->​adapt($productEntity);​
  
-    return $images ​? $images->​getValues()[''​] : '';​+    return $url ? $url->​getValues()[''​] : '';​
 } }
  
Line 334: Line 327:
  
 //... //...
 +```
 +
 +This will export the `name`, `url` and `price` of each variant, the JSON would be like: 
 +```json
 +[
 +  {
 +    "​name":​ "​Findologic T-Shirt (Gray - Orange Logo)",​
 +    "​url":​ "​https://​store.com/​Findologic-T-Shirt-Gray-Orange-Logo/​411dc735cade4c8789421f9c2aaec51f",​
 +    "​price":​ 59.99
 +  },
 +  {
 +    "​name":​ "​Findologic T-Shirt",​
 +    "​url":​ "​https://​store.com/​Findologic-T-Shirt/​ad99a6257e1546f08dbe9886a48e4230",​
 +    "​price":​ 55.99
 +  },
 +  {
 +    "​name":​ "​Findologic T-Shirt (Black - White Logo)",​
 +    "​url":​ "​https://​store.com/​Findologic-T-Shirt/​7c18c5ff8aa548e1bdba6b738ac42f71",​
 +    "​price":​ 49.99
 +  }
 +]
 ``` ```
  
 ### Add images ### Add images
  
-For variant images, you will need to add the relevant associations as shown [here](#Item)+For variant images, you will need to add the relevant ​variant ​associations as shown [here](#add_product_or_variant_associations). (`cover` and `media`) 
 + 
 +Additionally:​ 
 +`src/​Subscriber/​ProductSubscriber.php` 
 +```php 
 +// ... 
 + 
 +public function afterVariantAdapted(AfterVariantAdaptEvent $event) 
 +
 +    $product = $event->​getProduct();​ 
 + 
 +    $this->​variantData[] = [ 
 +        // ... 
 +        '​image'​ => $this->​getImageUrl($product) 
 +    ]; 
 +
 + 
 +// ... 
 + 
 +private function getImageUrl(ProductEntity $productEntity):​ string 
 +
 +    $images = $this->​adapterFactory->​getImagesAdapter()->​adapt($productEntity);​ 
 + 
 +    return count($images) ? current($images)->​getUrl() : '';​ 
 +
 +``` 
 + 
 +### Deal with variant-specific data 
 + 
 +`src/​Subscriber/​ProductSubscriber.php` 
 +```php 
 +// ... 
 + 
 +private const VARIANT_PROPERTY = '​color';​ 
 + 
 +//... 
 + 
 +public function afterVariantAdapted(AfterVariantAdaptEvent $event) 
 +
 +    $product = $event->​getProduct();​ 
 + 
 +    foreach ($product->​properties as $variantProperty) { 
 +        // Ignore all properties except the property we want to export our variants off. 
 +        if ( 
 +            !$variantProperty->​group || 
 +            $variantProperty->​group->​getTranslation('​name'​) !== self::​VARIANT_PROPERTY) 
 +        { 
 +            continue; 
 +        } 
 + 
 +        $propertyName = $variantProperty->​getTranslation('​name'​);​ 
 + 
 +        $this->​variantData[$propertyName] = [ 
 +            '​name'​ => $this->​getName($product),​ 
 +            '​url'​ => $this->​getUrl($product),​ 
 +            '​price'​ => $this->​getPrice($product),​ 
 +            '​image'​ => $this->​getImageUrl($product),​ 
 +            self::​VARIANT_PROPERTY => $propertyName 
 +        ]; 
 +    } 
 +
 + 
 +// ... 
 +``` 
 + 
 +After this implementation,​ the JSON would be like:  
 + 
 +```json 
 +
 +  "​Gray":​ { 
 +    "​name":​ "​Findologic T-Shirt (Gray - Orange Logo)",​ 
 +    "​image":​ "​https://​store.com/​some/​path/​to/​image_800x800.jpg",​ 
 +    "​url":​ "​https://​store.com/​Findologic-T-Shirt-Gray-Orange-Logo/​411dc735cade4c8789421f9c2aaec51f",​ 
 +    "​color":​ "​Gray"​ 
 +  }, 
 +  "​Black":​ { 
 +    "​name":​ "​Findologic T-Shirt (Black - White Logo)",​ 
 +    "​image":​ "​https://​store.com/​some/​path/​to/​image_800x800.jpg",​ 
 +    "​url":​ "​https://​store.com/​Findologic-T-Shirt/​7c18c5ff8aa548e1bdba6b738ac42f71",​ 
 +    "​color":​ "​Black"​ 
 +  } 
 +
 +``` 
 + 
 +### Usergroup-specific variants 
 + 
 +`src/​Subscriber/​ProductSubscriber.php` 
 +```php 
 +//... 
 + 
 +public function afterVariantAdapted(AfterVariantAdaptEvent $event) 
 +
 +    $product = $event->​getProduct();​ 
 + 
 +    $basicVariantData = [ 
 +        '​name'​ => $this->​getName($product),​ 
 +        '​url'​ => $this->​getUrl($product),​ 
 +        '​image'​ => $this->​getImageUrl($product) 
 +    ]; 
 + 
 +    foreach ($this->​adapterFactory->​getPriceAdapter()->​adapt($product) as $price) { 
 +        $values = $price->​getValues();​ 
 + 
 +        $variantData = array_merge( 
 +            $basicVariantData,​ 
 +            [ 
 +                '​price'​ => current($values) 
 +            ] 
 +        ); 
 + 
 +        $this->​variantData[array_key_first($values)][] = json_encode($variantData);​ 
 +    } 
 +
 + 
 +public function afterItemCompleted(AfterItemBuildEvent $event) 
 +
 +    $variantData = []; 
 +    foreach ($this->​variantData as $usergroup => $userGroupVariantData) { 
 +        $variantData[$usergroup] = json_encode($userGroupVariantData);​ 
 +    } 
 + 
 +    $item = $event->​getItem();​ 
 + 
 +    if (count($this->​variantData)) { 
 +        $item->​addProperty( 
 +            new Property('​variants',​ $variantData) 
 +        ); 
 +    } 
 +
 + 
 +//... 
 +``` 
 + 
 +</​markdown>​ 
 + 
 +<note tip>''​variants''​ **must** be exported for **all** usergroups. If a usergroup is not exported, this usergroup will not have any ''​variants''​ data.</​note>​ 
 + 
 +<​markdown>​ 
 + 
 +An XML export with usergroup in properties may look like: 
 + 
 +```xml 
 +<!-- ... --> 
 +<​allProperties>​ 
 +    <​property usergroup="​JyInVwMCBQtTdQ1RAwkmCSRXUVkGBCZ6B1YgDyFXVnc=">​ 
 +        <​key>​ 
 +            <​![CDATA[ variants ]]> 
 +        </​key>​ 
 +        <​value>​ 
 +            <​![CDATA[ 
 +                [ 
 +                    { 
 +                        "​name":​ "​Findologic T-Shirt (Gray - Orange Logo)",​ 
 +                        "​image":​ "​https://​store.com/​some/​path/​to/​image_800x800.jpg",​ 
 +                        "​url":​ "​https://​store.com/​Findologic-T-Shirt-Gray-Orange-Logo/​411dc735cade4c8789421f9c2aaec51f",​ 
 +                        "​price":​ 59.99 
 +                    }, 
 +                    { 
 +                        "​name":​ "​Findologic T-Shirt",​ 
 +                        "​image":​ "​https://​store.com/​some/​path/​to/​image_800x800.jpg",​ 
 +                        "​url":​ "​https://​store.com/​Findologic-T-Shirt/​ad99a6257e1546f08dbe9886a48e4230",​ 
 +                        "​price":​ 55.99 
 +                    }, 
 +                    { 
 +                        "​name":​ "​Findologic T-Shirt (Black - White Logo)",​ 
 +                        "​image":​ "​https://​store.com/​some/​path/​to/​image_800x800.jpg",​ 
 +                        "​url":​ "​https://​store.com/​Findologic-T-Shirt/​7c18c5ff8aa548e1bdba6b738ac42f71",​ 
 +                        "​price":​ 49.99 
 +                    } 
 +                ] 
 +            ]]> 
 +        </​value>​ 
 +    </​property>​ 
 +    <​property usergroup="​dX1WUgsgCyVUIHcPcXYFUw1xUlBZUwcAB1FUcgNQCwA=">​ 
 +        <​key>​ 
 +            <​![CDATA[ variants ]]> 
 +        </​key>​ 
 +        <​value>​ 
 +            <​![CDATA[ 
 +                [ 
 +                    { 
 +                        "​name":​ "​Findologic T-Shirt (Gray - Orange Logo)",​ 
 +                        "​image":​ "​https://​store.com/​some/​path/​to/​image_800x800.jpg",​ 
 +                        "​url":​ "​https://​store.com/​Findologic-T-Shirt-Gray-Orange-Logo/​411dc735cade4c8789421f9c2aaec51f",​ 
 +                        "​price":​ 599.99 
 +                    }, 
 +                    { 
 +                        "​name":​ "​Findologic T-Shirt",​ 
 +                        "​image":​ "​https://​store.com/​some/​path/​to/​image_800x800.jpg",​ 
 +                        "​url":​ "​https://​store.com/​Findologic-T-Shirt/​ad99a6257e1546f08dbe9886a48e4230",​ 
 +                        "​price":​ 559.99 
 +                    }, 
 +                    { 
 +                        "​name":​ "​Findologic T-Shirt (Black - White Logo)",​ 
 +                        "​image":​ "​https://​store.com/​some/​path/​to/​image_800x800.jpg",​ 
 +                        "​url":​ "​https://​store.com/​Findologic-T-Shirt/​7c18c5ff8aa548e1bdba6b738ac42f71",​ 
 +                        "​price":​ 499.99 
 +                    } 
 +                ] 
 +            ]]> 
 +        </​value>​ 
 +    </​property>​ 
 +</​allProperties>​ 
 +<!-- ... --> 
 +```
  
 ## Add product or variant associations ## Add product or variant associations
Line 355: Line 573:
  
 use FINDOLOGIC\FinSearch\Export\Search\ProductCriteriaBuilder as OriginalProductCriteriaBuilder;​ use FINDOLOGIC\FinSearch\Export\Search\ProductCriteriaBuilder as OriginalProductCriteriaBuilder;​
-use FINDOLOGIC\FinSearch\Utils\Utils;​ 
  
 class ProductCriteriaBuilder extends OriginalProductCriteriaBuilder class ProductCriteriaBuilder extends OriginalProductCriteriaBuilder
Line 361: Line 578:
     public function withProductAssociations():​ OriginalProductCriteriaBuilder     public function withProductAssociations():​ OriginalProductCriteriaBuilder
     {     {
-        ​Utils::addProductAssociations($this->​criteria);+        ​parent::withProductAssociations();
  
         $this->​criteria->​addAssociations([         $this->​criteria->​addAssociations([
Line 372: Line 589:
     public function withVariantAssociations():​ OriginalProductCriteriaBuilder     public function withVariantAssociations():​ OriginalProductCriteriaBuilder
     {     {
-        ​Utils::addVariantAssociations($this->​criteria);+        ​parent::withVariantAssociations();
  
         $this->​criteria->​addAssociations([         $this->​criteria->​addAssociations([
             '​cover',​             '​cover',​
-            'media+            'media'
         ]);         ]);
  
Line 399: Line 616:
             decorates="​FINDOLOGIC\FinSearch\Export\Search\ProductCriteriaBuilder"​             decorates="​FINDOLOGIC\FinSearch\Export\Search\ProductCriteriaBuilder"​
             public="​true"​             public="​true"​
-        > +            decoration-on-invalid="ignore
-            <​argument type="service" ​id="​fin_search.sales_channel_context"​ /> +            ​autowire="true
-            ​<​argument type="service" ​id="​Shopware\Core\System\SystemConfig\SystemConfigService"​ /> +        />
-        ​</service>+
         ​         ​
         <!-- ... -->         <!-- ... -->
Line 409: Line 625:
 </​container>​ </​container>​
 ``` ```
 +
 +## Cookie Consent for Direct Integration
 +
 +In case it's required by the integration,​ you are required to add a cookie consent. Please see the Shopware 6 documentation about [Adding a cookie to the cookie manager]( https://​developer.shopware.com/​docs/​guides/​plugins/​plugins/​storefront/​add-cookie-to-manager).
 +
 +There is also an [example](https://​github.com/​findologic/​plugin-shopware-6-extension/​commit/​cf1a0b68a8f590f8eaf818dc038b5903edfbfd80) available in our GitHub repository.
 +
 +## Add custom sorting options for API Integration
 +
 +The Findologic base plugin already provides sorting options for the most common use-cases. The plugin uses `SortingHandler` to send the currently selected sorting option via API parameters to the Findologic Search-API (see [all available SortingHandlers](https://​github.com/​findologic/​plugin-shopware-6/​tree/​develop/​src/​Core/​Content/​Product/​SalesChannel/​Listing/​SortingHandler)).
 +
 +Therefore to handle custom sorting options, create a custom `SortingHandler` in the extension plugin, and override the responsible `SortingHandlerService` to include the created `SortingHandler`.
 +
 +### Prerequisites
 +
 +Before a custom sorting can be used, make sure to export the value for the custom sort in the `<​sort>​` field in the export. See the [XML Format documentation](:​xml_export_documentation:​xml_format#​sorts) for further details.
 +
 +### Implementation
 +
 +**Step 1: Create a `SortingHandler`**
 +
 +Create the folder structure `Core/​Content/​Product/​SalesChannel/​Listing/​SortingHandler` in the extension plugin, and add a custom sorting handler class. In this example it will be `ThirdPartySortingHandler`:​
 +
 +```php
 +use FINDOLOGIC\Api\Requests\SearchNavigation\SearchNavigationRequest;​
 +use FINDOLOGIC\FinSearch\Core\Content\Product\SalesChannel\Listing\SortingHandler\SortingHandlerInterface;​
 +use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;​
 +
 +class ThirdPartySortingHandler implements SortingHandlerInterface
 +{
 +    public function supportsSorting(FieldSorting $fieldSorting):​ bool
 +    {
 +        // Enter your custom sort here.
 +        // To get the name of the sort, select the sort in the storefront and
 +        // add a dd($fieldSorting) here and refresh the page.
 +        return $fieldSorting->​getField() === '​product.third_party_extension.field';​
 +    }
 +
 +    public function generateSorting(FieldSorting $fieldSorting,​ SearchNavigationRequest $searchNavigationRequest):​ void
 +    {
 +        $searchNavigationRequest->​setOrder('​shopsort ' . $fieldSorting->​getDirection());​
 +    }
 +}
 +```
 +
 +**Step 2: Decorate the `SortingHandlerService`**
 +
 +The `SortingHandlerService` holds all available sorting options. Therefore, you want to add your custom sort to this service. The service can be found in `Findologic/​Request/​Handler`. Simply override the `getSortingHandlers` method to include your own custom sorting handler.
 +
 +```php
 +namespace FINDOLOGIC\ExtendFinSearch\Findologic\Request\Handler;​
 +
 +use FINDOLOGIC\ExtendFinSearch\Core\Content\Product\SalesChannel\Listing\SortingHandler\ThirdPartySortingHandler;​
 +use FINDOLOGIC\FinSearch\Core\Content\Product\SalesChannel\Listing\SortingHandler\SortingHandlerInterface;​
 +use FINDOLOGIC\FinSearch\Findologic\Request\Handler\SortingHandlerService as OriginalSortingHandlerService;​
 +
 +class SortingHandlerService extends OriginalSortingHandlerService
 +{
 +    /**
 +     * @return SortingHandlerInterface[]
 +     */
 +    protected function getSortingHandlers():​ array
 +    {
 +        return array_merge(
 +            parent::​getSortingHandlers(),​
 +            [
 +                new ThirdPartySortingHandler()
 +            ]
 +        );
 +    }
 +}
 +```
 +
 +**Step 3: Add the decorated service to the services.xml**
 +
 +As a last step, simply decorate in your `src/​Resources/​config/​services.xml` the service of the main plugin:
 +
 +```xml
 +<?xml version="​1.0"​ ?>
 +<​container xmlns:​xsi="​http://​www.w3.org/​2001/​XMLSchema-instance"​
 +    xmlns="​http://​symfony.com/​schema/​dic/​services"​
 +    xsi:​schemaLocation="​http://​symfony.com/​schema/​dic/​services http://​symfony.com/​schema/​dic/​services/​services-1.0.xsd">​
 +
 +    <​services>​
 +
 +        <service
 +            id="​FINDOLOGIC\ExtendFinSearch\Findologic\Request\Handler\SortingHandlerService"​
 +            decorates="​FINDOLOGIC\FinSearch\Findologic\Request\Handler\SortingHandlerService"​
 +            decoration-on-invalid="​ignore"​
 +        />
 +
 +    </​services>​
 +</​container>​
 +```
 +
 +Once this step is done, selecting your relevant sorting option will send the order parameter to the Findologic API.
  
 </​markdown>​ </​markdown>​