🔷 ObjectModel — Referencia completa
Actualizado: 2024-12-01
ObjectModel es la capa de abstraccion de base de datos propia de PrestaShop. Define la estructura de las tablas, las validaciones y las operaciones CRUD de forma declarativa mediante el array $definition.
#La propiedad $definition
Estructura completa de $definition
php
<?php
class MyEntity extends ObjectModel
{
// ── Propiedades publicas (una por cada campo en DB) ──
public $name; // campo multilang
public $description; // campo multilang
public $active;
public $price;
public $sort_order;
public $id_category; // FK a otra tabla
public $date_add;
public $date_upd;
public static $definition = [
'table' => 'mymodule_entity', // Nombre sin prefijo
'primary' => 'id_mymodule_entity', // Clave primaria
'multilang' => true, // true = tabla _lang para campos con 'lang'=>true
'multilang_shop' => false, // true = tabla _lang_shop (multilang + multitienda)
'multishop' => false, // true = tabla _shop para datos por tienda
'fields' => [
// ── Campos simples ──
'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
'price' => ['type' => self::TYPE_FLOAT, 'validate' => 'isPrice', 'shop' => true],
'sort_order' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'default' => 0],
'id_category' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
'date_upd' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
// ── Campos multiidioma (van a tabla _lang) ──
'name' => [
'type' => self::TYPE_STRING,
'lang' => true,
'validate' => 'isCatalogName',
'required' => true,
'size' => 255,
],
'description' => [
'type' => self::TYPE_HTML,
'lang' => true,
'validate' => 'isCleanHtml',
'allow_html' => true,
],
],
];
}
#Tipos de campo disponibles
| Constante | PHP Type | Descripcion |
|---|---|---|
| TYPE_INT | int | Entero (incluye negativos) |
| TYPE_UINT | int | Entero sin signo (>=0) |
| TYPE_BOOL | bool | Booleano (0 o 1) |
| TYPE_STRING | string | Texto plano (se escapa) |
| TYPE_HTML | string | HTML (se usa isCleanHtml) |
| TYPE_FLOAT | float | Numero decimal |
| TYPE_DATE | string | Fecha formato Y-m-d H:i:s |
| TYPE_NOTHING | - | Campo sin mapeo especial |
#Campos multiidioma
Crear tabla principal y tabla _lang
php
<?php
// ── SQL para tabla principal ──
CREATE TABLE IF NOT EXISTS `ps_mymodule_entity` (
`id_mymodule_entity` int(10) unsigned NOT NULL AUTO_INCREMENT,
`id_category` int(10) unsigned NOT NULL DEFAULT 0,
`active` tinyint(1) unsigned NOT NULL DEFAULT 1,
`price` decimal(20,6) NOT NULL DEFAULT 0.000000,
`sort_order` int(10) unsigned NOT NULL DEFAULT 0,
`date_add` datetime NOT NULL,
`date_upd` datetime NOT NULL,
PRIMARY KEY (`id_mymodule_entity`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
// ── SQL para tabla _lang (campos multiidioma) ──
CREATE TABLE IF NOT EXISTS `ps_mymodule_entity_lang` (
`id_mymodule_entity` int(10) unsigned NOT NULL,
`id_lang` int(10) unsigned NOT NULL,
`id_shop` int(10) unsigned NOT NULL DEFAULT 1,
`name` varchar(255) NOT NULL,
`description` text,
PRIMARY KEY (`id_mymodule_entity`, `id_lang`, `id_shop`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
// ── Usar multilang en PHP ──
$entity = new MyEntity();
$entity->name = [
1 => 'Nombre en espanol', // id_lang => valor
2 => 'Name in English',
];
$entity->description[1] = '<p>Descripcion en espanol</p>';
$entity->active = true;
$entity->add();
// ── Leer con idioma especifico ──
$entity = new MyEntity(42, $id_lang); // Carga el objeto con el idioma dado
echo $entity->name; // 'Nombre en espanol' si id_lang = 1
#Operaciones CRUD
CRUD completo con ObjectModel
php
<?php
// ── CREATE ──
$entity = new MyEntity();
$entity->name = [1 => 'Test', 2 => 'Test EN'];
$entity->active = true;
$entity->price = 19.99;
$result = $entity->add(); // bool
$newId = $entity->id; // ID insertado
// ── READ ──
$entity = new MyEntity(42); // Carga por ID (sin idioma)
$entity = new MyEntity(42, $id_lang); // Carga por ID con idioma
// Verificar que se cargo correctamente:
if (!Validate::isLoadedObject($entity)) {
throw new \Exception('Entity not found');
}
// ── UPDATE ──
$entity = new MyEntity(42, $id_lang);
$entity->price = 24.99;
$entity->active = false;
$result = $entity->update(); // bool
// ── DELETE ──
$entity = new MyEntity(42);
$result = $entity->delete(); // bool
// ── Soft delete (marcar como inactivo) ──
$entity->active = 0;
$entity->update();
// ── Comprobar existencia ──
$exists = MyEntity::existsInDatabase(42, 'mymodule_entity'); // bool
#Validaciones de campo
| Validate:: | Descripcion |
|---|---|
| isName($s) | Nombre personal (letras, espacios, guiones) |
| isCatalogName($s) | Nombre de catalogo (mas permisivo) |
| isGenericName($s) | Nombre generico |
| isCleanHtml($s) | HTML limpio (sin scripts) |
| isUnsignedId($n) | ID positivo |
| isUnsignedInt($n) | Entero positivo |
| isPrice($f) | Precio (decimal positivo) |
| isDate($d) | Fecha formato Y-m-d |
| isEmail($e) | Email valido |
| isUrl($u) | URL valida |
| isMd5($s) | Hash MD5 valido |
| isBool($b) | 0 o 1 |
| isColor($s) | Color hexadecimal #RRGGBB |
| isAbsoluteUrl($u) | URL absoluta con protocolo |
#Metodos de busqueda
Metodos estaticos de busqueda en ObjectModel
php
<?php
// ── getAll(): todos los registros ──
// No existe por defecto — hay que implementarlo:
public static function getAll(int $idLang = 0, bool $activeOnly = false): array
{
$q = new DbQuery();
$q->select('e.*, el.name, el.description');
$q->from('mymodule_entity', 'e');
if ($idLang) {
$q->leftJoin('mymodule_entity_lang', 'el',
'e.id_mymodule_entity = el.id_mymodule_entity AND el.id_lang = ' . (int) $idLang
);
}
if ($activeOnly) {
$q->where('e.active = 1');
}
$q->orderBy('e.sort_order ASC, e.date_add DESC');
return Db::getInstance()->executeS($q) ?: [];
}
// ── Busqueda por campo especifico ──
public static function getByCategory(int $idCategory, int $idLang): array
{
return Db::getInstance()->executeS(
(new DbQuery())
->select('e.*, el.name')
->from('mymodule_entity', 'e')
->innerJoin('mymodule_entity_lang', 'el',
'e.id_mymodule_entity = el.id_mymodule_entity AND el.id_lang = ' . (int) $idLang
)
->where('e.id_category = ' . (int) $idCategory)
->where('e.active = 1')
) ?: [];
}
#Multitienda
ObjectModel con soporte multitienda
php
<?php
// En $definition:
'multishop' => true, // Activa tabla _shop
// Esto crea una tabla ps_mymodule_entity_shop con:
// (id_mymodule_entity, id_shop) + los campos marcados con 'shop' => true
// Campos que se pueden sobreescribir por tienda:
'price' => ['type' => self::TYPE_FLOAT, 'validate' => 'isPrice', 'shop' => true],
// ── Leer datos de la tienda actual ──
Shop::addTableAssociation('mymodule_entity', ['type' => 'shop']);
$entity = new MyEntity(42);
// Si multishop activo, carga automaticamente los datos de Context::shop
// ── Actualizar para una tienda especifica ──
$entity = new MyEntity(42);
$entity->price = 15.99;
$entity->setFieldsToUpdate(['price' => true]); // Solo actualiza este campo
$entity->update();
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.