Servicios e Inyeccion de Dependencias en modulos

Actualizado: 2024-12-01

PrestaShop 8+ integra el contenedor de servicios de Symfony. Los modulos pueden registrar sus propias clases como servicios y usar inyeccion de dependencias, lo que facilita el testing, desacopla la logica y permite acceder a servicios del core de forma elegante.

#Estructura config/services.yml

config/services.yml — estructura completa de un modulo
yaml
services:
  # ── DEFAULTS ──
  # Con autowire + autoconfigure no necesitas declarar argumentos manualmente
  _defaults:
    autowire: true
    autoconfigure: true
    public: true

  # ── AUTO-DESCUBRIMIENTO (recomendado para PS 8+) ──
  # Registra automaticamente todas las clases en src/
  MyModule\:
    resource: '../src/*'
    exclude:
      - '../src/Entity/*'  # Las entidades Doctrine NO como servicios
      - '../src/DTO/*'

  # ── SERVICIO INDIVIDUAL (cuando necesitas control fino) ──
  MyModule\Service\ProductSyncService:
    class: MyModule\Service\ProductSyncService
    arguments:
      - '@doctrine.orm.default_entity_manager'
      - '@prestashop.adapter.legacy.configuration'
      - '@logger'
    tags:
      - { name: 'monolog.logger', channel: 'mymodule' }

  # ── COMANDO DE CONSOLA ──
  MyModule\Command\SyncCommand:
    tags:
      - { name: console.command }

#Autowiring y autoconfiguration

Clase con inyeccion de dependencias via constructor (autowire)
php
<?php

declare(strict_types=1);

namespace MyModule\Service;

use Doctrine\ORM\EntityManagerInterface;
use PrestaShop\PrestaShop\Adapter\Configuration;
use Psr\Log\LoggerInterface;

/**
 * Con autowire=true, Symfony inyecta automaticamente
 * las dependencias declaradas en el constructor.
 */
class ProductSyncService
{
    private EntityManagerInterface $em;
    private Configuration          $config;
    private LoggerInterface        $logger;

    public function __construct(
        EntityManagerInterface $em,
        Configuration $config,
        LoggerInterface $logger
    ) {
        $this->em     = $em;
        $this->config = $config;
        $this->logger = $logger;
    }

    public function sync(int $productId): bool
    {
        $apiKey = $this->config->get('MY_MODULE_API_KEY');
        $this->logger->info('Syncing product', ['id' => $productId]);

        // ... logica de sincronizacion
        return true;
    }
}

#Acceder a servicios desde el modulo

Acceder al contenedor de servicios desde mymodule.php
php
<?php

// Desde dentro del modulo (mymodule.php) — con el servicio de PS
class MyModule extends Module
{
    /**
     * Obtener el contenedor de servicios de Symfony.
     * Solo disponible en PS 1.7.6+ y en contexto HTTP (no en CLI sin inicializar).
     */
    private function getContainer(): \Symfony\Component\DependencyInjection\ContainerInterface
    {
        if ($this->context->controller instanceof \Symfony\Component\HttpFoundation\Request) {
            return $this->get('service_container');
        }
        return \PrestaShop\PrestaShop\Adapter\SymfonyContainer::getInstance();
    }

    public function hookActionOrderStatusUpdate(array $params): void
    {
        // Obtener servicio por clase (recomendado)
        $container    = \PrestaShop\PrestaShop\Adapter\SymfonyContainer::getInstance();
        $syncService  = $container->get(\MyModule\Service\ProductSyncService::class);

        $syncService->sync((int) $params['id_order']);
    }
}

#Servicios del core mas usados

ID del servicioDescripcion
prestashop.adapter.legacy.configurationClase Configuration (get/set)
doctrine.orm.default_entity_managerEntity Manager de Doctrine
prestashop.core.hook.dispatcherDispatcher de hooks
prestashop.core.localization.locale.contextContexto de locale actual
translatorServicio de traducciones Symfony
loggerLogger de Symfony/Monolog
event_dispatcherDispatcher de eventos Symfony
form.factoryFactory de formularios Symfony
routerRouter de Symfony
sessionSesion HTTP de Symfony
security.token_storageToken de seguridad actual
prestashop.adapter.shop.contextContexto de tienda (multistore)

#Crear un servicio propio

src/Repository/MyItemRepository.php — repositorio como servicio
php
<?php

declare(strict_types=1);

namespace MyModule\Repository;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use MyModule\Entity\MyItem;

class MyItemRepository
{
    private EntityRepository $repository;

    public function __construct(EntityManagerInterface $em)
    {
        $this->repository = $em->getRepository(MyItem::class);
    }

    /** @return MyItem[] */
    public function findAllActive(): array
    {
        return $this->repository->findBy(['active' => true], ['sortOrder' => 'ASC']);
    }

    public function findById(int $id): ?MyItem
    {
        return $this->repository->find($id);
    }
}
Descargar en Markdown Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.