提交的内容
This commit is contained in:
26
vendor/topthink/think-orm/src/model/Collection.php
vendored
Executable file → Normal file
26
vendor/topthink/think-orm/src/model/Collection.php
vendored
Executable file → Normal 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
2
vendor/topthink/think-orm/src/model/Pivot.php
vendored
Executable file → Normal 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
2
vendor/topthink/think-orm/src/model/Relation.php
vendored
Executable file → Normal 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
180
vendor/topthink/think-orm/src/model/concern/Attribute.php
vendored
Executable file → Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
64
vendor/topthink/think-orm/src/model/concern/AutoWriteId.php
vendored
Normal file
64
vendor/topthink/think-orm/src/model/concern/AutoWriteId.php
vendored
Normal 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
65
vendor/topthink/think-orm/src/model/concern/Conversion.php
vendored
Executable file → Normal 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
21
vendor/topthink/think-orm/src/model/concern/ModelEvent.php
vendored
Executable file → Normal 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
0
vendor/topthink/think-orm/src/model/concern/OptimLock.php
vendored
Executable file → Normal file
56
vendor/topthink/think-orm/src/model/concern/RelationShip.php
vendored
Executable file → Normal file
56
vendor/topthink/think-orm/src/model/concern/RelationShip.php
vendored
Executable file → Normal 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
8
vendor/topthink/think-orm/src/model/concern/SoftDelete.php
vendored
Executable file → Normal 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
0
vendor/topthink/think-orm/src/model/concern/TimeStamp.php
vendored
Executable file → Normal file
2
vendor/topthink/think-orm/src/model/concern/Virtual.php
vendored
Executable file → Normal file
2
vendor/topthink/think-orm/src/model/concern/Virtual.php
vendored
Executable file → Normal 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();
|
||||
|
||||
10
vendor/topthink/think-orm/src/model/contract/EnumTransform.php
vendored
Normal file
10
vendor/topthink/think-orm/src/model/contract/EnumTransform.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace think\model\contract;
|
||||
|
||||
interface EnumTransform
|
||||
{
|
||||
public function value();
|
||||
}
|
||||
17
vendor/topthink/think-orm/src/model/contract/FieldTypeTransform.php
vendored
Normal file
17
vendor/topthink/think-orm/src/model/contract/FieldTypeTransform.php
vendored
Normal 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
67
vendor/topthink/think-orm/src/model/relation/BelongsTo.php
vendored
Executable file → Normal 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
68
vendor/topthink/think-orm/src/model/relation/BelongsToMany.php
vendored
Executable file → Normal 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
67
vendor/topthink/think-orm/src/model/relation/HasMany.php
vendored
Executable file → Normal 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
97
vendor/topthink/think-orm/src/model/relation/HasManyThrough.php
vendored
Executable file → Normal 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
59
vendor/topthink/think-orm/src/model/relation/HasOne.php
vendored
Executable file → Normal 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
20
vendor/topthink/think-orm/src/model/relation/HasOneThrough.php
vendored
Executable file → Normal 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
20
vendor/topthink/think-orm/src/model/relation/MorphMany.php
vendored
Executable file → Normal 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
18
vendor/topthink/think-orm/src/model/relation/MorphOne.php
vendored
Executable file → Normal 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
43
vendor/topthink/think-orm/src/model/relation/MorphTo.php
vendored
Executable file → Normal 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
14
vendor/topthink/think-orm/src/model/relation/MorphToMany.php
vendored
Executable file → Normal 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
44
vendor/topthink/think-orm/src/model/relation/OneToOne.php
vendored
Executable file → Normal 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) {
|
||||
|
||||
Reference in New Issue
Block a user