Skip to content

03 Architecture & customization

Lorenzo Ruozzi edited this page Aug 29, 2022 · 1 revision

This plugin has basically two main entry points:

  • The Webgriffe\SyliusAkeneoPlugin\Command\EnqueueCommand which is responsible to put in a queue those Akeneo entity identifiers which need to be imported.
  • The Webgriffe\SyliusAkeneoPlugin\Command\ConsumeCommand which is responsible to load (or consume) all queue items that have not been imported yet and import the related Akeneo entities.

To be able to import different entities (or even only different parts of each entity), both commands use an importer registry which holds all the registered importers.

An importer is a service implementing the Webgriffe\SyliusAkeneoPlugin\ImporterInterface and that mainly holds the logic about how to import its Akeneo entities. If you want to import from Akeneo other entities not implemented in this plugin you have can implement your own importer. You can also replace an importer provided with this plugin by decorating or replacing its service definition.

To implement a new custom importer create a class which implements the Webgriffe\SyliusAkeneoPlugin\ImporterInterface:

// src/Importer/CustomImporter.php
namespace App\Importer;

use Webgriffe\SyliusAkeneoPlugin\ImporterInterface;

final class CustomImporter implements ImporterInterface
{
    // ...
}

Then define the importer with the webgriffe_sylius_akeneo.importer tag:

# config/services.yaml
app.custom_importer:
  class: App\Importer\CustomImporter
  tags:
    - { name: 'webgriffe_sylius_akeneo.importer' }

Anyway, this plugin already implement the following importers.

Product Importer

Akeneo is a Product Information Management system so its job is to manage product data. For this reason, this Sylius Akeneo plugin is focused on importing products and provides a product importer (\Webgriffe\SyliusAkeneoPlugin\Product\Importer).

This product importer processes Akeneo product data through the following components:

Taxons resolver

A taxons resolver (Webgriffe\SyliusAkeneoPlugin\Product\TaxonsResolverInterface) which is responsible to return the list of Sylius taxons for a given Akeneo product. The provided implementation of the taxons resolver is the Webgriffe\SyliusAkeneoPlugin\Product\AlreadyExistingTaxonsResolver class which returns the already existent Sylius taxons which have the same code as the related Akeneo categories.

Product options resolver

A product options resolve (Webgriffe\SyliusAkeneoPlugin\Product\ProductOptionsResolverInterface) which is responsible to return the related Sylius's product option(s) when the product being imported is part of a parent product model. The provided implementation of the product options resolver is the Webgriffe\SyliusAkeneoPlugin\Product\ProductOptionsResolver class, which returns already existend product options but also creates new ones if needed.

Channels resolver

A channels resolver (Webgriffe\SyliusAkeneoPlugin\Product\ChannelsResolverInterface) which is responsible to return the list of Sylius channels where the products should be enabled. The provided implementation of the channels resolver is the Webgriffe\SyliusAkeneoPlugin\Product\AllChannelsResolver class which simply enables the product in all available Sylius channels.

Status resolver

A status resolver (Webgriffe\SyliusAkeneoPlugin\Product\StatusResolverInterface) which is responsible to return the Sylius product status (enabled or disabled, true or false). The provided implementation of the status resolver is the Webgriffe\SyliusAkeneoPlugin\Product\StatusResolver which returns the same product status of the related Akeneo product, but only if this doesn't belong to a parent product model, otherwise it will always return true (enabled). This is because in Sylius the product status is at product level and not (also) at product variant level; instead, in Akeneo the status is only at product level and not at product model level. So, in Akeneo, you could have only one disabled product variant for a parent product which have several other variants enabled. This situation can't be mapped on Sylius at present.

Value handlers resolver

A value handlers resolver (Webgriffe\SyliusAkeneoPlugin\ValueHandlersResolverInterface) which is responsible to return a list of value handlers (Webgriffe\SyliusAkeneoPlugin\ValueHandlerInterface) for each Akeneo product attribute value.

The provided implementation of the value handlers resolver is the Webgriffe\SyliusAkeneoPlugin\PriorityValueHandlersResolver which returns, for each attribute value, the list of all the value handlers supporting that attribute value sorted by a priority. Each value handler returned by the resolver for a given attribute is then called to handle that value.

For more detail on how the Product importer works look at the code of the Webgriffe\SyliusAkeneoPlugin\Product\Importer::import() method.

Value handlers

By default, the provided Webgriffe\SyliusAkeneoPlugin\PriorityValueHandlersResolver is configured with value handlers specified in the webgriffe_sylius_akeneo.value_handlers.product array as explained in the configuration paragraph. This plugin already provides some value handler implementations that are:

  • Webgriffe\SyliusAkeneoPlugin\ValueHandler\ChannelPricingValueHandler (type channel_pricing): it sets the value found on a given Akeneo price attribute (options.$akeneoAttribute) as the Sylius product's channels price for channels whose base currency is the price currency of the Akeneo price.
  • Webgriffe\SyliusAkeneoPlugin\ValueHandler\ImageValueHandler (type image): it downloads the image found on a given Akeneo image attribute (options.$akeneoAttributeCode) and sets it as a Sylius product image with a provided type string (options.$syliusImageType).
  • Webgriffe\SyliusAkeneoPlugin\ValueHandler\ImmutableSlugValueHandler (type immutable_slug): it slugifies the value found on a given Akeneo attribute (options.$akeneoAttributeToSlugify) and sets it on the Sylius slug product translation property.
  • Webgriffe\SyliusAkeneoPlugin\ValueHandler\ProductOptionValueHandler (type product_option): it sets the value found on a given Akeneo attribute as a Sylius product option value on the product variant.
  • Webgriffe\SyliusAkeneoPlugin\ValueHandler\TranslatablePropertyValueHandler (type translatable_property): using the Symofony's Property Access component, it sets the value found on a given Akeneo attribute (options.$akeneoAttributeCode) on a given property path (options.$translationPropertyPath) of both product and product variant translations.
  • Webgriffe\SyliusAkeneoPlugin\ValueHandler\AttributeValueHandler (type generic_attribute) it will automatically handle Sylius attributes whose attribute code matches Akeneo attribute code.
  • Webgriffe\SyliusAkeneoPlugin\ValueHandler\FileAttributeValueHandler (type file_attribute): it saves the file downloaded from the Akeneo file attribute (options.$akeneoAttributeCode) to the given destination path (options.$downloadPath)

To add a custom value handler to the resolver you can implement your own by implementing the Webgriffe\SyliusAkeneoPlugin\ValueHandlerInterface and then tag it with the webgriffe_sylius_akeneo.product.value_handler tag:

# config/services.yaml
app.my_custom_value_handler:
  class: App\MyCustomValueHandler
  tags:
    - { name: 'webgriffe_sylius_akeneo.product.value_handler', priority: 42 }

Product associations importer

Another provided importer is the product associations importer (Webgriffe\SyliusAkeneoPlugin\ProductAssociations\Importer). This importer imports the Akeneo products associations to the corresponding Sylius products associations. The association types must already exist on Sylius with the same code they have on Akeneo.

Attribute options importer

Another provided importer is the attribute options importer (\Webgriffe\SyliusAkeneoPlugin\AttributeOptions\Importer). This importer imports the Akeneo simple select and multi select attributes options into Sylius select attributes. The select attributes must already exist on Sylius with the same code they have on Akeneo.