🔷 Doctrine, ObjectModel y Multistore — 3 modulos
#demodoctrine — Entidades Doctrine ORM
Demuestra como usar entidades Doctrine en PrestaShop 9.0+ en lugar de ObjectModel. Doctrine es el ORM recomendado para nuevos desarrollos en PS 9.x.
github.com/PrestaShop/example-modules/tree/master/demodoctrine
#Definir entidad Doctrine
<?php
// src/Entity/DemoEntity.php
namespace PrestaShop\Module\DemoDoctrine\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: DemoEntityRepository::class)]
#[ORM\Table(name: 'ps_demo_doctrine_entity')]
class DemoEntity
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private ?int $id = null;
#[ORM\Column(type: 'string', length: 255)]
private string $name;
#[ORM\Column(type: 'text', nullable: true)]
private ?string $description = null;
#[ORM\Column(type: 'boolean')]
private bool $active = true;
#[ORM\Column(type: 'datetime_immutable')]
private \DateTimeImmutable $createdAt;
public function __construct(string $name)
{
$this->name = $name;
$this->createdAt = new \DateTimeImmutable();
}
public function getId(): ?int { return $this->id; }
public function getName(): string { return $this->name; }
public function setName(string $name): self { $this->name = $name; return $this; }
public function getDescription(): ?string { return $this->description; }
public function setDescription(?string $desc): self { $this->description = $desc; return $this; }
public function isActive(): bool { return $this->active; }
public function setActive(bool $active): self { $this->active = $active; return $this; }
}
#Repository y DQL
<?php
// src/Repository/DemoEntityRepository.php
namespace PrestaShop\Module\DemoDoctrine\Repository;
use Doctrine\ORM\EntityRepository;
use PrestaShop\Module\DemoDoctrine\Entity\DemoEntity;
class DemoEntityRepository extends EntityRepository
{
public function findActiveItems(): array
{
return $this->createQueryBuilder('d')
->where('d.active = :active')
->setParameter('active', true)
->orderBy('d.createdAt', 'DESC')
->getQuery()
->getResult();
}
public function findByNameLike(string $search): array
{
return $this->createQueryBuilder('d')
->where('d.name LIKE :search')
->setParameter('search', '%' . $search . '%')
->getQuery()
->getResult();
}
}
# config/services.yml
services:
_defaults:
autowire: true
autoconfigure: true
# Doctrine mapping - registrar entidades del modulo
doctrine:
orm:
mappings:
DemoDoctrine:
type: attribute
dir: '%kernel.project_dir%/modules/demodoctrine/src/Entity'
prefix: 'PrestaShop\Module\DemoDoctrine\Entity'
is_bundle: false
<?php
public function install(): bool
{
// Opcion 1: SQL directo
$sql = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'demo_doctrine_entity` (
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL,
`description` TEXT NULL,
`active` TINYINT(1) NOT NULL DEFAULT 1,
`created_at` DATETIME NOT NULL
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8mb4';
return parent::install() && Db::getInstance()->execute($sql);
// Opcion 2: Doctrine Schema Tool (PS 9.0+)
// $entityManager = $this->get('doctrine.orm.entity_manager');
// $schemaTool = new SchemaTool($entityManager);
// $schemaTool->createSchema([
// $entityManager->getClassMetadata(DemoEntity::class)
// ]);
}
#demooverrideobjectmodel — Override ObjectModel
Muestra como hacer un override de ObjectModel (ej: Manufacturer) y anadir un campo custom a la tabla de BD. Requiere PS 9.0+.
github.com/PrestaShop/example-modules/tree/master/demooverrideobjectmodel
<?php
// override/classes/Manufacturer.php
class Manufacturer extends ManufacturerCore
{
/** @var string Custom field added by module */
public $demo_custom_field;
}
// Tambien actualizar $definition en el modulo:
public function install(): bool
{
// 1. Anadir columna a la tabla
$sql = 'ALTER TABLE `' . _DB_PREFIX_ . 'manufacturer`
ADD `demo_custom_field` VARCHAR(255) NULL DEFAULT NULL';
Db::getInstance()->execute($sql);
// 2. Copiar el override
return parent::install()
&& $this->registerHook('actionManufacturerFormBuilderModifier')
&& $this->registerHook('actionAfterUpdateManufacturerFormHandler')
&& $this->registerHook('actionAfterCreateManufacturerFormHandler');
}
public function uninstall(): bool
{
// Limpiar: quitar columna y override
Db::getInstance()->execute(
'ALTER TABLE `' . _DB_PREFIX_ . 'manufacturer` DROP COLUMN `demo_custom_field`'
);
return parent::uninstall();
}
#demomultistoreform — Multitienda CRUD
Demuestra como hacer formularios compatibles con multitienda en un contexto CRUD. Compatible desde PS 1.7.8.
github.com/PrestaShop/example-modules/tree/master/demomultistoreform
<?php
// Guardar configuracion respetando el contexto de tienda
public function postProcess(): void
{
if (Tools::isSubmit('submitDemoConfig')) {
// Configuration::updateValue() automaticamente
// guarda para el shop context actual
Configuration::updateValue(
'DEMO_MULTISTORE_SETTING',
Tools::getValue('demo_setting')
);
// Para guardar para una tienda especifica:
Configuration::updateValue(
'DEMO_MULTISTORE_SETTING',
Tools::getValue('demo_setting'),
false, // html
null, // id_shop_group
$shopId // id_shop especifico
);
}
}
// Leer respetando contexto:
public function getConfigValue(): string
{
// Automatico segun contexto actual del BO
return Configuration::get('DEMO_MULTISTORE_SETTING');
// O para una tienda especifica:
// return Configuration::get('DEMO_MULTISTORE_SETTING', null, null, $shopId);
}
- Nuevo modulo PS 9+ only: usa Doctrine (demodoctrine) - Modulo retro-compatible 1.7/8/9: usa ObjectModel (sigue funcionando) - Extender entidad core: usa override (demooverrideobjectmodel) - CRUD multitienda: usa Configuration con shop context (demomultistoreform)