rancoud / model
Model package
Installs: 6 754
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 3
Forks: 0
Open Issues: 0
Requires
- php: >=7.4.0
- ext-json: *
- ext-mbstring: *
- ext-pdo: *
- rancoud/database: ^6.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.16 || ^3.0
- phpunit/phpunit: ^9.1 || ^10.0 || ^11.0
- squizlabs/php_codesniffer: ^3.5
Suggests
- ext-pdo_mysql: Needed to connect MySQL
- ext-pdo_pgsql: Needed to connect PostgreSQL
- ext-pdo_sqlite: Needed to connect SQLite
README
Abstract Model for better data manipulation between code and database.
Dependencies
Database package: https://github.com/rancoud/Database
Installation
composer require rancoud/model
How to use it?
Extends Rancoud\Model\Model to your class.
You have to implement two abstract methods setFields and setTable.
- setFields is for setting the fields in table
- setTable is for setting the table in database
class User extends Model { protected function setFields(): void { $this->fields = [ 'id' => new Field('int', ['not_null', 'unsigned', 'pk']), 'nickname' => new Field('varchar', ['max:255', 'not_null']) ]; } protected function setTable(): void { $this->table = 'user'; } }
What is Field?
Field represent a field in the table.
It have 3 arguments:
- field type
- rules
- default value
Field type
It support those field type
- int
- float
- char
- varchar
- text
- date
- datetime
- time
- timestamp
- year
- enum:x,y,z (x,y,z represent each possible value)
Rules
- pk : primary key
- fk : foreign key
- unsigned : only positive value
- email : check if it is valid email
- not_null : can't be null
- max:x : max size (x is size)
- min:x : min size (x is size)
- range:x,y : min size + max size (x is min size, y is max size)
Custom rule
class MyRule extends CustomRule { public function applyRule($value) { if ($value === 'azerty') { throw new FieldException('invalid azerty value'); } return $value; } }
Default
When value is not setted it can be set with those argument
Helpers
It have methods for pagination, create, read, update and delete.
// $database is an instance of Rancoud\Database\Database $user = new User($database); $newId = $user->create(['nickname' => 'rancoud']); $row = $user->one($newId); // you will have an array representing data in database with correct types // here : ['id' => 1, 'nickname' => 'rancoud']; $rows = $user->all(); // here it's all rows in table : [ ['id' => 1, 'nickname' => 'rancoud'] ] $user->update(['nickname' => 'rancoud2'], $newId); $user->delete($newId);
Model::all() accept an array with some keys that triggers specific actions
// $database is an instance of Rancoud\Database\Database $user = new User($database); // 50 rows using LIMIT 50 OFFSET 50 $rows = $user->all(['page' => 1]); // 10 rows using LIMIT 10 OFFSET 10 $rows = $user->all(['count' => 10, 'page' => 1]); // count rows in table $count = $user->all(['rows_count' => 1]); // return all rows with no limit $count = $user->all(['no_limit' => 1]); // change order by $count = $user->all(['order' => 'nickname']); // change order by and order $count = $user->all(['order' => 'nickname|desc']); // multiple change order by and order $count = $user->all(['order' => 'nickname|desc,id|asc']);
You can change values output in Model::all() with override functions:
- getSqlAllSelectAndFillSqlParams(params: array)
- getSqlAllJoinAndFillSqlParams(params: array)
- getSqlAllWhereAndFillSqlParams(params: array)
Callbacks
You can add callback before and after create, update and delete.
$model->addBeforeCreate('a', function($sql, $params){ // for modifying sql and params use this return otherwise don't return [$sql, $params]; }); $model->addAfterCreate('a', function($newId, $params){ // for modifying params use this return otherwise don't return $params; }); $model->addBeforeUpdate('a', function($sql, $params){ // for modifying sql and params use this return otherwise don't return [$sql, $params]; }); $model->addAfterUpdate('a', function($params){ // for modifying params use this return otherwise don't return $params; }); $model->addBeforeDelete('a', function($sql, $params){ // for modifying sql and params use this return otherwise don't return [$sql, $params]; }); $model->addAfterDelete('a', function($params){ // for modifying params use this return otherwise don't return $params; });
You can use JsonOutput trait for adding json format for the model.
Field Constructor
Settings
Mandatory
Optionnals
Field Methods
- isPrimaryKey(): bool
- isForeignKey(): bool
- isNotNull(): bool
- getDefault(): mixed
- formatValue(value: mixed): ?mixed
Model Constructor
Settings
Mandatory
Model Methods
General Commands
- all(params: array, [validFields: array = []]): array|bool|int
- one(id: mixed, [...ids: mixed = []]): array
- create(args: array): bool|int
- update(args: array, id: mixed, [...ids: mixed = []]): void
- delete(id: mixed, [...ids: mixed = []]): void
- getLastInsertId(): ?int
Database error
- getDatabaseErrors(): ?array
- getDatabaseLastError(): ?array
Callbacks
Add
- addBeforeCreate(name: string, callback: mixed): void
- addAfterCreate(name: string, callback: mixed): void
- addBeforeUpdate(name: string, callback: mixed): void
- addAfterUpdate(name: string, callback: mixed): void
- addBeforeDelete(name: string, callback: mixed): void
- addAfterDelete(name: string, callback: mixed): void
Remove
- removeBeforeCreate(name: string): void
- removeAfterCreate(name: string): void
- removeBeforeUpdate(name: string): void
- removeAfterUpdate(name: string): void
- removeBeforeDelete(name: string): void
- removeAfterDelete(name: string): void
Static Helper Methods
- getCountPerPage(args: array): int
- getLimitOffsetCount(args: array): array
- getOrderByOrderField(args: array, [validFields: array = []]): array
- getPageNumberForHuman(args: array): int
- getPageNumberForSql(args: array): int
- hasInvalidPrimaryKey(value: int): bool
- hasLimit(args: array): bool
- implodeOrder(orders: array): string
- isRowsCount(args: array): bool
- isValidFieldForOrderBy(field: string, [validFields: array = []]): bool
How to Dev
docker compose build && docker compose run lib composer ci
for launching tests