🏗️ CRUD completo — ObjectModel + HelperForm + HelperList

Actualizado: 2024-12-01

Un CRUD completo en el BO de PrestaShop combina tres elementos: un ObjectModel para la capa de datos, un ModuleAdminController para la logica y un par HelperList + HelperForm para la UI. Este patron funciona desde PS 1.6 hasta PS 9.

#El ObjectModel

src/Entity/MyItem.php — ObjectModel basico
php
<?php

class MyModuleItem extends ObjectModel
{
    public $name;
    public $description;
    public $active = 1;
    public $sort_order = 0;
    public $date_add;
    public $date_upd;

    public static $definition = [
        'table'   => 'mymodule_item',
        'primary' => 'id_mymodule_item',
        'multilang' => false,
        'fields'  => [
            'name'        => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 255],
            'description' => ['type' => self::TYPE_HTML,   'validate' => 'isCleanHtml'],
            'active'      => ['type' => self::TYPE_BOOL,   'validate' => 'isBool'],
            'sort_order'  => ['type' => self::TYPE_INT,    'validate' => 'isUnsignedInt'],
            'date_add'    => ['type' => self::TYPE_DATE,   'validate' => 'isDate'],
            'date_upd'    => ['type' => self::TYPE_DATE,   'validate' => 'isDate'],
        ],
    ];

    public static function getItems(bool $activeOnly = false): array
    {
        $sql = 'SELECT * FROM `' . _DB_PREFIX_ . 'mymodule_item`';
        if ($activeOnly) {
            $sql .= ' WHERE `active` = 1';
        }
        $sql .= ' ORDER BY `sort_order` ASC';
        return Db::getInstance()->executeS($sql) ?: [];
    }
}

#El AdminController

controllers/admin/AdminMyModuleItemsController.php
php
<?php

class AdminMyModuleItemsController extends ModuleAdminController
{
    public function __construct()
    {
        $this->table        = 'mymodule_item';
        $this->className    = 'MyModuleItem';
        $this->identifier   = 'id_mymodule_item';
        $this->lang         = false;  // true si multilang
        $this->addRowAction('edit');
        $this->addRowAction('delete');
        $this->bulk_actions = [
            'delete' => [
                'text'    => $this->trans('Delete selected', [], 'Admin.Actions'),
                'confirm' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'),
                'icon'    => 'icon-trash',
            ],
        ];
        parent::__construct();
    }
}

#HelperList — listado de registros

fields_list y renderList() en el AdminController
php
<?php

// Definir columnas del listado (en __construct o como propiedad)
$this->fields_list = [
    'id_mymodule_item' => [
        'title'  => 'ID',
        'align'  => 'center',
        'class'  => 'fixed-width-xs',
    ],
    'name' => [
        'title'  => 'Nombre',
        'filter_key' => 'a!name',  // 'a' = alias de la tabla principal
    ],
    'active' => [
        'title'   => 'Activo',
        'active'  => 'status',      // activa el toggle de on/off
        'type'    => 'bool',
        'align'   => 'center',
        'class'   => 'fixed-width-sm',
    ],
    'sort_order' => [
        'title'  => 'Orden',
        'align'  => 'center',
        'class'  => 'fixed-width-sm',
    ],
    'date_add' => [
        'title'  => 'Creado',
        'type'   => 'datetime',
        'filter_key' => 'a!date_add',
    ],
];

// El ModuleAdminController renderiza el listado automaticamente
// cuando $this->display == 'list' (valor por defecto)

#HelperForm — formulario de edicion

renderForm() en el AdminController
php
<?php

public function renderForm(): string
{
    $this->fields_form = [
        'legend' => [
            'title' => 'Item',
            'icon'  => 'icon-cogs',
        ],
        'input' => [
            [
                'type'     => 'text',
                'label'    => 'Nombre',
                'name'     => 'name',
                'required' => true,
                'col'      => 6,
                'hint'     => 'Nombre del item (requerido)',
            ],
            [
                'type'  => 'textarea',
                'label' => 'Descripcion',
                'name'  => 'description',
                'cols'  => 60,
                'rows'  => 10,
                'autoload_rte' => true,  // activa el editor WYSIWYG
            ],
            [
                'type'   => 'text',
                'label'  => 'Orden',
                'name'   => 'sort_order',
                'class'  => 'fixed-width-sm',
            ],
            [
                'type'   => 'switch',
                'label'  => 'Activo',
                'name'   => 'active',
                'values' => [
                    ['id' => 'active_on',  'value' => 1, 'label' => 'Si'],
                    ['id' => 'active_off', 'value' => 0, 'label' => 'No'],
                ],
            ],
        ],
        'submit' => [
            'title' => $this->trans('Save', [], 'Admin.Actions'),
        ],
    ];

    return parent::renderForm();
}

#Registrar el Tab en install()

Registrar el Tab del AdminController en install()
php
<?php

// En mymodule.php
public function install(): bool
{
    return parent::install()
        && $this->installTab();
}

public function uninstall(): bool
{
    return $this->uninstallTab()
        && parent::uninstall();
}

private function installTab(): bool
{
    $tab = new Tab();
    $tab->class_name = 'AdminMyModuleItems';
    $tab->module     = $this->name;
    $tab->id_parent  = (int) Tab::getIdFromClassName('AdminCatalog'); // bajo Catalogo
    $tab->icon       = 'icon-cogs'; // solo PS 1.7+
    foreach (Language::getLanguages() as $lang) {
        $tab->name[$lang['id_lang']] = 'Mis Items';
    }
    return (bool) $tab->add();
}

private function uninstallTab(): bool
{
    $id = (int) Tab::getIdFromClassName('AdminMyModuleItems');
    if ($id) {
        $tab = new Tab($id);
        return (bool) $tab->delete();
    }
    return true;
}
Descargar en Markdown Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.