🔷 Doctrine, ObjectModel y Multistore — 3 modulos

Actualizado: 2026-04

#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.

ℹ️
Repositorio

github.com/PrestaShop/example-modules/tree/master/demodoctrine

#Definir entidad Doctrine

Entidad Doctrine con atributos PHP 8
php
<?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

Repository con metodos custom
php
<?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();
    }
}
Registrar Doctrine mapping en services.yml
yaml
# 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
Crear tabla en install() con Doctrine schema
php
<?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+.

ℹ️
Repositorio

github.com/PrestaShop/example-modules/tree/master/demooverrideobjectmodel

Override de Manufacturer con campo custom
php
<?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.

ℹ️
Repositorio

github.com/PrestaShop/example-modules/tree/master/demomultistoreform

Configuracion por tienda en CRUD
php
<?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);
}
💡
Doctrine vs ObjectModel en PS 9.x

- 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)

Descargar en Markdown Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.