Files
thetool/lib/mfBaseModelV2/README.md

156 lines
3.4 KiB
Markdown

# mfBaseModelV2
Modern PHP 8+ base model with typed properties and automatic journaling.
## Basic Usage
```php
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
```php
protected static ?array $__databaseConfig = [
'host' => ADDRESSDB_DBHOST,
'user' => ADDRESSDB_DBUSER,
'pass' => ADDRESSDB_DBPASS,
'name' => ADDRESSDB_DBNAME
];
```
## Static Methods
```php
$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:**
```php
['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
```php
MyModel::getAll([], null, 0, ['column' => 'name', 'dir' => 'ASC']);
```
## Instance Methods
```php
$model->save(); // insert or update
$model->delete();
$model->isLoaded();
$model->getId();
$model->toArray();
$model->toJson();
$model->getJournalHistory(); // returns change history
```
## Hooks
```php
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:
```php
protected static array $__journalFieldMap = [
'name' => 'Name',
'extref' => 'External Reference',
];
```
Disable per model:
```php
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:
```php
/**
* @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:
```php
class ADBNetzgebietRelations {
/** @var array{id: int, name: string}[] */
public array $networks = [];
/** @var array{id: int, name: string}[] */
public array $campaigns = [];
}
```
Usage with full autocomplete:
```php
$model = ADBNetzgebiet::get(1);
$model->relations->networks; // IDE knows this is array{id: int, name: string}[]
```