提交的内容

This commit is contained in:
2025-05-12 15:45:02 +08:00
parent 629c4750da
commit b48c692775
3043 changed files with 34732 additions and 60810 deletions

26
vendor/topthink/think-orm/src/model/Collection.php vendored Executable file → Normal file
View File

@ -131,6 +131,22 @@ class Collection extends BaseCollection
return $this;
}
/**
* 设置属性映射.
*
* @param array $mapping 属性映射
*
* @return $this
*/
public function mapping(array $mapping)
{
$this->each(function (Model $model) use ($mapping) {
$model->mapping($mapping);
});
return $this;
}
/**
* 设置模型输出场景.
*
@ -171,10 +187,10 @@ class Collection extends BaseCollection
*
* @return $this
*/
public function withAttr(string|array $name, callable $callback = null)
public function withAttr(string|array $name, ?callable $callback = null)
{
$this->each(function (Model $model) use ($name, $callback) {
$model->withAttr($name, $callback);
$model->withFieldAttr($name, $callback);
});
return $this;
@ -207,7 +223,7 @@ class Collection extends BaseCollection
*
* @return array
*/
public function dictionary($items = null, string &$indexKey = null)
public function dictionary($items = null, ?string &$indexKey = null)
{
if ($items instanceof self || $items instanceof Paginator) {
$items = $items->all();
@ -234,7 +250,7 @@ class Collection extends BaseCollection
*
* @return static
*/
public function diff($items, string $indexKey = null)
public function diff($items, ?string $indexKey = null)
{
if ($this->isEmpty()) {
return new static($items);
@ -262,7 +278,7 @@ class Collection extends BaseCollection
*
* @return static
*/
public function intersect($items, string $indexKey = null)
public function intersect($items, ?string $indexKey = null)
{
if ($this->isEmpty()) {
return new static([]);

2
vendor/topthink/think-orm/src/model/Pivot.php vendored Executable file → Normal file
View File

@ -41,7 +41,7 @@ class Pivot extends Model
* @param Model|null $parent 上级模型
* @param string $table 中间数据表名
*/
public function __construct(array $data = [], Model $parent = null, string $table = '')
public function __construct(array $data = [], ?Model $parent = null, string $table = '')
{
$this->parent = $parent;

2
vendor/topthink/think-orm/src/model/Relation.php vendored Executable file → Normal file
View File

@ -163,7 +163,7 @@ abstract class Relation
*
* @return mixed
*/
protected function resultSetBuild(array $resultSet, Model $parent = null)
protected function resultSetBuild(array $resultSet, ?Model $parent = null)
{
return (new $this->model())->toCollection($resultSet)->setParent($parent);
}

180
vendor/topthink/think-orm/src/model/concern/Attribute.php vendored Executable file → Normal file
View File

@ -9,15 +9,19 @@
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare(strict_types=1);
declare (strict_types = 1);
namespace think\model\concern;
use BackedEnum;
use Closure;
use InvalidArgumentException;
use Stringable;
use think\db\Raw;
use think\helper\Str;
use think\Model;
use think\model\contract\EnumTransform;
use think\model\contract\FieldTypeTransform;
use think\model\Relation;
/**
@ -32,6 +36,13 @@ trait Attribute
*/
protected $pk = 'id';
/**
* 数据表主键自增.
*
* @var bool|null|string
*/
protected $autoInc;
/**
* 数据表字段信息 留空则自动获取.
*
@ -102,6 +113,20 @@ trait Attribute
*/
protected $jsonAssoc = false;
/**
* Enum数据取出自动转换为name.
*
* @var bool|string
*/
protected $enumReadName = false;
/**
* 严格检查Enum数据类型.
*
* @var bool
*/
protected $enumStrict = false;
/**
* 是否严格字段大小写.
*
@ -124,11 +149,11 @@ trait Attribute
private $withAttr = [];
/**
* 数据表延迟写入字段
* 自动写入字段.
*
* @var array
*/
protected $lazyFields = [];
protected $insert = [];
/**
* 获取模型对象的主键.
@ -195,7 +220,7 @@ trait Attribute
*
* @return $this
*/
public function readOnly(array $field)
public function readonly(array $field)
{
$this->readonly = $field;
@ -227,14 +252,14 @@ trait Attribute
*
* @return $this
*/
public function data(array|object $data, bool $set = false, array $allow = [])
public function data(array | object $data, bool $set = false, array $allow = [])
{
if ($data instanceof Model) {
$data = $data->getData();
} elseif (is_object($data)) {
$data = get_object_vars($data);
}
// 清空数据
$this->data = [];
@ -298,7 +323,7 @@ trait Attribute
*
* @return mixed
*/
public function getOrigin(string $name = null)
public function getOrigin(?string $name = null)
{
if (is_null($name)) {
return $this->origin;
@ -318,7 +343,7 @@ trait Attribute
*
* @return mixed
*/
public function getData(string $name = null)
public function getData(?string $name = null)
{
if (is_null($name)) {
return $this->data;
@ -349,11 +374,15 @@ trait Attribute
return 1;
}
if ($b instanceof Raw) {
return 0;
}
return is_object($a) || $a != $b ? 1 : 0;
});
// 只读字段不允许更新
foreach ($this->readonly as $key => $field) {
foreach ($this->readonly as $field) {
if (array_key_exists($field, $data)) {
unset($data[$field]);
}
@ -404,6 +433,10 @@ trait Attribute
*/
public function setAttr(string $name, $value, array $data = []): void
{
if ($this->mapping) {
$name = array_search($name, $this->mapping) ?: $name;
}
$name = $this->getRealFieldName($name);
// 检测修改器
@ -416,12 +449,16 @@ trait Attribute
if (is_null($value) && $array !== $this->data) {
return;
}
} elseif (isset($this->type[$name])) {
} elseif (!in_array($name, $this->json) && isset($this->type[$name])) {
// 类型转换
if ($this->enumStrict && is_subclass_of($this->type[$name], BackedEnum::class) && !($value instanceof BackedEnum)) {
throw new InvalidArgumentException('data type error: ' . $name . ' => ' . $this->type[$name]);
}
$value = $this->writeTransform($value, $this->type[$name]);
} elseif ($this->isRelationAttr($name)) {
// 关联属性
$this->relation[$name] = $value;
$this->with[$name] = true;
} elseif ((array_key_exists($name, $this->origin) || empty($this->origin)) && $value instanceof Stringable) {
// 对象类型
$value = $value->__toString();
@ -440,9 +477,9 @@ trait Attribute
*
* @return mixed
*/
protected function writeTransform($value, string|array $type)
protected function writeTransform($value, string | array $type)
{
if (is_null($value)) {
if (null === $value) {
return;
}
@ -456,17 +493,32 @@ trait Attribute
[$type, $param] = explode(':', $type, 2);
}
$typeTransform = static function (string $type, $value, $model) {
if (str_contains($type, '\\') && class_exists($type)) {
if (is_subclass_of($type, FieldTypeTransform::class)) {
$value = $type::set($value, $model);
} elseif ($value instanceof BackedEnum) {
$value = $value->value;
} elseif ($value instanceof Stringable) {
$value = $value->__toString();
}
}
return $value;
};
return match ($type) {
'integer' => (int) $value,
'float' => empty($param) ? (float) $value : (float) number_format($value, (int) $param, '.', ''),
'boolean' => (bool) $value,
'timestamp' => !is_numeric($value) ? strtotime($value) : $value,
'datetime' => $this->formatDateTime('Y-m-d H:i:s.u', $value, true),
'object' => is_object($value) ? json_encode($value, JSON_FORCE_OBJECT) : $value,
'array' => json_encode((array) $value, !empty($param) ? (int) $param : JSON_UNESCAPED_UNICODE),
'json' => json_encode($value, !empty($param) ? (int) $param : JSON_UNESCAPED_UNICODE),
'serialize' => serialize($value),
default => $value instanceof Stringable && str_contains($type, '\\') ? $value->__toString() : $value,
'string' => (string) $value,
'integer' => (int) $value,
'float' => empty($param) ? (float) $value : (float) number_format($value, (int) $param, '.', ''),
'boolean' => (bool) $value,
'timestamp' => !is_numeric($value) ? strtotime($value) : $value,
'datetime' => $this->formatDateTime('Y-m-d H:i:s.u', $value, true),
'object' => is_object($value) ? json_encode($value, JSON_FORCE_OBJECT) : $value,
'array' => json_encode((array) $value, !empty($param) ? (int) $param : JSON_UNESCAPED_UNICODE),
'json' => json_encode($value, !empty($param) ? (int) $param : JSON_UNESCAPED_UNICODE),
'serialize' => serialize($value),
default => $typeTransform($type, $value, $this),
};
}
@ -482,11 +534,14 @@ trait Attribute
public function getAttr(string $name)
{
try {
$relation = false;
$value = $this->getData($name);
$relation = false;
if ($this->mapping) {
$name = array_search($name, $this->mapping) ?: $name;
}
$value = $this->getData($name);
} catch (InvalidArgumentException $e) {
$relation = $this->isRelationAttr($name);
$value = null;
$relation = $this->isRelationAttr($name);
$value = null;
}
return $this->getValue($name, $value, $relation);
@ -503,7 +558,7 @@ trait Attribute
*
* @return mixed
*/
protected function getValue(string $name, $value, bool|string $relation = false)
protected function getValue(string $name, $value, bool | string $relation = false)
{
// 检测属性获取器
$fieldName = $this->getRealFieldName($name);
@ -523,7 +578,7 @@ trait Attribute
} else {
$closure = $this->withAttr[$fieldName];
if ($closure instanceof \Closure) {
$value = $closure($value, $this->data);
$value = $closure($value, $this->data, $this);
}
}
} elseif (method_exists($this, $method)) {
@ -532,7 +587,7 @@ trait Attribute
}
$value = $this->$method($value, $this->data);
} elseif (isset($this->type[$fieldName])) {
} elseif (!in_array($fieldName, $this->json) && isset($this->type[$fieldName])) {
// 类型转换
$value = $this->readTransform($value, $this->type[$fieldName]);
} elseif ($this->autoWriteTimestamp && in_array($fieldName, [$this->createTime, $this->updateTime])) {
@ -564,9 +619,9 @@ trait Attribute
foreach ($this->withAttr[$name] as $key => $closure) {
if ($this->jsonAssoc) {
$value[$key] = $closure($value[$key], $value);
$value[$key] = $closure($value[$key] ?? '', $value);
} else {
$value->$key = $closure($value->$key, $value);
$value->$key = $closure($value->$key ?? '', $value);
}
}
@ -595,7 +650,7 @@ trait Attribute
*
* @return mixed
*/
protected function readTransform($value, string|array $type)
protected function readTransform($value, string | array $type)
{
if (is_null($value)) {
return;
@ -616,17 +671,39 @@ trait Attribute
return $value;
};
$typeTransform = static function (string $type, $value, $model) {
if (str_contains($type, '\\') && class_exists($type)) {
if (is_subclass_of($type, FieldTypeTransform::class)) {
$value = $type::get($value, $model);
} elseif (is_subclass_of($type, BackedEnum::class)) {
$value = $type::from($value);
if (is_subclass_of($type, EnumTransform::class)) {
$value = $value->value();
} elseif ($model->enumReadName) {
$method = $model->enumReadName;
$value = is_string($method) ? $value->$method() : $value->name;
}
} else {
// 对象类型
$value = new $type($value);
}
}
return $value;
};
return match ($type) {
'integer' => (int) $value,
'float' => empty($param) ? (float) $value : (float) number_format($value, (int) $param, '.', ''),
'boolean' => (bool) $value,
'timestamp' => !is_null($value) ? $this->formatDateTime(!empty($param) ? $param : $this->dateFormat, $value, true) : null,
'datetime' => !is_null($value) ? $this->formatDateTime(!empty($param) ? $param : $this->dateFormat, $value) : null,
'json' => json_decode($value, true),
'array' => empty($value) ? [] : json_decode($value, true),
'object' => empty($value) ? new \stdClass() : json_decode($value),
'serialize' => $call($value),
default => str_contains($type, '\\') ? new $type($value) : $value,
'string' => (string) $value,
'integer' => (int) $value,
'float' => empty($param) ? (float) $value : (float) number_format($value, (int) $param, '.', ''),
'boolean' => (bool) $value,
'timestamp' => !is_null($value) ? $this->formatDateTime(!empty($param) ? $param : $this->dateFormat, $value, true) : null,
'datetime' => !is_null($value) ? $this->formatDateTime(!empty($param) ? $param : $this->dateFormat, $value) : null,
'json' => json_decode($value, true),
'array' => empty($value) ? [] : json_decode($value, true),
'object' => empty($value) ? new \stdClass() : json_decode($value),
'serialize' => $call($value),
default => $typeTransform($type, $value, $this),
};
}
@ -638,14 +715,15 @@ trait Attribute
*
* @return $this
*/
public function withAttr(string|array $name, Closure $callback = null)
public function withFieldAttr(string | array $name, ?Closure $callback = null)
{
if (is_array($name)) {
foreach ($name as $key => $val) {
$this->withAttr($key, $val);
$this->withFieldAttr($key, $val);
}
} else {
$name = $this->getRealFieldName($name);
$this->append([$name], true);
if (str_contains($name, '.')) {
[$name, $key] = explode('.', $name);
@ -658,4 +736,18 @@ trait Attribute
return $this;
}
/**
* 设置枚举类型自动读取数据方式
* true 表示使用name值返回
* 字符串 表示使用枚举类的方法返回
*
* @return $this
*/
public function withEnumRead(bool | string $method = true)
{
$this->enumReadName = $method;
return $this;
}
}

View File

@ -0,0 +1,64 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace think\model\concern;
/**
* 自动写入主键.
*/
trait AutoWriteId
{
/**
* 是否需要自动写入主键.
*
* @var false|callable
*/
protected $autoWriteId = false;
/**
* 是否需要自动写入.
*
* @return bool
*/
public function isAutoWriteId(): bool
{
return $this->autoWriteId ? true : false;
}
/**
* 设置自动写入方法.
*
* @param callable $callable
*
* @return $this
*/
public function setAutoWriteId(callable $callable)
{
$this->autoWriteId = $callable;
return $this;
}
/**
* 自动写入主键.
*
* @return mixed
*/
protected function autoWriteId()
{
$build = $this->autoWriteId;
return is_callable($build) ? $build() : '';
}
}

65
vendor/topthink/think-orm/src/model/concern/Conversion.php vendored Executable file → Normal file
View File

@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare(strict_types=1);
declare (strict_types = 1);
namespace think\model\concern;
@ -132,7 +132,7 @@ trait Conversion
throw new Exception('bind attr has exists:' . $key);
}
$this->data[$key] = $model->$attr;
$this->data[$key] = $model->getAttr($attr);
}
}
@ -147,13 +147,9 @@ trait Conversion
*
* @return $this
*/
public function append(array $append = [], bool $merge = false)
public function append(array $append, bool $merge = false)
{
if ($merge) {
$this->append = array_merge($this->append, $append);
} else {
$this->append = $append;
}
$this->append = $merge ? array_merge($this->append, $append) : $append;
return $this;
}
@ -166,13 +162,9 @@ trait Conversion
*
* @return $this
*/
public function hidden(array $hidden = [], bool $merge = false)
public function hidden(array $hidden, bool $merge = false)
{
if ($merge) {
$this->hidden = array_merge($this->hidden, $hidden);
} else {
$this->hidden = $hidden;
}
$this->hidden = $merge ? array_merge($this->hidden, $hidden) : $hidden;
return $this;
}
@ -185,13 +177,9 @@ trait Conversion
*
* @return $this
*/
public function visible(array $visible = [], bool $merge = false)
public function visible(array $visible, bool $merge = false)
{
if ($merge) {
$this->visible = array_merge($this->visible, $visible);
} else {
$this->visible = $visible;
}
$this->visible = $merge ? array_merge($this->visible, $visible) : $visible;
return $this;
}
@ -218,16 +206,17 @@ trait Conversion
public function toArray(): array
{
$item = $visible = $hidden = [];
$hasVisible = false;
foreach ($this->visible as $key => $val) {
if (is_string($val)) {
if (str_contains($val, '.')) {
[$relation, $name] = explode('.', $val);
[$relation, $name] = explode('.', $val);
$visible[$relation][] = $name;
} else {
$visible[$val] = true;
$hasVisible = true;
$hasVisible = true;
}
} else {
$visible[$key] = $val;
@ -237,7 +226,7 @@ trait Conversion
foreach ($this->hidden as $key => $val) {
if (is_string($val)) {
if (str_contains($val, '.')) {
[$relation, $name] = explode('.', $val);
[$relation, $name] = explode('.', $val);
$hidden[$relation][] = $name;
} else {
$hidden[$val] = true;
@ -264,13 +253,27 @@ trait Conversion
$val->hidden($hidden[$key], true);
}
// 关联模型对象
if (!isset($hidden[$key]) || true !== $hidden[$key]) {
if (!array_key_exists($key, $this->relation) || (array_key_exists($key, $this->with) && (!isset($hidden[$key]) || true !== $hidden[$key]))) {
$item[$key] = $val->toArray();
}
} elseif (isset($visible[$key])) {
$item[$key] = $this->getAttr($key);
} elseif (!isset($hidden[$key]) && !$hasVisible) {
$item[$key] = $this->getAttr($key);
} elseif (in_array($key, $this->json)) {
if (isset($hidden[$key]) && is_array($hidden[$key])) {
// 隐藏JSON属性
foreach ($hidden[$key] as $name) {
if (is_array($val)) {
unset($val[$name]);
} else {
unset($val->$name);
}
}
$item[$key] = $val;
} elseif (!isset($hidden[$key])) {
$item[$key] = $val;
}
}
if (isset($this->mapping[$key])) {
@ -294,7 +297,7 @@ trait Conversion
return $item;
}
protected function appendAttrToArray(array &$item, $key, array|string $name, array $visible, array $hidden): void
protected function appendAttrToArray(array &$item, $key, array | string $name, array $visible, array $hidden): void
{
if (is_array($name)) {
// 批量追加关联对象属性
@ -303,11 +306,11 @@ trait Conversion
} elseif (str_contains($name, '.')) {
// 追加单个关联对象属性
[$key, $attr] = explode('.', $name);
$relation = $this->getRelationWith($key, $hidden, $visible);
$item[$key] = $relation ? $relation->append([$attr])->toArray() : [];
$relation = $this->getRelationWith($key, $hidden, $visible);
$item[$key] = $relation ? $relation->append([$attr])->toArray() : [];
} else {
$value = $this->getAttr($name);
$item[$name] = $value;
$value = $this->getAttr($name);
$item[$name] = $value;
$this->getBindAttrValue($name, $value, $item);
}
@ -315,7 +318,7 @@ trait Conversion
protected function getRelationWith(string $key, array $hidden, array $visible)
{
$relation = $this->getRelation($key, true);
$relation = $this->getRelation($key, true);
if ($relation) {
if (isset($visible[$key])) {
$relation->visible($visible[$key]);
@ -385,7 +388,7 @@ trait Conversion
*
* @return Collection
*/
public function toCollection(iterable $collection = [], string $resultSetType = null): Collection
public function toCollection(iterable $collection = [], ?string $resultSetType = null): Collection
{
$resultSetType = $resultSetType ?: $this->resultSetType;

21
vendor/topthink/think-orm/src/model/concern/ModelEvent.php vendored Executable file → Normal file
View File

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace think\model\concern;
use ReflectionClass;
use think\db\exception\ModelEventException;
use think\helper\Str;
@ -35,6 +36,13 @@ trait ModelEvent
*/
protected $withEvent = true;
/**
* 事件观察者.
*
* @var string
*/
protected $eventObserver;
/**
* 设置Event对象
*
@ -77,10 +85,17 @@ trait ModelEvent
$call = 'on' . Str::studly($event);
try {
if (method_exists(static::class, $call)) {
$result = call_user_func([static::class, $call], $this);
if ($this->eventObserver) {
$reflect = new ReflectionClass($this->eventObserver);
$observer = $reflect->newinstance();
} else {
$observer = static::class;
}
if (method_exists($observer, $call)) {
$result = $this->invoke([$observer, $call], [$this]);
} elseif (is_object(self::$event) && method_exists(self::$event, 'trigger')) {
$result = self::$event->trigger('model.' . static::class . '.' . $event, $this);
$result = self::$event->trigger(static::class . '.' . $event, $this);
$result = empty($result) ? true : end($result);
} else {
$result = true;

0
vendor/topthink/think-orm/src/model/concern/OptimLock.php vendored Executable file → Normal file
View File

56
vendor/topthink/think-orm/src/model/concern/RelationShip.php vendored Executable file → Normal file
View File

@ -17,6 +17,7 @@ use Closure;
use think\Collection;
use think\db\BaseQuery as Query;
use think\db\exception\DbException as Exception;
use think\db\exception\InvalidArgumentException;
use think\helper\Str;
use think\Model;
use think\model\Relation;
@ -51,6 +52,13 @@ trait RelationShip
*/
private $relation = [];
/**
* 预载入关联模型
*
* @var array
*/
protected $with = [];
/**
* 关联写入定义信息.
*
@ -97,7 +105,7 @@ trait RelationShip
*
* @return mixed
*/
public function getRelation(string $name = null, bool $auto = false)
public function getRelation(?string $name = null, bool $auto = false)
{
if (is_null($name)) {
return $this->relation;
@ -130,7 +138,10 @@ trait RelationShip
$value = $this->$method($value, array_merge($this->data, $data));
}
$this->relation[$this->getRealFieldName($name)] = $value;
$name = $this->getRealFieldName($name);
$this->relation[$name] = $value;
$this->with[$name] = true;
return $this;
}
@ -170,7 +181,7 @@ trait RelationShip
$relationResult->withAttr($withRelationAttr[$relationName]);
}
$this->relation[$relation] = $relationResult->getRelation((array) $subRelation, $closure);
$this->setRelation($relation, $relationResult->getRelation((array) $subRelation, $closure));
}
}
@ -202,7 +213,7 @@ trait RelationShip
*
* @return Query
*/
public static function has(string $relation, string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null): Query
public static function has(string $relation, string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', ?Query $query = null): Query
{
return (new static())
->$relation()
@ -220,7 +231,7 @@ trait RelationShip
*
* @return Query
*/
public static function hasWhere(string $relation, $where = [], string $fields = '*', string $joinType = '', Query $query = null): Query
public static function hasWhere(string $relation, $where = [], string $fields = '*', string $joinType = '', ?Query $query = null): Query
{
return (new static())
->$relation()
@ -239,7 +250,7 @@ trait RelationShip
*
* @return bool
*/
public function eagerly(Query $query, string $relation, $field, string $joinType = '', Closure $closure = null, bool $first = false): bool
public function eagerly(Query $query, string $relation, $field, string $joinType = '', ?Closure $closure = null, bool $first = false): bool
{
$relation = Str::camel($relation);
$class = $this->$relation();
@ -257,7 +268,7 @@ trait RelationShip
* 预载入关联查询 返回数据集.
*
* @param array $resultSet 数据集
* @param string $relation 关联名
* @param array $relations 关联名
* @param array $withRelationAttr 关联获取器
* @param bool $join 是否为JOIN方式
* @param mixed $cache 关联缓存
@ -299,6 +310,8 @@ trait RelationShip
}
$relationResult->eagerlyResultSet($resultSet, $relationName, $subRelation, $closure, $relationCache, $join);
$this->with[$relationName] = true;
}
}
@ -365,14 +378,25 @@ trait RelationShip
$relation = $this->getRelation($relation, true);
foreach ($attrs as $key => $attr) {
$key = is_numeric($key) ? $attr : $key;
$value = $this->getOrigin($key);
if (is_numeric($key)) {
if (!is_string($attr)) {
throw new InvalidArgumentException('bind attr must be string:' . $key);
}
if (!is_null($value)) {
$key = $attr;
}
if (null !== $this->getOrigin($key)) {
throw new Exception('bind attr has exists:' . $key);
}
$this->set($key, $relation ? $relation->$attr : null);
if ($attr instanceof Closure) {
$value = $attr($relation, $key, $this);
} else {
$value = $relation?->getAttr($attr);
}
$this->set($key, $value);
}
return $this;
@ -562,7 +586,7 @@ trait RelationShip
*
* @return MorphOne
*/
public function morphOne(string $model, string|array $morph = null, string $type = ''): MorphOne
public function morphOne(string $model, string|array|null $morph = null, string $type = ''): MorphOne
{
// 记录当前关联信息
$model = $this->parseModel($model);
@ -588,7 +612,7 @@ trait RelationShip
*
* @return MorphMany
*/
public function morphMany(string $model, string|array $morph = null, string $type = ''): MorphMany
public function morphMany(string $model, string|array|null $morph = null, string $type = ''): MorphMany
{
// 记录当前关联信息
$model = $this->parseModel($model);
@ -613,7 +637,7 @@ trait RelationShip
*
* @return MorphTo
*/
public function morphTo(string|array $morph = null, array $alias = []): MorphTo
public function morphTo(string|array|null $morph = null, array $alias = []): MorphTo
{
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$relation = Str::snake($trace[1]['function']);
@ -637,7 +661,7 @@ trait RelationShip
*
* @return MorphToMany
*/
public function morphToMany(string $model, string $middle, string|array $morph = null, string $localKey = null): MorphToMany
public function morphToMany(string $model, string $middle, string|array|null $morph = null, ?string $localKey = null): MorphToMany
{
if (is_null($morph)) {
$morph = $middle;
@ -662,7 +686,7 @@ trait RelationShip
*
* @return MorphToMany
*/
public function morphByMany(string $model, string $middle, string|array $morph = null, string $foreignKey = null): MorphToMany
public function morphByMany(string $model, string $middle, string|array|null $morph = null, ?string $foreignKey = null): MorphToMany
{
if (is_null($morph)) {
$morph = $middle;

8
vendor/topthink/think-orm/src/model/concern/SoftDelete.php vendored Executable file → Normal file
View File

@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare(strict_types=1);
declare (strict_types = 1);
namespace think\model\concern;
@ -85,7 +85,7 @@ trait SoftDelete
return false;
}
$name = $this->getDeleteTimeField();
$name = $this->getDeleteTimeField();
$force = $this->isForce();
if ($name && !$force) {
@ -145,7 +145,7 @@ trait SoftDelete
$query->where($data);
$data = [];
} elseif ($data instanceof \Closure) {
call_user_func_array($data, [&$query]);
call_user_func_array($data, [ &$query]);
$data = [];
}
@ -199,7 +199,7 @@ trait SoftDelete
*
* @return string|false
*/
public function getDeleteTimeField(bool $read = false): bool|string
public function getDeleteTimeField(bool $read = false): bool | string
{
$field = property_exists($this, 'deleteTime') && isset($this->deleteTime) ? $this->deleteTime : 'delete_time';

0
vendor/topthink/think-orm/src/model/concern/TimeStamp.php vendored Executable file → Normal file
View File

2
vendor/topthink/think-orm/src/model/concern/Virtual.php vendored Executable file → Normal file
View File

@ -53,7 +53,7 @@ trait Virtual
*
* @return bool
*/
public function save(array|object $data = [], string $sequence = null): bool
public function save(array|object $data = [], ?string $sequence = null): bool
{
if ($data instanceof Model) {
$data = $data->getData();

View File

@ -0,0 +1,10 @@
<?php
declare (strict_types = 1);
namespace think\model\contract;
interface EnumTransform
{
public function value();
}

View File

@ -0,0 +1,17 @@
<?php
declare (strict_types = 1);
namespace think\model\contract;
use think\Model;
interface FieldTypeTransform
{
public static function get(mixed $value, Model $model): ?static;
/**
* @return static|mixed
*/
public static function set($value, Model $model) : mixed;
}

67
vendor/topthink/think-orm/src/model/relation/BelongsTo.php vendored Executable file → Normal file
View File

@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare(strict_types=1);
declare (strict_types = 1);
namespace think\model\relation;
@ -31,14 +31,14 @@ class BelongsTo extends OneToOne
* @param string $localKey 关联主键
* @param string $relation 关联名
*/
public function __construct(Model $parent, string $model, string $foreignKey, string $localKey, string $relation = null)
public function __construct(Model $parent, string $model, string $foreignKey, string $localKey, ?string $relation = null)
{
$this->parent = $parent;
$this->model = $model;
$this->foreignKey = $foreignKey;
$this->localKey = $localKey;
$this->query = (new $model())->db();
$this->relation = $relation;
$this->parent = $parent;
$this->model = $model;
$this->foreignKey = $foreignKey;
$this->localKey = $localKey;
$this->query = (new $model())->db();
$this->relation = $relation;
if (get_class($parent) == $model) {
$this->selfRelation = true;
@ -53,14 +53,14 @@ class BelongsTo extends OneToOne
*
* @return Model
*/
public function getRelation(array $subRelation = [], Closure $closure = null)
public function getRelation(array $subRelation = [], ?Closure $closure = null)
{
if ($closure) {
$closure($this->query);
}
$foreignKey = $this->foreignKey;
$relationModel = $this->query
$foreignKey = $this->foreignKey;
$relationModel = $this->query
->removeWhereField($this->localKey)
->where($this->localKey, $this->parent->$foreignKey)
->relation($subRelation)
@ -74,7 +74,7 @@ class BelongsTo extends OneToOne
$relationModel->setParent(clone $this->parent);
} else {
$default = $this->query->getOptions('default_model');
$default = $this->query->getOptions('default_model');
$relationModel = $this->getDefaultModel($default);
}
@ -91,14 +91,14 @@ class BelongsTo extends OneToOne
*
* @return string
*/
public function getRelationCountQuery(Closure $closure = null, string $aggregate = 'count', string $field = '*', &$name = ''): string
public function getRelationCountQuery(?Closure $closure = null, string $aggregate = 'count', string $field = '*', &$name = ''): string
{
if ($closure) {
$closure($this->query, $name);
}
return $this->query
->whereExp($this->localKey, '=' . $this->parent->getTable() . '.' . $this->foreignKey)
->whereExp($this->localKey, '=' . $this->parent->getTable(true) . '.' . $this->foreignKey)
->fetchSql()
->$aggregate($field);
}
@ -114,7 +114,7 @@ class BelongsTo extends OneToOne
*
* @return int
*/
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null)
public function relationCount(Model $result, ?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null)
{
$foreignKey = $this->foreignKey;
@ -142,7 +142,7 @@ class BelongsTo extends OneToOne
*
* @return Query
*/
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null): Query
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', ?Query $query = null): Query
{
$table = $this->query->getTable();
$model = class_basename($this->parent);
@ -172,11 +172,11 @@ class BelongsTo extends OneToOne
*
* @return Query
*/
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null): Query
public function hasWhere($where = [], $fields = null, string $joinType = '', ?Query $query = null): Query
{
$table = $this->query->getTable();
$model = class_basename($this->parent);
$relation = class_basename($this->model);
$table = $this->query->getTable();
$model = class_basename($this->parent);
$relation = class_basename($this->model);
if (is_array($where)) {
$this->getQueryWhere($where, $relation);
@ -192,12 +192,15 @@ class BelongsTo extends OneToOne
$query = $query ?: $this->parent->db();
return $query->alias($model)
->via($model)
->field($fields)
->join([$table => $relation], $model . '.' . $this->foreignKey . '=' . $relation . '.' . $this->localKey, $joinType ?: $this->joinType)
->when($softDelete, function ($query) use ($softDelete, $relation) {
$query->where($relation . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
})
->where($where);
->where(function ($query) use ($where) {
$query->where($where);
});
}
/**
@ -211,12 +214,12 @@ class BelongsTo extends OneToOne
*
* @return void
*/
protected function eagerlySet(array &$resultSet, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
protected function eagerlySet(array &$resultSet, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
$range = [];
$range = [];
foreach ($resultSet as $result) {
// 获取关联外键列表
if (isset($result->$foreignKey)) {
@ -226,13 +229,19 @@ class BelongsTo extends OneToOne
if (!empty($range)) {
$this->query->removeWhereField($localKey);
$default = $this->query->getOptions('default_model');
$default = $this->query->getOptions('default_model');
$defaultModel = $this->getDefaultModel($default);
$data = $this->eagerlyWhere([
[$localKey, 'in', $range],
], $localKey, $subRelation, $closure, $cache);
// 动态绑定参数
$bindAttr = $this->query->getOptions('bind_attr');
if ($bindAttr) {
$this->bind($bindAttr);
}
// 关联数据封装
foreach ($resultSet as $result) {
// 关联模型
@ -266,7 +275,7 @@ class BelongsTo extends OneToOne
*
* @return void
*/
protected function eagerlyOne(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
protected function eagerlyOne(Model $result, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
@ -279,7 +288,7 @@ class BelongsTo extends OneToOne
// 关联模型
if (!isset($data[$result->$foreignKey])) {
$default = $this->query->getOptions('default_model');
$default = $this->query->getOptions('default_model');
$relationModel = $this->getDefaultModel($default);
} else {
$relationModel = $data[$result->$foreignKey];
@ -290,6 +299,12 @@ class BelongsTo extends OneToOne
// 设置关联属性
$result->setRelation($relation, $relationModel);
// 动态绑定参数
$bindAttr = $this->query->getOptions('bind_attr');
if ($bindAttr) {
$this->bind($bindAttr);
}
if (!empty($this->bindAttr)) {
// 绑定关联属性
$this->bindAttr($result, $relationModel);

68
vendor/topthink/think-orm/src/model/relation/BelongsToMany.php vendored Executable file → Normal file
View File

@ -54,6 +54,13 @@ class BelongsToMany extends Relation
*/
protected $pivotDataName = 'pivot';
/**
* 绑定的关联属性.
*
* @var array
*/
protected $bindAttr = [];
/**
* 架构函数.
*
@ -109,6 +116,20 @@ class BelongsToMany extends Relation
return $this;
}
/**
* 绑定关联表的属性到父模型属性.
*
* @param array $attr 要绑定的属性列表
*
* @return $this
*/
public function bind(array $attr)
{
$this->bindAttr = $attr;
return $this;
}
/**
* 实例化中间表模型.
*
@ -138,7 +159,7 @@ class BelongsToMany extends Relation
*
* @return Collection
*/
public function getRelation(array $subRelation = [], Closure $closure = null): Collection
public function getRelation(array $subRelation = [], ?Closure $closure = null): Collection
{
if ($closure) {
$closure($this->query);
@ -158,13 +179,27 @@ class BelongsToMany extends Relation
*/
protected function matchPivot(Model $result): array
{
$pivot = [];
$pivot = [];
$bindAttr = $this->query->getOptions('bind_attr');
if (empty($bindAttr)) {
$bindAttr = $this->bindAttr;
}
foreach ($result->getData() as $key => $val) {
if (str_contains($key, '__')) {
[$name, $attr] = explode('__', $key, 2);
if ('pivot' == $name) {
$pivot[$attr] = $val;
$pos = array_search($attr, $bindAttr);
if (false !== $pos) {
// 中间表属性绑定
$attr = !is_numeric($pos) ? $pos : $attr;
if (null !== $result->getOrigin($attr)) {
throw new Exception('bind attr has exists:' . $attr);
}
$result->setAttr($attr, $val);
}
unset($result->$key);
}
}
@ -191,7 +226,7 @@ class BelongsToMany extends Relation
*
* @return Model
*/
public function has(string $operator = '>=', $count = 1, $id = '*', string $joinType = 'INNER', Query $query = null)
public function has(string $operator = '>=', $count = 1, $id = '*', string $joinType = 'INNER', ?Query $query = null)
{
return $this->parent;
}
@ -208,7 +243,7 @@ class BelongsToMany extends Relation
*
* @return Query
*/
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null)
public function hasWhere($where = [], $fields = null, string $joinType = '', ?Query $query = null)
{
throw new Exception('relation not support: hasWhere');
}
@ -240,7 +275,7 @@ class BelongsToMany extends Relation
*
* @return void
*/
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
$pk = $resultSet[0]->getPk();
@ -281,7 +316,7 @@ class BelongsToMany extends Relation
*
* @return void
*/
public function eagerlyResult(Model $result, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
public function eagerlyResult(Model $result, string $relation, array $subRelation, ?Closure $closure = null, array $cache = []): void
{
$pk = $result->getPk();
@ -312,7 +347,7 @@ class BelongsToMany extends Relation
*
* @return int
*/
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null)
public function relationCount(Model $result, ?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null)
{
$pk = $result->getPk();
@ -341,7 +376,7 @@ class BelongsToMany extends Relation
*
* @return string
*/
public function getRelationCountQuery(Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null): string
public function getRelationCountQuery(?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null): string
{
if ($closure) {
$closure($this->query, $name);
@ -349,7 +384,7 @@ class BelongsToMany extends Relation
return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [
[
'pivot.' . $this->localKey, 'exp', new Raw('=' . $this->parent->db(false)->getTable() . '.' . $this->parent->getPk()),
'pivot.' . $this->localKey, 'exp', new Raw('=' . $this->parent->db(false)->getTable(true) . '.' . $this->parent->getPk()),
],
])->fetchSql()->$aggregate($field);
}
@ -364,7 +399,7 @@ class BelongsToMany extends Relation
*
* @return array
*/
protected function eagerlyManyToMany(array $where, array $subRelation = [], Closure $closure = null, array $cache = []): array
protected function eagerlyManyToMany(array $where, array $subRelation = [], ?Closure $closure = null, array $cache = []): array
{
if ($closure) {
$closure($this->query);
@ -410,7 +445,7 @@ class BelongsToMany extends Relation
{
// 关联查询封装
if (empty($this->baseQuery)) {
$tableName = $this->query->getTable();
$tableName = $this->query->getTable(true);
$table = $this->pivot->db()->getTable();
$fields = $this->getQueryFields($tableName);
@ -499,11 +534,10 @@ class BelongsToMany extends Relation
$ids = (array) $id;
foreach ($ids as $id) {
$pivot[$this->foreignKey] = $id;
$this->pivot->replace()
->exists(false)
->data([])
->save($pivot);
$result[] = $this->newPivot($pivot);
$object = $this->newPivot();
$object->replace()->save($pivot);
$result[] = $object;
}
if (count($result) == 1) {
@ -645,7 +679,7 @@ class BelongsToMany extends Relation
// 关联查询
if (null === $this->parent->getKey()) {
$condition = ['pivot.' . $localKey, 'exp', new Raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk())];
$condition = ['pivot.' . $localKey, 'exp', new Raw('=' . $this->parent->getTable(true) . '.' . $this->parent->getPk())];
} else {
$condition = ['pivot.' . $localKey, '=', $this->parent->getKey()];
}

67
vendor/topthink/think-orm/src/model/relation/HasMany.php vendored Executable file → Normal file
View File

@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare(strict_types=1);
declare (strict_types = 1);
namespace think\model\relation;
@ -34,11 +34,11 @@ class HasMany extends Relation
*/
public function __construct(Model $parent, string $model, string $foreignKey, string $localKey)
{
$this->parent = $parent;
$this->model = $model;
$this->foreignKey = $foreignKey;
$this->localKey = $localKey;
$this->query = (new $model())->db();
$this->parent = $parent;
$this->model = $model;
$this->foreignKey = $foreignKey;
$this->localKey = $localKey;
$this->query = (new $model())->db();
if (get_class($parent) == $model) {
$this->selfRelation = true;
@ -53,7 +53,7 @@ class HasMany extends Relation
*
* @return Collection
*/
public function getRelation(array $subRelation = [], Closure $closure = null): Collection
public function getRelation(array $subRelation = [], ?Closure $closure = null): Collection
{
if ($closure) {
$closure($this->query);
@ -77,10 +77,10 @@ class HasMany extends Relation
*
* @return void
*/
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
$range = [];
$localKey = $this->localKey;
$range = [];
foreach ($resultSet as $result) {
// 获取关联外键列表
@ -117,13 +117,13 @@ class HasMany extends Relation
*
* @return void
*/
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
if (isset($result->$localKey)) {
$pk = $result->$localKey;
$data = $this->eagerlyOneToMany([
$pk = $result->$localKey;
$data = $this->eagerlyOneToMany([
[$this->foreignKey, '=', $pk],
], $subRelation, $closure, $cache);
@ -147,7 +147,7 @@ class HasMany extends Relation
*
* @return int
*/
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null)
public function relationCount(Model $result, ?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null)
{
$localKey = $this->localKey;
@ -174,14 +174,14 @@ class HasMany extends Relation
*
* @return string
*/
public function getRelationCountQuery(Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null): string
public function getRelationCountQuery(?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null): string
{
if ($closure) {
$closure($this->query, $name);
}
return $this->query->alias($aggregate . '_table')
->whereExp($aggregate . '_table.' . $this->foreignKey, '=' . $this->parent->getTable() . '.' . $this->localKey)
->whereExp($aggregate . '_table.' . $this->foreignKey, '=' . $this->parent->getTable(true) . '.' . $this->localKey)
->fetchSql()
->$aggregate($field);
}
@ -196,7 +196,7 @@ class HasMany extends Relation
*
* @return array
*/
protected function eagerlyOneToMany(array $where, array $subRelation = [], Closure $closure = null, array $cache = []): array
protected function eagerlyOneToMany(array $where, array $subRelation = [], ?Closure $closure = null, array $cache = []): array
{
$foreignKey = $this->foreignKey;
@ -242,7 +242,7 @@ class HasMany extends Relation
*
* @return Model|false
*/
public function save(array|Model $data, bool $replace = true)
public function save(array | Model $data, bool $replace = true)
{
$model = $this->make();
@ -256,7 +256,7 @@ class HasMany extends Relation
*
* @return Model
*/
public function make(array|Model $data = []): Model
public function make(array | Model $data = []): Model
{
if ($data instanceof Model) {
$data = $data->getData();
@ -265,7 +265,7 @@ class HasMany extends Relation
// 保存关联表数据
$data[$this->foreignKey] = $this->parent->{$this->localKey};
return new $this->model($data);
return (new $this->model($data))->setSuffix($this->getModel()->getSuffix());
}
/**
@ -298,18 +298,18 @@ class HasMany extends Relation
*
* @return Query
*/
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = 'INNER', Query $query = null): Query
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = 'INNER', ?Query $query = null): Query
{
$table = $this->query->getTable();
$model = class_basename($this->parent);
$relation = class_basename($this->model);
$table = $this->query->getTable();
$model = class_basename($this->parent);
$relation = class_basename($this->model);
if ('*' != $id) {
$id = $relation . '.' . (new $this->model())->getPk();
}
$softDelete = $this->query->getOptions('soft_delete');
$query = $query ?: $this->parent->db()->alias($model);
$query = $query ?: $this->parent->db()->alias($model);
return $query->field($model . '.*')
->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $joinType)
@ -330,11 +330,11 @@ class HasMany extends Relation
*
* @return Query
*/
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null): Query
public function hasWhere($where = [], $fields = null, string $joinType = '', ?Query $query = null): Query
{
$table = $this->query->getTable();
$model = class_basename($this->parent);
$relation = class_basename($this->model);
$table = $this->query->getTable();
$model = class_basename($this->parent);
$relation = class_basename($this->model);
if (is_array($where)) {
$this->getQueryWhere($where, $relation);
@ -345,18 +345,21 @@ class HasMany extends Relation
$where = $this->query;
}
$fields = $this->getRelationQueryFields($fields, $model);
$fields = $this->getRelationQueryFields($fields, $model);
$softDelete = $this->query->getOptions('soft_delete');
$query = $query ?: $this->parent->db();
$query = $query ?: $this->parent->db();
return $query->alias($model)
->via($model)
->group($model . '.' . $this->localKey)
->field($fields)
->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $joinType)
->when($softDelete, function ($query) use ($softDelete, $relation) {
$query->where($relation . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
})
->where($where);
->where(function ($query) use ($where) {
$query->where($where);
});
}
/**

97
vendor/topthink/think-orm/src/model/relation/HasManyThrough.php vendored Executable file → Normal file
View File

@ -58,14 +58,14 @@ class HasManyThrough extends Relation
*/
public function __construct(Model $parent, string $model, string $through, string $foreignKey, string $throughKey, string $localKey, string $throughPk)
{
$this->parent = $parent;
$this->model = $model;
$this->through = (new $through())->db();
$this->foreignKey = $foreignKey;
$this->throughKey = $throughKey;
$this->localKey = $localKey;
$this->throughPk = $throughPk;
$this->query = (new $model())->db();
$this->parent = $parent;
$this->model = $model;
$this->through = (new $through())->db();
$this->foreignKey = $foreignKey;
$this->throughKey = $throughKey;
$this->localKey = $localKey;
$this->throughPk = $throughPk;
$this->query = (new $model())->db();
}
/**
@ -76,7 +76,7 @@ class HasManyThrough extends Relation
*
* @return Collection
*/
public function getRelation(array $subRelation = [], Closure $closure = null)
public function getRelation(array $subRelation = [], ?Closure $closure = null)
{
if ($closure) {
$closure($this->query);
@ -100,15 +100,15 @@ class HasManyThrough extends Relation
*
* @return Query
*/
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null): Query
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', ?Query $query = null): Query
{
$model = Str::snake(class_basename($this->parent));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$relation = new $this->model();
$relationTable = $relation->getTable();
$softDelete = $this->query->getOptions('soft_delete');
$model = Str::snake(class_basename($this->parent));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$relation = new $this->model();
$relationTable = $relation->getTable();
$softDelete = $this->query->getOptions('soft_delete');
if ('*' != $id) {
$id = $relationTable . '.' . $relation->getPk();
@ -135,13 +135,13 @@ class HasManyThrough extends Relation
*
* @return Query
*/
public function hasWhere($where = [], $fields = null, $joinType = '', Query $query = null): Query
public function hasWhere($where = [], $fields = null, $joinType = '', ?Query $query = null): Query
{
$model = Str::snake(class_basename($this->parent));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = (new $this->model())->getTable();
$model = Str::snake(class_basename($this->parent));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = (new $this->model())->getTable();
if (is_array($where)) {
$this->getQueryWhere($where, $modelTable);
@ -157,13 +157,16 @@ class HasManyThrough extends Relation
$query = $query ?: $this->parent->db();
return $query->alias($model)
->via($model)
->join($throughTable, $throughTable . '.' . $this->foreignKey . '=' . $model . '.' . $this->localKey)
->join($modelTable, $modelTable . '.' . $throughKey . '=' . $throughTable . '.' . $this->throughPk, $joinType)
->when($softDelete, function ($query) use ($softDelete, $modelTable) {
$query->where($modelTable . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
})
->group($modelTable . '.' . $this->throughKey)
->where($where)
->where(function ($query) use ($where) {
$query->where($where);
})
->field($fields);
}
@ -178,12 +181,12 @@ class HasManyThrough extends Relation
*
* @return void
*/
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
$range = [];
$range = [];
foreach ($resultSet as $result) {
// 获取关联外键列表
if (isset($result->$localKey)) {
@ -222,7 +225,7 @@ class HasManyThrough extends Relation
*
* @return void
*/
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
@ -253,11 +256,11 @@ class HasManyThrough extends Relation
*
* @return array
*/
protected function eagerlyWhere(array $where, string $key, array $subRelation = [], Closure $closure = null, array $cache = []): array
protected function eagerlyWhere(array $where, string $key, array $subRelation = [], ?Closure $closure = null, array $cache = []): array
{
// 预载入关联查询 支持嵌套预载入
$throughList = $this->through->where($where)->select();
$keys = $throughList->column($this->throughPk, $this->throughPk);
$throughList = $this->through->where($where)->select();
$keys = $throughList->column($this->throughPk, $this->throughPk);
if ($closure) {
$this->baseQuery = true;
@ -308,7 +311,7 @@ class HasManyThrough extends Relation
*
* @return mixed
*/
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null)
public function relationCount(Model $result, ?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null)
{
$localKey = $this->localKey;
@ -320,11 +323,11 @@ class HasManyThrough extends Relation
$closure($this->query, $name);
}
$alias = Str::snake(class_basename($this->model));
$alias = Str::snake(class_basename($this->model));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = $this->parent->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = $this->parent->getTable();
if (!str_contains($field, '.')) {
$field = $alias . '.' . $field;
@ -348,17 +351,17 @@ class HasManyThrough extends Relation
*
* @return string
*/
public function getRelationCountQuery(Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null): string
public function getRelationCountQuery(?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null): string
{
if ($closure) {
$closure($this->query, $name);
}
$alias = Str::snake(class_basename($this->model));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = $this->parent->getTable();
$alias = Str::snake(class_basename($this->model));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = $this->parent->getTable();
if (!str_contains($field, '.')) {
$field = $alias . '.' . $field;
@ -381,12 +384,12 @@ class HasManyThrough extends Relation
protected function baseQuery(): void
{
if (empty($this->baseQuery) && $this->parent->getData()) {
$alias = Str::snake(class_basename($this->model));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = $this->parent->getTable();
$fields = $this->getQueryFields($alias);
$alias = Str::snake(class_basename($this->model));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = $this->parent->getTable();
$fields = $this->getQueryFields($alias);
$this->query
->field($fields)

59
vendor/topthink/think-orm/src/model/relation/HasOne.php vendored Executable file → Normal file
View File

@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare(strict_types=1);
declare (strict_types = 1);
namespace think\model\relation;
@ -32,11 +32,11 @@ class HasOne extends OneToOne
*/
public function __construct(Model $parent, string $model, string $foreignKey, string $localKey)
{
$this->parent = $parent;
$this->model = $model;
$this->foreignKey = $foreignKey;
$this->localKey = $localKey;
$this->query = (new $model())->db();
$this->parent = $parent;
$this->model = $model;
$this->foreignKey = $foreignKey;
$this->localKey = $localKey;
$this->query = (new $model())->db();
if (get_class($parent) == $model) {
$this->selfRelation = true;
@ -51,7 +51,7 @@ class HasOne extends OneToOne
*
* @return Model
*/
public function getRelation(array $subRelation = [], Closure $closure = null)
public function getRelation(array $subRelation = [], ?Closure $closure = null)
{
$localKey = $this->localKey;
@ -74,7 +74,7 @@ class HasOne extends OneToOne
$relationModel->setParent(clone $this->parent);
} else {
$default = $this->query->getOptions('default_model');
$default = $this->query->getOptions('default_model');
$relationModel = $this->getDefaultModel($default);
}
@ -91,14 +91,14 @@ class HasOne extends OneToOne
*
* @return string
*/
public function getRelationCountQuery(Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null): string
public function getRelationCountQuery(?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null): string
{
if ($closure) {
$closure($this->query, $name);
}
return $this->query
->whereExp($this->foreignKey, '=' . $this->parent->getTable() . '.' . $this->localKey)
->whereExp($this->foreignKey, '=' . $this->parent->getTable(true) . '.' . $this->localKey)
->fetchSql()
->$aggregate($field);
}
@ -114,7 +114,7 @@ class HasOne extends OneToOne
*
* @return int
*/
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null)
public function relationCount(Model $result, ?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null)
{
$localKey = $this->localKey;
@ -142,7 +142,7 @@ class HasOne extends OneToOne
*
* @return Query
*/
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null): Query
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', ?Query $query = null): Query
{
$table = $this->query->getTable();
$model = class_basename($this->parent);
@ -172,11 +172,11 @@ class HasOne extends OneToOne
*
* @return Query
*/
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null): Query
public function hasWhere($where = [], $fields = null, string $joinType = '', ?Query $query = null): Query
{
$table = $this->query->getTable();
$model = class_basename($this->parent);
$relation = class_basename($this->model);
$table = $this->query->getTable();
$model = class_basename($this->parent);
$relation = class_basename($this->model);
if (is_array($where)) {
$this->getQueryWhere($where, $relation);
@ -192,12 +192,15 @@ class HasOne extends OneToOne
$query = $query ?: $this->parent->db();
return $query->alias($model)
->via($model)
->field($fields)
->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $joinType ?: $this->joinType)
->when($softDelete, function ($query) use ($softDelete, $relation) {
$query->where($relation . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
})
->where($where);
->where(function ($query) use ($where) {
$query->where($where);
});
}
/**
@ -211,12 +214,12 @@ class HasOne extends OneToOne
*
* @return void
*/
protected function eagerlySet(array &$resultSet, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
protected function eagerlySet(array &$resultSet, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
$range = [];
$range = [];
foreach ($resultSet as $result) {
// 获取关联外键列表
if (isset($result->$localKey)) {
@ -226,13 +229,19 @@ class HasOne extends OneToOne
if (!empty($range)) {
$this->query->removeWhereField($foreignKey);
$default = $this->query->getOptions('default_model');
$default = $this->query->getOptions('default_model');
$defaultModel = $this->getDefaultModel($default);
$data = $this->eagerlyWhere([
[$foreignKey, 'in', $range],
], $foreignKey, $subRelation, $closure, $cache);
// 动态绑定参数
$bindAttr = $this->query->getOptions('bind_attr');
if ($bindAttr) {
$this->bind($bindAttr);
}
// 关联数据封装
foreach ($resultSet as $result) {
// 关联模型
@ -266,7 +275,7 @@ class HasOne extends OneToOne
*
* @return void
*/
protected function eagerlyOne(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
protected function eagerlyOne(Model $result, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
@ -279,7 +288,7 @@ class HasOne extends OneToOne
// 关联模型
if (!isset($data[$result->$localKey])) {
$default = $this->query->getOptions('default_model');
$default = $this->query->getOptions('default_model');
$relationModel = $this->getDefaultModel($default);
} else {
$relationModel = $data[$result->$localKey];
@ -290,6 +299,12 @@ class HasOne extends OneToOne
// 设置关联属性
$result->setRelation($relation, $relationModel);
// 动态绑定参数
$bindAttr = $this->query->getOptions('bind_attr');
if ($bindAttr) {
$this->bind($bindAttr);
}
if (!empty($this->bindAttr)) {
// 绑定关联属性
$this->bindAttr($result, $relationModel);

20
vendor/topthink/think-orm/src/model/relation/HasOneThrough.php vendored Executable file → Normal file
View File

@ -28,7 +28,7 @@ class HasOneThrough extends HasManyThrough
*
* @return Model
*/
public function getRelation(array $subRelation = [], Closure $closure = null)
public function getRelation(array $subRelation = [], ?Closure $closure = null)
{
if ($closure) {
$closure($this->query);
@ -59,7 +59,7 @@ class HasOneThrough extends HasManyThrough
*
* @return void
*/
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
@ -109,7 +109,7 @@ class HasOneThrough extends HasManyThrough
*
* @return void
*/
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
@ -144,7 +144,7 @@ class HasOneThrough extends HasManyThrough
*
* @return array
*/
protected function eagerlyWhere(array $where, string $key, array $subRelation = [], Closure $closure = null, array $cache = []): array
protected function eagerlyWhere(array $where, string $key, array $subRelation = [], ?Closure $closure = null, array $cache = []): array
{
// 预载入关联查询 支持嵌套预载入
$keys = $this->through->where($where)->column($this->throughPk, $this->foreignKey);
@ -159,13 +159,9 @@ class HasOneThrough extends HasManyThrough
->select();
// 组装模型数据
$data = [];
$keys = array_flip($keys);
foreach ($list as $set) {
$data[$keys[$set->{$this->throughKey}]] = $set;
}
return $data;
return array_map(function ($key) use ($list) {
$set = $list->where($this->throughKey, '=', $key)->first();
return $set ? clone $set : null;
}, $keys);
}
}

20
vendor/topthink/think-orm/src/model/relation/MorphMany.php vendored Executable file → Normal file
View File

@ -72,7 +72,7 @@ class MorphMany extends Relation
*
* @return Collection
*/
public function getRelation(array $subRelation = [], Closure $closure = null): Collection
public function getRelation(array $subRelation = [], ?Closure $closure = null): Collection
{
if ($closure) {
$closure($this->query);
@ -96,7 +96,7 @@ class MorphMany extends Relation
*
* @return Query
*/
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null)
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', ?Query $query = null)
{
throw new Exception('relation not support: has');
}
@ -111,7 +111,7 @@ class MorphMany extends Relation
*
* @return Query
*/
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null)
public function hasWhere($where = [], $fields = null, string $joinType = '', ?Query $query = null)
{
throw new Exception('relation not support: hasWhere');
}
@ -127,7 +127,7 @@ class MorphMany extends Relation
*
* @return void
*/
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, ?Closure $closure = null, array $cache = []): void
{
$morphType = $this->morphType;
$morphKey = $this->morphKey;
@ -171,7 +171,7 @@ class MorphMany extends Relation
*
* @return void
*/
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$pk = $result->getPk();
@ -201,7 +201,7 @@ class MorphMany extends Relation
*
* @return mixed
*/
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null)
public function relationCount(Model $result, ?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null)
{
$pk = $result->getPk();
@ -231,14 +231,14 @@ class MorphMany extends Relation
*
* @return string
*/
public function getRelationCountQuery(Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null): string
public function getRelationCountQuery(?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null): string
{
if ($closure) {
$closure($this->query, $name);
}
return $this->query
->whereExp($this->morphKey, '=' . $this->parent->getTable() . '.' . $this->parent->getPk())
->whereExp($this->morphKey, '=' . $this->parent->getTable(true) . '.' . $this->parent->getPk())
->where($this->morphType, '=', $this->type)
->fetchSql()
->$aggregate($field);
@ -254,7 +254,7 @@ class MorphMany extends Relation
*
* @return array
*/
protected function eagerlyMorphToMany(array $where, array $subRelation = [], Closure $closure = null, array $cache = []): array
protected function eagerlyMorphToMany(array $where, array $subRelation = [], ?Closure $closure = null, array $cache = []): array
{
// 预载入关联查询 支持嵌套预载入
$this->query->removeOption('where');
@ -325,7 +325,7 @@ class MorphMany extends Relation
$data[$this->morphKey] = $this->parent->$pk;
$data[$this->morphType] = $this->type;
return new $this->model($data);
return (new $this->model($data))->setSuffix($this->getModel()->getSuffix());
}
/**

18
vendor/topthink/think-orm/src/model/relation/MorphOne.php vendored Executable file → Normal file
View File

@ -78,7 +78,7 @@ class MorphOne extends Relation
*
* @return Model
*/
public function getRelation(array $subRelation = [], Closure $closure = null)
public function getRelation(array $subRelation = [], ?Closure $closure = null)
{
if ($closure) {
$closure($this->query);
@ -114,7 +114,7 @@ class MorphOne extends Relation
*
* @return Query
*/
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null)
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', ?Query $query = null)
{
return $this->parent;
}
@ -129,7 +129,7 @@ class MorphOne extends Relation
*
* @return Query
*/
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null)
public function hasWhere($where = [], $fields = null, string $joinType = '', ?Query $query = null)
{
throw new Exception('relation not support: hasWhere');
}
@ -145,7 +145,7 @@ class MorphOne extends Relation
*
* @return void
*/
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, ?Closure $closure = null, array $cache = []): void
{
$morphType = $this->morphType;
$morphKey = $this->morphKey;
@ -201,7 +201,7 @@ class MorphOne extends Relation
*
* @return void
*/
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
$pk = $result->getPk();
@ -241,7 +241,7 @@ class MorphOne extends Relation
*
* @return array
*/
protected function eagerlyMorphToOne(array $where, array $subRelation = [], $closure = null, array $cache = []): array
protected function eagerlyMorphToOne(array $where, array $subRelation = [], ?Closure $closure = null, array $cache = []): array
{
// 预载入关联查询 支持嵌套预载入
if ($closure) {
@ -300,7 +300,7 @@ class MorphOne extends Relation
$data[$this->morphKey] = $this->parent->$pk;
$data[$this->morphType] = $this->type;
return new $this->model($data);
return (new $this->model($data))->setSuffix($this->getModel()->getSuffix());
}
/**
@ -355,7 +355,7 @@ class MorphOne extends Relation
*
* @return void
*/
protected function bindAttr(Model $result, Model $model = null): void
protected function bindAttr(Model $result, ?Model $model = null): void
{
foreach ($this->bindAttr as $key => $attr) {
$key = is_numeric($key) ? $attr : $key;
@ -365,7 +365,7 @@ class MorphOne extends Relation
throw new Exception('bind attr has exists:' . $key);
}
$result->setAttr($key, $model?->$attr);
$result->setAttr($key, $model?->getAttr($attr));
}
}
}

43
vendor/topthink/think-orm/src/model/relation/MorphTo.php vendored Executable file → Normal file
View File

@ -12,6 +12,7 @@
namespace think\model\relation;
use BackedEnum;
use Closure;
use think\db\exception\DbException as Exception;
use think\db\Query;
@ -63,7 +64,7 @@ class MorphTo extends Relation
* @param array $alias 多态别名定义
* @param ?string $relation 关联名
*/
public function __construct(Model $parent, string $morphType, string $morphKey, array $alias = [], string $relation = null)
public function __construct(Model $parent, string $morphType, string $morphKey, array $alias = [], ?string $relation = null)
{
$this->parent = $parent;
$this->morphType = $morphType;
@ -93,7 +94,7 @@ class MorphTo extends Relation
*
* @return Model
*/
public function getRelation(array $subRelation = [], Closure $closure = null)
public function getRelation(array $subRelation = [], ?Closure $closure = null)
{
$morphKey = $this->morphKey;
$morphType = $this->morphType;
@ -124,7 +125,7 @@ class MorphTo extends Relation
*
* @return Query
*/
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null)
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', ?Query $query = null)
{
return $this->parent;
}
@ -139,7 +140,7 @@ class MorphTo extends Relation
*
* @return Query
*/
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null)
public function hasWhere($where = [], $fields = null, string $joinType = '', ?Query $query = null)
{
$alias = class_basename($this->parent);
$types = $this->parent->distinct()->column($this->morphType);
@ -173,8 +174,12 @@ class MorphTo extends Relation
*
* @return Model
*/
protected function parseModel(string $model): string
protected function parseModel($model): string
{
if ($model instanceof BackedEnum) {
$model = $model->value;
}
if (isset($this->alias[$model])) {
$model = $this->alias[$model];
}
@ -226,7 +231,7 @@ class MorphTo extends Relation
*
* @return void
*/
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, ?Closure $closure = null, array $cache = []): void
{
$morphKey = $this->morphKey;
$morphType = $this->morphType;
@ -243,18 +248,20 @@ class MorphTo extends Relation
foreach ($range as $key => $val) {
// 多态类型映射
$model = $this->parseModel($key);
$obj = new $model();
if (!is_null($closure)) {
$obj = $closure($obj);
}
$pk = $obj->getPk();
$list = $obj->with($subRelation)
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
->select($val);
$data = [];
if (class_exists($model)) {
$obj = new $model();
if (!is_null($closure)) {
$obj = $closure($obj);
}
$pk = $obj->getPk();
$list = $obj->with($subRelation)
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
->select($val);
foreach ($list as $k => $vo) {
$data[$vo->$pk] = $vo;
foreach ($list as $k => $vo) {
$data[$vo->$pk] = $vo;
}
}
foreach ($resultSet as $result) {
@ -286,7 +293,7 @@ class MorphTo extends Relation
*
* @return void
*/
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = []): void
{
// 多态类型映射
$model = $this->parseModel($result->{$this->morphType});
@ -304,7 +311,7 @@ class MorphTo extends Relation
*
* @return int
*/
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*')
public function relationCount(Model $result, ?Closure $closure = null, string $aggregate = 'count', string $field = '*')
{
}

14
vendor/topthink/think-orm/src/model/relation/MorphToMany.php vendored Executable file → Normal file
View File

@ -90,7 +90,7 @@ class MorphToMany extends BelongsToMany
*
* @return void
*/
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, ?Closure $closure = null, array $cache = []): void
{
$pk = $resultSet[0]->getPk();
$range = [];
@ -131,7 +131,7 @@ class MorphToMany extends BelongsToMany
*
* @return void
*/
public function eagerlyResult(Model $result, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
public function eagerlyResult(Model $result, string $relation, array $subRelation, ?Closure $closure = null, array $cache = []): void
{
$pk = $result->getPk();
@ -163,7 +163,7 @@ class MorphToMany extends BelongsToMany
*
* @return int
*/
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null)
public function relationCount(Model $result, ?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null)
{
$pk = $result->getPk();
@ -191,14 +191,14 @@ class MorphToMany extends BelongsToMany
*
* @return string
*/
public function getRelationCountQuery(Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null): string
public function getRelationCountQuery(?Closure $closure = null, string $aggregate = 'count', string $field = '*', ?string &$name = null): string
{
if ($closure) {
$closure($this->query, $name);
}
return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [
['pivot.' . $this->localKey, 'exp', new Raw('=' . $this->parent->db(false)->getTable() . '.' . $this->parent->getPk())],
['pivot.' . $this->localKey, 'exp', new Raw('=' . $this->parent->db(false)->getTable(true) . '.' . $this->parent->getPk())],
['pivot.' . $this->morphType, '=', $this->morphClass],
])->fetchSql()->$aggregate($field);
}
@ -242,7 +242,7 @@ class MorphToMany extends BelongsToMany
*
* @return array
*/
protected function eagerlyManyToMany(array $where, array $subRelation = [], Closure $closure = null, array $cache = []): array
protected function eagerlyManyToMany(array $where, array $subRelation = [], ?Closure $closure = null, array $cache = []): array
{
if ($closure) {
$closure($this->query);
@ -486,7 +486,7 @@ class MorphToMany extends BelongsToMany
*
* @return array
*/
public static function morphMap(array $map = null, $merge = true): array
public static function morphMap(?array $map = null, $merge = true): array
{
if (is_array($map)) {
static::$morphMap = $merge && static::$morphMap

44
vendor/topthink/think-orm/src/model/relation/OneToOne.php vendored Executable file → Normal file
View File

@ -15,6 +15,7 @@ namespace think\model\relation;
use Closure;
use think\db\BaseQuery as Query;
use think\db\exception\DbException as Exception;
use think\db\exception\InvalidArgumentException;
use think\helper\Str;
use think\Model;
use think\model\Relation;
@ -71,7 +72,7 @@ abstract class OneToOne extends Relation
*
* @return void
*/
public function eagerly(Query $query, string $relation, $field = true, string $joinType = '', Closure $closure = null, bool $first = false): void
public function eagerly(Query $query, string $relation, $field = true, string $joinType = '', ?Closure $closure = null, bool $first = false): void
{
$name = Str::snake(class_basename($this->parent));
@ -91,7 +92,7 @@ abstract class OneToOne extends Relation
// 预载入封装
$joinTable = $this->query->getTable();
$joinAlias = $relation;
$joinAlias = Str::snake($relation);
$joinType = $joinType ?: $this->joinType;
$query->via($joinAlias);
@ -126,7 +127,7 @@ abstract class OneToOne extends Relation
}
$query->join([$joinTable => $joinAlias], $joinOn, $joinType)
->tableField($field, $joinTable, $joinAlias, $relation . '__');
->tableField($field, $joinTable, $joinAlias, $joinAlias . '__');
}
/**
@ -139,7 +140,7 @@ abstract class OneToOne extends Relation
*
* @return mixed
*/
abstract protected function eagerlySet(array &$resultSet, string $relation, array $subRelation = [], Closure $closure = null);
abstract protected function eagerlySet(array &$resultSet, string $relation, array $subRelation = [], ?Closure $closure = null);
/**
* 预载入关联查询(数据).
@ -151,7 +152,7 @@ abstract class OneToOne extends Relation
*
* @return mixed
*/
abstract protected function eagerlyOne(Model $result, string $relation, array $subRelation = [], Closure $closure = null);
abstract protected function eagerlyOne(Model $result, string $relation, array $subRelation = [], ?Closure $closure = null);
/**
* 预载入关联查询(数据集).
@ -165,7 +166,7 @@ abstract class OneToOne extends Relation
*
* @return void
*/
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation = [], Closure $closure = null, array $cache = [], bool $join = false): void
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = [], bool $join = false): void
{
if ($join) {
// 模型JOIN关联组装
@ -190,7 +191,7 @@ abstract class OneToOne extends Relation
*
* @return void
*/
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = [], bool $join = false): void
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], ?Closure $closure = null, array $cache = [], bool $join = false): void
{
if ($join) {
// 模型JOIN关联组装
@ -232,7 +233,7 @@ abstract class OneToOne extends Relation
// 保存关联表数据
$data[$this->foreignKey] = $this->parent->{$this->localKey};
return new $this->model($data);
return (new $this->model($data))->setSuffix($this->getModel()->getSuffix());
}
/**
@ -274,8 +275,8 @@ abstract class OneToOne extends Relation
foreach ($result->getData() as $key => $val) {
if (str_contains($key, '__')) {
[$name, $attr] = explode('__', $key, 2);
if ($name == $relation) {
$list[$name][$attr] = $val;
if ($name == Str::snake($relation)) {
$list[$relation][$attr] = $val;
unset($result->$key);
}
}
@ -312,17 +313,28 @@ abstract class OneToOne extends Relation
*
* @return void
*/
protected function bindAttr(Model $result, Model $model = null): void
protected function bindAttr(Model $result, ?Model $model = null): void
{
foreach ($this->bindAttr as $key => $attr) {
$key = is_numeric($key) ? $attr : $key;
$value = $result->getOrigin($key);
if (is_numeric($key)) {
if (!is_string($attr)) {
throw new InvalidArgumentException('bind attr must be string:' . $key);
}
if (!is_null($value)) {
$key = $attr;
}
if (null !== $result->getOrigin($key)) {
throw new Exception('bind attr has exists:' . $key);
}
$result->setAttr($key, $model?->$attr);
if ($attr instanceof Closure) {
$value = $attr($model, $key, $result);
} else {
$value = $model?->getAttr($attr);
}
$result->setAttr($key, $value);
}
}
@ -337,7 +349,7 @@ abstract class OneToOne extends Relation
*
* @return array
*/
protected function eagerlyWhere(array $where, string $key, array $subRelation = [], Closure $closure = null, array $cache = [])
protected function eagerlyWhere(array $where, string $key, array $subRelation = [], ?Closure $closure = null, array $cache = [])
{
// 预载入关联查询 支持嵌套预载入
if ($closure) {