Files
thetool/lib/mfBaseModelV2/README.md

3.4 KiB

mfBaseModelV2

Modern PHP 8+ base model with typed properties and automatic journaling.

Basic Usage

class ADBNetzgebiet extends mfBaseModelV2 {
    protected static string $__tableName = 'Netzgebiet';
    protected static string $__primaryKey = 'id'; // default

    public int $id;
    public ?string $name = null;
    public ?string $extref = null;
    public int $create;
    public int $edit;
}

Custom Database

protected static ?array $__databaseConfig = [
    'host' => ADDRESSDB_DBHOST,
    'user' => ADDRESSDB_DBUSER,
    'pass' => ADDRESSDB_DBPASS,
    'name' => ADDRESSDB_DBNAME
];

Static Methods

$model = MyModel::get(123);                    // by ID, returns ?static
$model = MyModel::getFirst(['name' => 'foo']); // first match
$all   = MyModel::getAll($filter, $limit, $offset, $order);
$all   = MyModel::search($filter);             // alias for getAll
$count = MyModel::count($filter);

Filter Operators

Prefix SQL Example
(none) LIKE %...% ['name' => 'foo']
= = exact ['=name' => 'foo']
! != / NOT IN ['!status' => 'deleted']
> < >= <= comparison ['>create' => $timestamp]

Special values:

['status' => null]           // IS NULL
['!status' => null]          // IS NOT NULL
['id' => [1, 2, 3]]          // IN (1, 2, 3)
['!id' => [1, 2, 3]]         // NOT IN (1, 2, 3)

Ordering

MyModel::getAll([], null, 0, ['column' => 'name', 'dir' => 'ASC']);

Instance Methods

$model->save();              // insert or update
$model->delete();
$model->isLoaded();
$model->getId();
$model->toArray();
$model->toJson();
$model->getJournalHistory(); // returns change history

Hooks

public function validate(): array {
    $errors = [];
    if (empty($this->name)) $errors[] = 'Name required';
    return $errors; // empty = valid
}

protected function beforeSave(bool $isInsert): bool {
    return true; // false cancels save
}

protected function afterSave(bool $isInsert, array $changes): void {
    // $changes = ['field' => ['old' => x, 'new' => y]]
}

Journaling

Automatic change tracking to Journal table. Configure field labels:

protected static array $__journalFieldMap = [
    'name' => 'Name',
    'extref' => 'External Reference',
];

Disable per model:

protected static bool $__enableJournaling = false;

Auto-timestamps

If properties exist, they're set automatically on save:

  • create, create_by - on insert
  • edit, edit_by - on insert/update

Magic Properties with Intellisense

Use @property-read for lazy-loaded relations:

/**
 * @property-read ADBNetzgebietRelations $relations
 */
class ADBNetzgebiet extends mfBaseModelV2 {
    private ?ADBNetzgebietRelations $__relations = null;

    public function __get(string $name) {
        if ($name === 'relations') {
            return $this->__relations ??= $this->loadRelations();
        }
        return null;
    }

    public function loadRelations(): ADBNetzgebietRelations {
        // ...
    }
}

Typed relation class for IDE support:

class ADBNetzgebietRelations {
    /** @var array{id: int, name: string}[] */
    public array $networks = [];
    /** @var array{id: int, name: string}[] */
    public array $campaigns = [];
}

Usage with full autocomplete:

$model = ADBNetzgebiet::get(1);
$model->relations->networks; // IDE knows this is array{id: int, name: string}[]