Files
kiri-databases/Base/Model.php
T

825 lines
15 KiB
PHP
Raw Normal View History

2022-01-09 03:49:51 +08:00
<?php
/**
* Created by PhpStorm.
* User: whwyy
* Date: 2018/3/30 0030
* Time: 14:39
*/
declare(strict_types=1);
namespace Database\Base;
defined('SAVE_FAIL') or define('SAVE_FAIL', 3227);
defined('FIND_OR_CREATE_MESSAGE') or define('FIND_OR_CREATE_MESSAGE', 'Create a new model, but the data cannot be empty.');
use ArrayAccess;
use Database\ActiveQuery;
2023-04-11 17:05:03 +08:00
use Database\Collection;
2022-01-09 03:49:51 +08:00
use Database\Connection;
use Database\ModelInterface;
use Database\Mysql\Columns;
use Database\Relation;
use Database\SqlBuilder;
use Database\Traits\HasBase;
use Exception;
2022-02-23 16:32:08 +08:00
use Kiri;
2022-01-09 03:49:51 +08:00
use Kiri\Abstracts\Component;
2022-02-23 16:32:08 +08:00
use Kiri\Annotation\Annotation;
2022-02-23 18:02:28 +08:00
use Kiri\Error\StdoutLoggerInterface;
2022-06-22 16:29:42 +08:00
use ReturnTypeWillChange;
2022-01-09 03:49:51 +08:00
use Kiri\ToArray;
use ReflectionException;
use validator\Validator;
/**
* Class BOrm
*
* @package Kiri\Abstracts
*
* @property bool $isNowExample
* @property array $attributes
* @property array $oldAttributes
*/
abstract class Model extends Component implements ModelInterface, ArrayAccess, ToArray
{
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/** @var array */
protected array $_attributes = [];
2023-04-05 10:15:50 +08:00
2023-04-10 17:13:24 +08:00
2022-01-09 03:49:51 +08:00
/** @var array */
protected array $_oldAttributes = [];
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/** @var null|string */
protected ?string $primary = NULL;
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @var bool
*/
protected bool $isNewExample = TRUE;
2023-04-05 10:15:50 +08:00
2023-04-10 11:36:33 +08:00
/**
2023-04-10 17:13:24 +08:00
* @var bool
2022-01-09 03:49:51 +08:00
*/
2023-04-10 17:13:24 +08:00
protected bool $skipValidate = false;
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @var string
*/
protected string $table = '';
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @var string
*/
protected string $connection = 'db';
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @var array
*/
2023-04-01 17:11:47 +08:00
protected array $_with = [];
2023-04-05 10:15:50 +08:00
2023-04-10 17:13:24 +08:00
/**
* @param array $config
* @throws Exception
*/
public function __construct(array $config = [])
{
parent::__construct($config);
$this->init();
}
2023-04-05 11:06:45 +08:00
/**
2023-04-05 11:08:34 +08:00
* @return array
2023-04-05 11:06:45 +08:00
*/
2023-04-05 11:08:34 +08:00
public function rules(): array
2023-04-05 11:06:45 +08:00
{
2023-04-05 11:08:34 +08:00
return [];
2023-04-05 11:06:45 +08:00
}
2022-01-09 03:49:51 +08:00
/**
2023-04-01 01:27:57 +08:00
* @param array $data
2022-01-09 03:49:51 +08:00
* @return Model
*/
2023-04-01 01:27:57 +08:00
public function setWith(array $data): static
2022-01-09 03:49:51 +08:00
{
$this->_with = $data;
return $this;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
2023-04-01 01:27:57 +08:00
* @return array
2022-01-09 03:49:51 +08:00
*/
2023-04-01 01:27:57 +08:00
public function getWith(): array
2022-01-09 03:49:51 +08:00
{
return $this->_with;
}
2023-04-05 10:15:50 +08:00
2023-04-01 01:27:57 +08:00
/**
* @return bool
*/
public function hasWith(): bool
{
return count($this->_with) > 0;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* object init
*/
public function clean()
{
$this->_attributes = [];
$this->_oldAttributes = [];
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @throws Exception
*/
public function init()
{
2022-02-23 16:32:08 +08:00
$an = Kiri::getDi()->get(Annotation::class);
2022-01-09 03:49:51 +08:00
$an->injectProperty($this);
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return bool
*/
public function getIsNowExample(): bool
{
return $this->isNewExample === TRUE;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param bool $bool
* @return $this
*/
public function setIsNowExample(bool $bool = FALSE): static
{
$this->isNewExample = $bool;
return $this;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return string
* @throws Exception
* get last exception or other error
*/
public function getLastError(): string
{
2022-02-23 18:02:28 +08:00
$logger = Kiri::getDi()->get(StdoutLoggerInterface::class);
2022-02-23 16:32:08 +08:00
return $logger->getLastError('mysql');
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return bool
* @throws Exception
*/
public function hasPrimary(): bool
{
2023-04-10 17:13:24 +08:00
return $this->primary !== NULL && $this->primary !== '';
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return null|string
* @throws Exception
*/
public function getPrimary(): ?string
{
if (!$this->hasPrimary()) {
return NULL;
}
return $this->primary;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return bool
* @throws Exception
*/
public function hasPrimaryValue(): bool
{
if ($this->hasPrimary()) {
2023-04-10 17:13:24 +08:00
return $this->getPrimaryValue() === null;
2022-01-09 03:49:51 +08:00
}
return false;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return int|null
* @throws Exception
*/
public function getPrimaryValue(): ?int
{
2022-06-22 16:29:42 +08:00
if ($this->hasPrimary()) {
2023-04-10 17:13:24 +08:00
return $this->getAttribute($this->getPrimary());
2022-01-09 03:49:51 +08:00
}
2022-06-22 16:29:42 +08:00
return null;
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
2023-04-11 17:05:03 +08:00
* @param int|string|array $param
2022-01-09 03:49:51 +08:00
* @param null $db
* @return Model|null
* @throws Exception
*/
2023-04-11 17:05:03 +08:00
public static function findOne(int|string|array $param, $db = NULL): ?static
2022-01-09 03:49:51 +08:00
{
2023-04-11 17:05:03 +08:00
$model = new ActiveQuery(static::makeNewInstance());
$model->from($model->getTable())->alias('t1');
if (is_numeric($param)) {
$model->where([$model->modelClass->getPrimary() => $param]);
} else {
$model->where($param);
}
return $model->first();
}
/**
* @param int $param
* @param null $db
* @return Model|null
* @throws Exception
*/
public static function primary(int $param, $db = NULL): ?static
{
$model = new ActiveQuery(static::makeNewInstance());
$model->from($model->getTable())->alias('t1');
$model->where([$model->modelClass->getPrimary() => $param]);
return $model->first();
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return static
*/
private static function makeNewInstance(): static
{
2022-02-25 15:57:40 +08:00
return new static();
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
2023-04-11 17:05:03 +08:00
* @param int|string|array $condition
2022-01-09 03:49:51 +08:00
* @return static|null
* @throws Exception
*/
2023-04-11 17:05:03 +08:00
public static function first(int|string|array $condition): ?static
{
return static::findOne($condition);
}
/**
* @param string|array $condition
* @return Collection
* @throws Exception
*/
public static function all(string|array $condition): Collection
2022-01-09 03:49:51 +08:00
{
2023-04-11 17:05:03 +08:00
$model = new ActiveQuery(static::makeNewInstance());
$model->from($model->getTable())->alias('t1');
$model->where($condition);
return $model->get();
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return ActiveQuery
2023-04-10 17:13:24 +08:00
* @throws Exception
2022-01-09 03:49:51 +08:00
*/
public static function query(): ActiveQuery
{
2023-04-11 17:05:03 +08:00
$model = new ActiveQuery(static::makeNewInstance());
$model->from($model->getTable())->alias('t1');
return $model;
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return Connection
2022-06-22 16:29:42 +08:00
* @throws Exception
2022-01-09 03:49:51 +08:00
*/
public function getConnection(): Connection
{
2022-06-22 16:29:42 +08:00
return Kiri::service()->get($this->connection);
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param null $condition
* @param array $attributes
*
* @return bool
* @throws Exception
*/
2023-04-10 17:13:24 +08:00
protected static function deleteByCondition($condition = NULL, array $attributes = []): bool
2022-01-09 03:49:51 +08:00
{
2022-12-12 15:04:11 +08:00
$model = static::query();
if (!empty($condition)) {
$model->where($condition)->bindParams($attributes);
2022-01-09 03:49:51 +08:00
}
return (bool)$model->delete();
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return array
* @throws Exception
*/
public function getAttributes(): array
{
return $this->toArray();
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return array
*/
public function getOldAttributes(): array
{
return $this->_oldAttributes;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param $name
* @param $value
* @return mixed
* @throws ReflectionException
*/
public function setAttribute($name, $value): mixed
{
2023-04-10 17:13:24 +08:00
$method = 'set' . ucfirst($name) . 'Attribute';
if (method_exists($this, $method)) {
2023-03-30 20:39:00 +08:00
$value = $this->{$method}($value);
2022-06-22 16:29:42 +08:00
}
return $this->_attributes[$name] = $value;
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param $name
* @param $value
* @return mixed
* @throws ReflectionException
*/
public function setOldAttribute($name, $value): mixed
{
2023-04-10 17:13:24 +08:00
$method = 'set' . ucfirst($name) . 'Attribute';
if (method_exists($this, $method)) {
$value = $this->{$method}($value);
2022-06-22 16:29:42 +08:00
}
return $this->_oldAttributes[$name] = $value;
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param array $param
* @return $this
* @throws Exception
*/
public function setAttributes(array $param): static
{
2023-04-10 17:13:24 +08:00
if (count($param) < 1) {
2022-01-09 03:49:51 +08:00
return $this;
}
foreach ($param as $key => $attribute) {
$this->setAttribute($key, $attribute);
}
return $this;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
2023-04-10 17:13:24 +08:00
* @param array $param
2022-01-09 03:49:51 +08:00
* @return $this
* @throws ReflectionException
*/
2023-04-10 17:13:24 +08:00
public function setOldAttributes(array $param): static
2022-01-09 03:49:51 +08:00
{
2023-04-10 17:13:24 +08:00
if (count($param) < 1) {
2022-01-09 03:49:51 +08:00
return $this;
}
foreach ($param as $key => $attribute) {
$this->setOldAttribute($key, $attribute);
}
return $this;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return $this|bool
* @throws Exception
*/
2023-04-10 17:13:24 +08:00
private function insert(): bool|static
2022-01-09 03:49:51 +08:00
{
2023-04-10 17:13:24 +08:00
[$sql, $param] = SqlBuilder::builder(static::query())->insert($this->_attributes);
2022-01-09 03:49:51 +08:00
$dbConnection = $this->getConnection()->createCommand($sql, $param);
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
$lastId = $dbConnection->save();
2023-04-10 17:13:24 +08:00
if ($lastId === false) {
return false;
}
if ($this->hasPrimary()) {
$this->_attributes[$this->getPrimary()] = $lastId;
2022-03-01 17:37:45 +08:00
}
2023-04-10 17:13:24 +08:00
return $this;
}
2023-04-05 10:15:50 +08:00
2023-04-10 17:13:24 +08:00
/**
* @param array $old
* @param array|string $condition
* @param array $change
* @return $this|bool
* @throws Exception
*/
protected function updateInternal(array $old, array|string $condition, array $change): bool|static
{
$query = static::query()->where($condition);
$generate = SqlBuilder::builder($query)->update($change);
if ($generate === false) {
return false;
}
2023-04-05 10:15:50 +08:00
2023-04-10 17:13:24 +08:00
$command = $this->getConnection()->createCommand($generate, $query->attributes);
if ($command->save()) {
return $this->refresh()->afterSave($old, $change);
} else {
return FALSE;
}
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
2023-04-10 17:13:24 +08:00
* @param array $data
* @return bool|$this
2022-01-09 03:49:51 +08:00
* @throws Exception
*/
2023-04-10 17:13:24 +08:00
public function save(array $data = []): static|bool
2022-01-09 03:49:51 +08:00
{
2023-04-10 17:13:24 +08:00
if (count($data) > 0) {
$this->_attributes = array_merge($this->_attributes, $data);
2022-01-09 03:49:51 +08:00
}
2023-04-10 17:13:24 +08:00
if (!$this->isNewExample) {
if (!$this->validator($this->rules()) || !$this->beforeSave($this)) {
return FALSE;
}
2023-04-05 10:15:50 +08:00
2023-04-10 17:13:24 +08:00
[$changes, $condition] = $this->diff();
2023-04-05 10:15:50 +08:00
2023-04-10 17:13:24 +08:00
return $this->updateInternal($condition, $condition, $changes);
} else {
return $this->create();
2022-01-09 03:49:51 +08:00
}
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
2023-04-10 17:13:24 +08:00
* @return array<array, array>
2022-01-09 03:49:51 +08:00
*/
2023-04-10 17:13:24 +08:00
private function diff(): array
2022-01-09 03:49:51 +08:00
{
2023-04-10 17:13:24 +08:00
$changes = array_diff_assoc($this->_oldAttributes, $this->_attributes);
2023-04-07 21:57:47 +08:00
2023-04-10 17:13:24 +08:00
$condition = array_intersect_key($this->_oldAttributes, $this->_attributes);
2023-04-07 21:57:47 +08:00
2023-04-10 17:13:24 +08:00
return [$changes, $condition];
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2023-04-10 17:13:24 +08:00
2022-01-09 03:49:51 +08:00
/**
2023-04-10 17:13:24 +08:00
* @return $this|bool
2022-01-09 03:49:51 +08:00
* @throws Exception
*/
2023-04-10 17:13:24 +08:00
protected function create(): bool|static
2022-01-09 03:49:51 +08:00
{
if (!$this->validator($this->rules()) || !$this->beforeSave($this)) {
return FALSE;
}
2023-04-10 17:13:24 +08:00
return $this->insert();
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param $value
* @return $this
*/
public function populates($value): static
{
$this->_attributes = $value;
$this->_oldAttributes = $value;
2023-04-10 17:13:24 +08:00
$this->setIsNowExample();
2022-01-09 03:49:51 +08:00
return $this;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
2023-04-10 17:13:24 +08:00
* @param array $rule
2022-01-09 03:49:51 +08:00
* @return bool
* @throws Exception
*/
2023-04-10 17:13:24 +08:00
public function validator(array $rule): bool
2022-01-09 03:49:51 +08:00
{
2023-04-10 17:13:24 +08:00
if (count($rule) < 1 || $this->skipValidate) {
return TRUE;
}
2022-01-09 03:49:51 +08:00
$validate = $this->resolve($rule);
if (!$validate->validation()) {
2023-04-16 02:46:54 +08:00
return \Kiri::getLogger()->addError($validate->getError(), 'mysql');
2022-01-09 03:49:51 +08:00
} else {
return TRUE;
}
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param $rule
* @return Validator
* @throws Exception
*/
private function resolve($rule): Validator
{
2023-04-10 17:13:24 +08:00
$validate = Validator::instance($this->_attributes, $this);
2022-01-09 03:49:51 +08:00
foreach ($rule as $val) {
$field = array_shift($val);
2023-04-06 18:21:55 +08:00
2022-01-09 03:49:51 +08:00
$validate->make($field, $val);
}
return $validate;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param string $name
* @return null
* @throws Exception
*/
public function getAttribute(string $name)
{
return $this->_attributes[$name] ?? NULL;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return Relation|null
*/
public function getRelation(): ?Relation
{
return Kiri::getDi()->get(Relation::class);
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param $attribute
* @return bool
* @throws Exception
*/
public function has($attribute): bool
{
2023-04-10 17:13:24 +08:00
return true;
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**ƒ
* @return string
* @throws Exception
*/
public function getTable(): string
{
$connection = static::getConnection();
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
$tablePrefix = $connection->tablePrefix;
if (empty($this->table)) {
throw new Exception('You need add static method `tableName` and return table name.');
}
$table = trim($this->table, '{%}');
if (!empty($tablePrefix) && !str_starts_with($table, $tablePrefix)) {
$table = $tablePrefix . $table;
}
return '`' . $connection->database . '`.' . $table;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
2023-04-10 17:13:24 +08:00
* @param $oldAttributes
2022-01-09 03:49:51 +08:00
* @param $changeAttributes
* @return bool
*/
2023-04-10 17:13:24 +08:00
public function afterSave($oldAttributes, $changeAttributes): bool
2022-01-09 03:49:51 +08:00
{
return TRUE;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
2023-04-10 17:13:24 +08:00
* @param self $model
2022-01-09 03:49:51 +08:00
* @return bool
2023-04-10 17:13:24 +08:00
* @throws Exception
2022-01-09 03:49:51 +08:00
*/
2023-04-10 17:13:24 +08:00
public function beforeSave(self $model): bool
2022-01-09 03:49:51 +08:00
{
return TRUE;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return static
*/
public function refresh(): static
{
$this->_oldAttributes = $this->_attributes;
return $this;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param $name
* @param $value
* @throws Exception
*/
2022-02-23 17:24:33 +08:00
public function __set($name, $value): void
2022-01-09 03:49:51 +08:00
{
2023-04-10 17:13:24 +08:00
if ($this->hasRelateMethod($name, 'set')) {
$this->{'set' . ucfirst($name)}($value);
2022-01-09 03:49:51 +08:00
} else {
2023-04-10 17:13:24 +08:00
$method = 'set' . ucfirst($name) . 'Attribute';
if (method_exists($this, $method)) {
$value = $this->{$method} ($value);
}
$this->_attributes[$name] = $value;
2022-01-09 03:49:51 +08:00
}
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param $name
* @return mixed
* @throws Exception
*/
public function __get($name): mixed
{
2023-04-10 17:13:24 +08:00
$value = $this->_attributes[$name] ?? null;
if (!$this->hasRelateMethod($name)) {
return $this->withPropertyOverride($name, $value);
2023-04-05 10:15:50 +08:00
} else {
2023-04-10 17:13:24 +08:00
return $this->withRelate($name);
2022-01-09 03:49:51 +08:00
}
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param $name
2022-06-22 16:29:42 +08:00
* @param null $value
2022-01-09 03:49:51 +08:00
* @return mixed
* @throws Exception
*/
2022-06-22 16:29:42 +08:00
protected function withPropertyOverride($name, $value = null): mixed
2022-01-09 03:49:51 +08:00
{
2023-04-10 17:13:24 +08:00
$method = 'get' . ucfirst($name) . 'Attribute';
if (method_exists($this, $method)) {
return $this->{$method}($value);
} else {
return $value;
2022-06-22 16:29:42 +08:00
}
}
2023-04-05 10:15:50 +08:00
2022-06-22 16:29:42 +08:00
/**
2023-04-10 17:13:24 +08:00
* @param string $name
* @param string $prefix
2022-06-22 16:29:42 +08:00
* @return bool
*/
2023-04-10 17:13:24 +08:00
protected function hasRelateMethod(string $name, string $prefix = 'get'): bool
2022-06-22 16:29:42 +08:00
{
2023-04-10 17:13:24 +08:00
return method_exists($this, $prefix . ucfirst($name));
2022-06-22 16:29:42 +08:00
}
2023-04-05 10:15:50 +08:00
2022-06-22 16:29:42 +08:00
/**
* @param $name
* @return mixed|null
*/
2023-04-10 17:53:20 +08:00
protected function withRelate($name): mixed
2022-01-09 03:49:51 +08:00
{
2022-06-22 16:29:42 +08:00
$response = $this->{'get' . ucfirst($name)}();
if ($response instanceof HasBase) {
$response = $response->get();
}
return $response;
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param $name
* @return bool
*/
public function __isset($name): bool
{
return isset($this->_attributes[$name]);
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param mixed $offset
* @return bool
* @throws Exception
*/
public function offsetExists(mixed $offset): bool
{
return isset($this->_attributes[$offset]) || isset($this->_oldAttributes[$offset]);
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param mixed $offset
* @return mixed
* @throws Exception
*/
public function offsetGet(mixed $offset): mixed
{
return $this->__get($offset);
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param mixed $offset
* @param mixed $value
* @throws Exception
*/
#[ReturnTypeWillChange] public function offsetSet(mixed $offset, mixed $value)
{
$this->__set($offset, $value);
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param mixed $offset
* @throws Exception
*/
#[ReturnTypeWillChange] public function offsetUnset(mixed $offset)
{
if (!isset($this->_attributes[$offset])
&& !isset($this->_oldAttributes[$offset])) {
return;
}
unset($this->_attributes[$offset]);
unset($this->_oldAttributes[$offset]);
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
2022-06-22 16:29:42 +08:00
* @param string ...$params
2022-01-09 03:49:51 +08:00
* @return array
*/
2022-06-22 16:29:42 +08:00
public function unset(string ...$params): array
2022-01-09 03:49:51 +08:00
{
2022-06-22 16:29:42 +08:00
return array_diff_assoc($params, $this->_attributes);
2022-01-09 03:49:51 +08:00
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @return Columns
* @throws Exception
*/
public function getColumns(): Columns
{
return $this->getConnection()->getSchema()->getColumns()
->table($this->getTable());
}
2023-04-05 10:15:50 +08:00
2023-04-10 17:13:24 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param array $data
* @return static
* @throws
*/
public static function populate(array $data): static
{
2023-04-10 17:13:24 +08:00
$model = new static();
2022-01-09 03:49:51 +08:00
$model->_attributes = $data;
$model->_oldAttributes = $data;
2023-04-10 17:13:24 +08:00
$model->setIsNowExample();
2022-01-09 03:49:51 +08:00
return $model;
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
/**
* @param string $name
* @param array $arguments
* @return mixed
*/
public static function __callStatic(string $name, array $arguments)
{
return (new static())->{$name}(...$arguments);
}
2023-04-05 10:15:50 +08:00
2022-01-09 03:49:51 +08:00
}