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 servicio | Descripcion |
|---|---|
| prestashop.adapter.legacy.configuration | Clase Configuration (get/set) |
| doctrine.orm.default_entity_manager | Entity Manager de Doctrine |
| prestashop.core.hook.dispatcher | Dispatcher de hooks |
| prestashop.core.localization.locale.context | Contexto de locale actual |
| translator | Servicio de traducciones Symfony |
| logger | Logger de Symfony/Monolog |
| event_dispatcher | Dispatcher de eventos Symfony |
| form.factory | Factory de formularios Symfony |
| router | Router de Symfony |
| session | Sesion HTTP de Symfony |
| security.token_storage | Token de seguridad actual |
| prestashop.adapter.shop.context | Contexto 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.