<?phpnamespace FacturaScripts\Plugins\YourPlugin\Model;use FacturaScripts\Core\Template\ModelClass;use FacturaScripts\Core\Template\ModelTrait;class MyModel extends ModelClass{ use ModelTrait; /** * Primary key * @var int */ public $id; /** * Model name * @var string */ public $name; /** * Description * @var string */ public $description; /** * Active status * @var bool */ public $active; /** * Creation date * @var string */ public $created_at; /** * Returns the primary column name */ public static function primaryColumn(): string { return 'id'; } /** * Returns the table name */ public static function tableName(): string { return 'mymodel'; } /** * Reset default values */ public function clear() { parent::clear(); $this->active = true; $this->created_at = date('Y-m-d H:i:s'); } /** * Returns the installation SQL */ public function install(): string { return ''; }}
public function install(): string{ // Return empty string if table is defined in Table/ XML return ''; // Or return custom SQL return 'CREATE INDEX idx_mymodel_name ON mymodel(name);';}
use FacturaScripts\Plugins\YourPlugin\Model\MyModel;// Method 1: Create and save$model = new MyModel();$model->name = 'Example';$model->description = 'This is an example';if ($model->save()) { echo 'Saved with ID: ' . $model->id;}// Method 2: Create with data$model = MyModel::create([ 'name' => 'Example', 'description' => 'This is an example']);// Method 3: Update or create$model = MyModel::updateOrCreate( ['name' => 'Example'], // Find by these fields ['description' => 'Updated'] // Update these fields);// Method 4: Find or create$model = MyModel::findOrCreate( ['name' => 'Example'], // Find by these fields ['description' => 'Default'] // Create with these if not found);
use FacturaScripts\Core\Base\DataBase;$db = new DataBase();// Select$sql = 'SELECT * FROM mymodel WHERE active = ? ORDER BY name';$data = $db->select($sql, [true]);// Execute$sql = 'UPDATE mymodel SET active = ? WHERE id = ?';$db->exec($sql, [false, $id]);
class MyModel extends ModelClass{ /** @var int Primary key */ public $id; /** @var string */ public $name; /** @var float */ public $price; /** @var bool */ public $active; /** @var string Date in Y-m-d format */ public $created_at;}
class Customer extends ModelClass{ use ModelTrait; public $id; public $name; /** * Get customer invoices * @return Invoice[] */ public function getInvoices(): array { return Invoice::all( ['customer_id' => $this->id], ['date' => 'DESC'] ); }}class Invoice extends ModelClass{ use ModelTrait; public $id; public $customer_id; public $total; /** * Get customer * @return Customer|null */ public function getCustomer(): ?Customer { return Customer::find($this->customer_id); }}
class Product extends ModelClass{ use ModelTrait; public $id; public $name; /** * Get product categories * @return Category[] */ public function getCategories(): array { $sql = ' SELECT c.* FROM categories c INNER JOIN product_category pc ON c.id = pc.category_id WHERE pc.product_id = ? '; $data = static::db()->select($sql, [$this->id]); $categories = []; foreach ($data as $row) { $categories[] = new Category($row); } return $categories; }}
use FacturaScripts\Core\Model\Base\TaxRelationTrait;class Product extends ModelClass{ use ModelTrait; use TaxRelationTrait; public $codimpuesto; // Tax code public $iva; // Tax percentage // TaxRelationTrait provides tax-related methods}
Models automatically cache field definitions. Clear cache when needed:
public function install(): string{ // Clear model cache after structure changes $this->clearCache(); return '';}// Clear specific model cacheMyModel::clearCache();// Or use the cache system directlyuse FacturaScripts\Core\Cache;Cache::clear();
Here’s a complete model with validation, relationships, and custom methods:
<?phpnamespace FacturaScripts\Plugins\YourPlugin\Model;use FacturaScripts\Core\Template\ModelClass;use FacturaScripts\Core\Template\ModelTrait;use FacturaScripts\Core\Tools;class Product extends ModelClass{ use ModelTrait; public $id; public $reference; public $name; public $description; public $price; public $stock; public $active; public $created_at; public $updated_at; public static function primaryColumn(): string { return 'id'; } public static function tableName(): string { return 'products'; } public function clear() { parent::clear(); $this->active = true; $this->stock = 0; $this->price = 0.0; $this->created_at = date('Y-m-d H:i:s'); } public function test(): bool { $this->reference = trim($this->reference); $this->name = trim($this->name); if (empty($this->reference)) { Tools::log()->warning('product-reference-required'); return false; } if (empty($this->name)) { Tools::log()->warning('product-name-required'); return false; } if ($this->price < 0) { Tools::log()->warning('product-price-negative'); return false; } // Check for duplicate reference if ($this->checkDuplicate()) { Tools::log()->warning('product-reference-duplicate'); return false; } return parent::test(); } public function save(): bool { $this->updated_at = date('Y-m-d H:i:s'); return parent::save(); } public function install(): string { return 'CREATE INDEX idx_products_reference ON products(reference);'; } /** * Check if reference is already used */ private function checkDuplicate(): bool { $duplicate = static::findWhere([ ['reference', '=', $this->reference], ['id', '!=', $this->id] ]); return $duplicate !== null; } /** * Check if product is in stock */ public function inStock(): bool { return $this->stock > 0; } /** * Reduce stock by quantity */ public function reduceStock(float $quantity): bool { if ($this->stock < $quantity) { Tools::log()->warning('insufficient-stock'); return false; } $this->stock -= $quantity; return $this->save(); } /** * Get formatted price with currency */ public function formattedPrice(): string { return Tools::money($this->price); }}