Extendiendo Servicios de Sylius con Decoradores

La documentación de Sylius tiene varias vías para personalizar las principales funciones de este framework. Para la mayoría de los desarrolladores Sylius, extender sus funcionalidades no es un problema. Pero para los principiantes puede ser un poco confuso.

Casi todo en Sylius es un servicio, así que puedes inyectarlos en un controlador o cualquier otro servicio sin esfuerzo alguno. Estos usualmente poseen 2 ids, el nombre basado en vendor separado por comas como es sylius.calculator.product_variant_price y el basado en la interfaz que implementa Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface (La última es un alias para la primera, de esta forma solo necesitas cambiar la primera y con el autowire usarla en tus servicios).

De esta forma si quieres sobreescribir el servicio sylius.calculator.product_variant_price tu solo debes crear tu propio servicio e implementar su interfaz Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface, nombrar tu servicio sylius.calculator.product_variant_price o simplemente crear un alias:

[yaml]
# config/services.yaml
services:
    # ..
    sylius.calculator.product_variant_price: '@App\Calculator\MyCalculator'

Este es una solución simple pero trae sus complicaciones, como perder el servicio original y quizás solo quieras chequear algunos atributos antes de ejecutar el calculador (por ejemplo):

En este caso tenemos 3 posibles soluciones:

  1. Extender la clase original y sobreescribir lo que querramos. Imposible: Sylius ha hecho de sus servicios `final class` por lo que no podemos extenderlas.
  2. Copiar+Pegar el código original. Problema: Tienes que estar alerta para recopiar todo el código cuando cambie el código original por cualquier motivo, correcciones, arreglo de errores, etc.
  3. Decorar el servicio original. Mejor solución: Solo debes hacerlo :).

Decorando servicios en Symfony

Recomendamos el uso de este patrón siguiendo la documentación oficial de Symfony. Con este podemos inyectar el servicio original en el nuevo, vinculando todas las referencias hacia nuestro servicio y teniendo además la posibilidad de ejecutar el código original.

La documentación de Sylius habla y recomienda el uso de decoradores para sobreescribir Servicios Factorías. Pero no termina ahí, puedes hacer lo mismo para casi todos los servicios en Sylius, calculadores, procesadores, factorías y otros servicios.

Aquí está un ejemplo de App\Calculator\MyCalculator:

// src/Calculatror/MyCalculator.php
namespace App\Calculator;

use Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use App\Service\OtherService;

class MyCalculator implements ProductVariantPriceCalculatorInterface
{
    protected $calculator;
    protected $service;
    public function __construct(ProductVariantPriceCalculatorInterface $calculator, OtherService $service) 
    {
        $this->calculator = $calculator;
        $this->service = $service;
    }

    public function calculate(ProductVariantInterface $productVariant, array $context): int
    {
        $price = $this->calculator->calculate($productVariant, $context); //.. call before or alfer depend of your logic

        $price = $this->service->doSomethingWithThePrice($price); //.. do something the price

        return $price;
    }
}

Y defines la configuración:

[yaml]
# config/services.yaml
services:
    #..
    App\Calculator\MyCalculator:
        decorates: sylius.calculator.product_variant_price
        # pass the old service as an argument, with the name of the current service with the .inner at the end
        arguments: [‘@App\Calculator\MyCalculator.inner’, ‘@App\Service\OtherService’]

Ahora ya puedes extender cualquier servicio que quieras en Sylius.

Traducción del artículos original: https://medium.com/@pcabreus/extending-sylius-services-with-decorators-a5c3f76d07e2

Comentarios


Deja un comentario

Pedro Carlos Abreu

Pedro Carlos Abreu

Líder de PositibeLabs, emprendedor e innovador con visión open-source. Apacionado del Framework PHP Symfony, desarrolla aplicaciones y sitios web desde hace más de 7 años. Fan del universo DC y Marvel, practicante de Aikido en su tiempo libre.


Otros título del autor
Categorías
Noticias

Úlltimas noticias sobre Tecnología, Desarrollo de software, Negocios e Innovación en la web.


Servicios

Servicios de PositibeLabs. Desarrollo de software, Páginas web, Aplicaciones de Gestión Empresarial, SEO y Mercadotecnia.


Bundles

Bundles y librerías de códgio abierto de PositibeLabs Projects


Artículos

Artículos sobre desarrollo de software y tecnologías de la información.