API

The configuratorware backend has a public API, usually having the name “…Api” included. These classes are not marked as @internal and are therefore part of our backward compatibility promise. All classes that are marked as internal might change at any time with a new release without deprecations.

Events

The most common way to extend the functionality of the API is by binding listeners to existing events and add functionality there. For example if you want to calculate the weight of your configured item

After those steps the calculation call will return the calculation result with an additional property “weight” to the frontend.

Modify the CalculationResult

Create a new structure for the calculation result inheriting the original structure from the ConfiguratorApiBundle. This way you can add a new weight property.

<?php declare(strict_types=1);

namespace App\Structure;

use JMS\Serializer\Annotation as Serializer;
use Redhotmagma\ConfiguratorApiBundle\Structure\Frontend\CalculationResult as ApiCalculationResult;

class CalculationResult extends ApiCalculationResult
{
    /**
     * @Serializer\Type("integer")
     */
    public $weight;
}

Create an event listener class in your project

Create an event listener in your client project.

<?php declare(strict_types=1);

namespace App\EventListener;
use Redhotmagma\ConfiguratorApiBundle\Events\CalculationEvent;
use App\Service\WeightCalculation;

class WeightCalculationListener
{
    /**
     * Service to calculate the weight
     * @var WeightCalculation
     */
    private $weightCalculation;

    /**
     * WeightCalculationListener constructor.
     * @param WeightCalculation $weightCalculation
     */
    public function __construct(WeightCalculation $weightCalculation)
    {
        $this->weightCalculation = $weightCalculation;
    }

    /**
     * @param CalculationEvent $event
     */
    public function onCalculate(CalculationEvent $event)
    {
        $configuration = $event->getConfiguration();
        $calculationResult = $event->getCalculationResult();

        // use your own weight calculation class to calculate the weight
        $calculationResult = $this->weightCalculation->calculate($calculationResult, $configuration);

        $event->setCalculationResult($calculationResult);
    }
}

Register the listener to the calculation event

Your event listener has to be bound to the event. In most cases you want your code to be executed after all core functionality has been executed. The core usually sets the priority of its listeners within +/- 100.

App\EventListener\WeightCalculationListener:
  autowire: true
  class: App\EventListener\WeightCalculationListener
  tags:
    - { name: kernel.event_listener, event: configuratorware.calculation.calculate, method: onCalculate, priority: -200 }

Finding all available events

Symfony provides a command to list all available events with the listeners bound to them

bin/console debug:event-dispatcher

Repositories

If you want to add functionality to existing repositories you can create a repository class in you client project for an existing entity and have custom queries to fetch those entities there. For example if you want to retrieve items by an attribute and attribute value to get all items that are made of steel.

Create a repository in your project

Create a repository in your client project and implement the custom query you need.

<?php declare(strict_types=1);

namespace App\Repository;

use Doctrine\ORM\Query;
use Redhotmagma\ConfiguratorApiBundle\Entity\Item;

class ItemRepository extends \Redhotmagma\ConfiguratorApiBundle\Repository\ItemRepository
{
    /**
     * @param string $attributeIdentifier
     * @param string $attributeValue
     * @return Item[]|null
     */
    public function fetchItemsByAttribute(
        string $attributeIdentifier,
        string $attributeValue
    ): array {
        $entityName = $this->getNormalizedEntityName();

        $queryBuilder = $this->createQueryBuilder($entityName);
        $queryBuilder->leftJoin('item.itemAttribute', 'itemAttribute')
                     ->leftJoin('itemAttribute.attribute', 'attribute')
                     ->leftJoin('itemAttribute.attributevalue', 'attributevalue')
                     ->where(
            $queryBuilder->expr()->andX(
                $queryBuilder->expr()->eq('attribute.identifier', ':attributeIdentifier'),
                $queryBuilder->expr()->eq('attributevalue.value', ':attributeValue')
            )
        );

        $queryBuilder->setParameter(':attributeIdentifier', $attributeIdentifier);
        $queryBuilder->setParameter(':attributeValue', $attributeValue);

        $query = $queryBuilder->getQuery();
        $items = $query->getResult();

        return $items;
    }
}

Register the custom repository for the item entity

To register your item repository you have to use the repository factory. By this whenever the item repository is used in the configurator it instead uses the one with your extended functions. The newly created method to get items can then be used wherever the item repository is available.

Redhotmagma\ConfiguratorApiBundle\Repository\ItemRepository:
    class: App\Repository\ItemRepository
    factory: ["@configuratorware.doctrine_extensions.repository_factory", createRepository]
    arguments:
      - Redhotmagma\ConfiguratorApiBundle\Entity\Item
      - App\Repository\ItemRepository

Service Tags

To add a custom option text type / validator, you can add your custom Validator that implements the Redhotmagma\ConfiguratorApiBundle\Service\Option\OptionInputValidation\OptionInputValidatorInterface.

The Validator will be selectable when editing an option in the adminarea and its validation will be triggered when a configuration is saved.

Security

Configuratorware allows the security config only to be stored in 1 file. It’s valid to override the firewall settings in the project, but trying to add a new firewall will cause an error. Because of this limitation it is possible to disable configuratorware default_security. Change in config/packages/redhotmagma_configurator_api.yaml to:

redhotmagma_configurator_api:
    default_security: false

This will disable all security configuration. Do this on your own risk. You will need to setup the complete security for the project. It is recommended to not depend on any internals like Authenticators in your security config because they might change without deprecation.

Rest APIs

The Rest APIs for the configurator are documented in swagger. There are three sections admin area, frontend and connector.

Configuration PDF

Change Template

To change the Template of the configuration PDF, create a new template in the following folder: templates/bundles/RedhotmagmaConfiguratorApiBundle/configuration/main.html.twig

Note

The templates directory needs to be configured as the twig default path, which is the default after install.

The template has access to the following data:

[
    'calculationResult' => Redhotmagma\ConfiguratorApiBundle\Structure\Frontend\CalculationResult,
    'cover' => Redhotmagma\ConfiguratorApiBundle\Service\ConfigurationDocument\Models\Cover,
    'documentInfo' => [
        'currentDate' => '',
        'channelSettings' => [...],
        'documentType' => 'user', // 'user' or 'production'
        'logoPath' => 'logo.png',
        'theme' => [...],
        'contactName' => '', // specified per client/globally in adminarea
        'contactStreet' => '',
        'contactPostCode' => '',
        'contactCity' => '',
        'contactPhone' => '',
        'contactEmail' => '',
        'displayNetPrices' => false
    ],
    'editedDesignAreas' => Redhotmagma\ConfiguratorApiBundle\Service\ConfigurationDocument\ModelsEditedDesignArea[],
    'preview' => Redhotmagma\ConfiguratorApiBundle\Service\ConfigurationDocument\Models\Preview
];

Note

Twig is a powerful template engine to generate html. For more info see: https://twig.symfony.com/ In configuratorware the PDF is generated out of html via weasyprint, see https://weasyprint.org/

Change Contents

The data array (see Change Template) for the template can be changed by listening to the Event Redhotmagma\ConfiguratorApiBundle\Events\ConfigurationDocument\DataCollectionEvent. Be aware that configuratorware itself uses this event to populate the data and therefore the listener must be registered after the internal listeners to overwrite.

Weasyprint

Up to version 1.24 configuratorware depended on weasyprint as PDF generator. From 1.25 on the default pdf generator is Dompdf which is installed via composer automatically without any further infrastructure requirement. If you did not customize your template, there is nothing to do. Otherwise you have 2 options:

  1. adapt your template to work with DomPDF

  2. adapt your service config as follows to continue to use weasyprint:

Redhotmagma\ConfiguratorApiBundle\Vector\HtmlPdfConverterInterface:
    alias: Redhotmagma\ConfiguratorApiBundle\Vector\WeasyprintHtmlPdfConverter

API classes

The api classes define the public interface to the configurator functionality. Those services can be used in client projects to access functionality that is already provided by the configurator. E.g. if you want to load a configuration by its code you can use the method loadByConfigurationCode in the class ConfigurationApi.

You can find a complete list here: