From 40f384806ba6a2a74bb3342fd724ec71afc1d09e Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Tue, 14 Sep 2021 20:14:32 +0800 Subject: [PATCH 01/40] =?UTF-8?q?=E5=85=B3=E8=81=94=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0withDefault=E6=96=B9=E6=B3=95=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E5=85=B3=E8=81=94=E6=95=B0=E6=8D=AE=E4=B8=8D=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E6=97=B6=E5=80=99=E7=9A=84=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/Relation.php | 38 ++++++++++++++++++++++++++++ src/model/relation/BelongsTo.php | 6 +++-- src/model/relation/HasOne.php | 6 +++-- src/model/relation/HasOneThrough.php | 6 +++-- src/model/relation/MorphOne.php | 6 +++-- 5 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/model/Relation.php b/src/model/Relation.php index 97b6c595..358842d6 100644 --- a/src/model/Relation.php +++ b/src/model/Relation.php @@ -85,6 +85,12 @@ abstract class Relation */ protected $withoutField; + /** + * 默认数据 + * @var mixed + */ + protected $default; + /** * 获取关联的所属模型 * @access public @@ -234,6 +240,38 @@ public function withoutField($field) return $this; } + /** + * 设置关联数据不存在的时候默认值 + * @access public + * @param mixed $data 默认值 + * @return $this + */ + public function withDefault($data = null) + { + $this->default = $data; + return $this; + } + + /** + * 获取关联数据默认值 + * @access protected + * @return mixed + */ + protected function getDefaultModel() + { + if (is_array($this->default)) { + $model = (new $this->model)->data($this->default); + } elseif ($this->default instanceof Closure) { + $closure = $this->default; + $model = new $this->model; + $closure($model); + } else { + $model = $this->default; + } + + return $model; + } + /** * 判断闭包的参数类型 * @access protected diff --git a/src/model/relation/BelongsTo.php b/src/model/relation/BelongsTo.php index 7a590afd..941e1d44 100644 --- a/src/model/relation/BelongsTo.php +++ b/src/model/relation/BelongsTo.php @@ -73,6 +73,8 @@ public function getRelation(array $subRelation = [], Closure $closure = null) } $relationModel->setParent(clone $this->parent); + } else { + $relationModel = $this->getDefaultModel(); } return $relationModel; @@ -227,7 +229,7 @@ protected function eagerlySet(array &$resultSet, string $relation, array $subRel foreach ($resultSet as $result) { // 关联模型 if (!isset($data[$result->$foreignKey])) { - $relationModel = null; + $relationModel = $this->getDefaultModel(); } else { $relationModel = $data[$result->$foreignKey]; $relationModel->setParent(clone $result); @@ -268,7 +270,7 @@ protected function eagerlyOne(Model $result, string $relation, array $subRelatio // 关联模型 if (!isset($data[$result->$foreignKey])) { - $relationModel = null; + $relationModel = $this->getDefaultModel(); } else { $relationModel = $data[$result->$foreignKey]; $relationModel->setParent(clone $result); diff --git a/src/model/relation/HasOne.php b/src/model/relation/HasOne.php index a37eca46..be4927b6 100644 --- a/src/model/relation/HasOne.php +++ b/src/model/relation/HasOne.php @@ -72,6 +72,8 @@ public function getRelation(array $subRelation = [], Closure $closure = null) } $relationModel->setParent(clone $this->parent); + } else { + $relationModel = $this->getDefaultModel(); } return $relationModel; @@ -226,7 +228,7 @@ protected function eagerlySet(array &$resultSet, string $relation, array $subRel foreach ($resultSet as $result) { // 关联模型 if (!isset($data[$result->$localKey])) { - $relationModel = null; + $relationModel = $this->getDefaultModel(); } else { $relationModel = $data[$result->$localKey]; $relationModel->setParent(clone $result); @@ -267,7 +269,7 @@ protected function eagerlyOne(Model $result, string $relation, array $subRelatio // 关联模型 if (!isset($data[$result->$localKey])) { - $relationModel = null; + $relationModel = $this->getDefaultModel(); } else { $relationModel = $data[$result->$localKey]; $relationModel->setParent(clone $result); diff --git a/src/model/relation/HasOneThrough.php b/src/model/relation/HasOneThrough.php index 8ec42df4..0278533e 100644 --- a/src/model/relation/HasOneThrough.php +++ b/src/model/relation/HasOneThrough.php @@ -40,6 +40,8 @@ public function getRelation(array $subRelation = [], Closure $closure = null) if ($relationModel) { $relationModel->setParent(clone $this->parent); + } else { + $relationModel = $this->getDefaultModel(); } return $relationModel; @@ -79,7 +81,7 @@ public function eagerlyResultSet(array &$resultSet, string $relation, array $sub foreach ($resultSet as $result) { // 关联模型 if (!isset($data[$result->$localKey])) { - $relationModel = null; + $relationModel = $this->getDefaultModel(); } else { $relationModel = $data[$result->$localKey]; $relationModel->setParent(clone $result); @@ -115,7 +117,7 @@ public function eagerlyResult(Model $result, string $relation, array $subRelatio // 关联模型 if (!isset($data[$result->$localKey])) { - $relationModel = null; + $relationModel = $this->getDefaultModel(); } else { $relationModel = $data[$result->$localKey]; $relationModel->setParent(clone $result); diff --git a/src/model/relation/MorphOne.php b/src/model/relation/MorphOne.php index bc89c0ba..788dd295 100644 --- a/src/model/relation/MorphOne.php +++ b/src/model/relation/MorphOne.php @@ -90,6 +90,8 @@ public function getRelation(array $subRelation = [], Closure $closure = null) } $relationModel->setParent(clone $this->parent); + } else { + $relationModel = $this->getDefaultModel(); } return $relationModel; @@ -158,7 +160,7 @@ public function eagerlyResultSet(array &$resultSet, string $relation, array $sub // 关联数据封装 foreach ($resultSet as $result) { if (!isset($data[$result->$pk])) { - $relationModel = null; + $relationModel = $this->getDefaultModel(); } else { $relationModel = $data[$result->$pk]; $relationModel->setParent(clone $result); @@ -202,7 +204,7 @@ public function eagerlyResult(Model $result, string $relation, array $subRelatio $relationModel->setParent(clone $result); $relationModel->exists(true); } else { - $relationModel = null; + $relationModel = $this->getDefaultModel(); } if (!empty($this->bindAttr)) { From 3dcf9af447b048103093840833e8c74ab849152f Mon Sep 17 00:00:00 2001 From: Nzzz964 <2582787306@qq.com> Date: Tue, 12 Oct 2021 15:18:10 +0800 Subject: [PATCH 02/40] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20whereNotBetweenTime?= =?UTF-8?q?=20=E9=80=BB=E8=BE=91=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/concern/TimeFieldQuery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/concern/TimeFieldQuery.php b/src/db/concern/TimeFieldQuery.php index 1267e540..69b7eae4 100644 --- a/src/db/concern/TimeFieldQuery.php +++ b/src/db/concern/TimeFieldQuery.php @@ -182,7 +182,7 @@ public function whereBetweenTime(string $field, $startTime, $endTime, string $lo public function whereNotBetweenTime(string $field, $startTime, $endTime) { return $this->whereTime($field, '<', $startTime) - ->whereTime($field, '>', $endTime); + ->whereTime($field, '>', $endTime, 'OR'); } /** From 5425f2ca05e02c5ba15db77098ab9433bd2963bf Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Thu, 9 Dec 2021 22:21:28 +0800 Subject: [PATCH 03/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3column=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/BaseQuery.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 4bd4bfbf..7ff93d68 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -278,7 +278,9 @@ public function value(string $field, $default = null) public function column($field, string $key = ''): array { $result = $this->connection->column($this, $field, $key); - $this->resultSet($result, false); + if (count($result) != count($result, 1)) { + $this->resultSet($result, false); + } return $result; } From c422dbaa80671f120c0fef2acfe28ecb7dd1b794 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 15 Dec 2021 12:14:40 +0800 Subject: [PATCH 04/40] =?UTF-8?q?=E5=85=BC=E5=AE=B98.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model.php | 4 ++++ src/Paginator.php | 10 ++++++++-- src/model/concern/Conversion.php | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Model.php b/src/Model.php index 03453584..2d2f86fb 100644 --- a/src/Model.php +++ b/src/Model.php @@ -970,21 +970,25 @@ public function __unset(string $name): void } // ArrayAccess + #[\ReturnTypeWillChange] public function offsetSet($name, $value) { $this->setAttr($name, $value); } + #[\ReturnTypeWillChange] public function offsetExists($name): bool { return $this->__isset($name); } + #[\ReturnTypeWillChange] public function offsetUnset($name) { $this->__unset($name); } + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->getAttr($name); diff --git a/src/Paginator.php b/src/Paginator.php index d8d43d7d..2f755ef4 100644 --- a/src/Paginator.php +++ b/src/Paginator.php @@ -410,7 +410,8 @@ public function each(callable $callback) * @return Traversable An instance of an object implementing Iterator or * Traversable */ - public function getIterator() + #[\ReturnTypeWillChange] + public function getIterator(): Traversable { return new ArrayIterator($this->items->all()); } @@ -421,7 +422,8 @@ public function getIterator() * @param mixed $offset * @return bool */ - public function offsetExists($offset) + #[\ReturnTypeWillChange] + public function offsetExists($offset): bool { return $this->items->offsetExists($offset); } @@ -432,6 +434,7 @@ public function offsetExists($offset) * @param mixed $offset * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->items->offsetGet($offset); @@ -443,6 +446,7 @@ public function offsetGet($offset) * @param mixed $offset * @param mixed $value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->items->offsetSet($offset, $value); @@ -455,6 +459,7 @@ public function offsetSet($offset, $value) * @return void * @since 5.0.0 */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $this->items->offsetUnset($offset); @@ -498,6 +503,7 @@ public function toArray(): array /** * Specify data which should be serialized to JSON */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); diff --git a/src/model/concern/Conversion.php b/src/model/concern/Conversion.php index 35d96d05..22d62565 100644 --- a/src/model/concern/Conversion.php +++ b/src/model/concern/Conversion.php @@ -330,6 +330,7 @@ public function __toString() } // JsonSerializable + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); From 3af9219b110bdd66391b5c25b4ad141b989274bd Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Mon, 20 Dec 2021 21:58:42 +0800 Subject: [PATCH 05/40] =?UTF-8?q?Db=E5=92=8C=E6=A8=A1=E5=9E=8B=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0filter=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model.php | 56 +++++++++++- src/db/BaseQuery.php | 5 +- src/db/concern/ModelRelationQuery.php | 126 +++++++++++--------------- src/db/concern/ResultOperation.php | 67 +++++--------- src/model/concern/Attribute.php | 24 +++++ src/model/relation/BelongsToMany.php | 90 ++++++------------ 6 files changed, 186 insertions(+), 182 deletions(-) diff --git a/src/Model.php b/src/Model.php index 2d2f86fb..89d3b40c 100644 --- a/src/Model.php +++ b/src/Model.php @@ -243,6 +243,50 @@ public function __construct(array $data = []) } } + $this->filter(function ($result, $options) { + // JSON 数据处理 + if (!empty($options['json'])) { + $this->jsonResult($result, $options['json'], $options['json_assoc'], $options['with_relation_attr']); + } + + // 动态获取器 + if (!empty($options['with_attr'])) { + $result->withAttribute($options['with_attr']); + } + + // 输出属性控制 + if (!empty($options['visible'])) { + $result->visible($options['visible']); + } elseif (!empty($options['hidden'])) { + $result->hidden($options['hidden']); + } + + if (!empty($options['append'])) { + $result->append($options['append']); + } + + // 关联查询 + if (!empty($options['relation'])) { + $result->relationQuery($options['relation'], $options['with_relation_attr']); + } + + // 预载入查询 + if (!empty($options['with'])) { + $result->eagerlyResult($result, $options['with'], $options['with_relation_attr'], false, $options['with_cache'] ?? false); + } + + // JOIN预载入查询 + if (!empty($options['with_join'])) { + $result->eagerlyResult($result, $options['with_join'], $options['with_relation_attr'], true, $options['with_cache'] ?? false); + } + + // 关联统计 + if (!empty($options['with_count'])) { + foreach ($options['with_count'] as $val) { + $result->relationCount($this, (array) $val[0], $val[1], $val[2], false); + } + } + }); // 执行初始化操作 $this->initialize(); } @@ -260,11 +304,12 @@ public function getName(): string /** * 创建新的模型实例 * @access public - * @param array $data 数据 - * @param mixed $where 更新条件 + * @param array $data 数据 + * @param mixed $where 更新条件 + * @param array $options 参数 * @return Model */ - public function newInstance(array $data = [], $where = null): Model + public function newInstance(array $data = [], $where = null, array $options = []): Model { $model = new static($data); @@ -284,6 +329,11 @@ public function newInstance(array $data = [], $where = null): Model $model->setUpdateWhere($where); + // 查询数据处理 + foreach ($this->filter as $filter) { + call_user_func_array($filter, [$model, $options]); + } + $model->trigger('AfterRead'); return $model; diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 7ff93d68..c2fee3a7 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -869,7 +869,10 @@ public function json(array $json = [], bool $assoc = false) { $this->options['json'] = $json; $this->options['json_assoc'] = $assoc; - return $this; + + return $this->filter(function (&$result) use ($json) { + $this->jsonResult($result, $json, true); + }, 'json'); } /** diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index ffb72de4..e0d06319 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -60,7 +60,10 @@ public function getModel() public function hidden(array $hidden) { $this->options['hidden'] = $hidden; - return $this; + + return $this->filter(function (&$result) { + $result = $this->dataVisibleFilter($result); + }, 'visible'); } /** @@ -72,7 +75,26 @@ public function hidden(array $hidden) public function visible(array $visible) { $this->options['visible'] = $visible; - return $this; + + return $this->filter(function (&$result) { + $result = $this->dataVisibleFilter($result); + }, 'visible'); + } + + protected function dataVisibleFilter($result) + { + if (!empty($this->options['visible'])) { + foreach ($this->options['visible'] as $key) { + $array[] = $key; + } + $result = array_intersect_key($result, array_flip($array)); + } elseif (!empty($this->options['hidden'])) { + foreach ($this->options['hidden'] as $key) { + $array[] = $key; + } + $result = array_diff_key($result, array_flip($array)); + } + return $result; } /** @@ -187,7 +209,9 @@ public function withAttr($name, callable $callback = null) $this->options['with_attr'][$name] = $callback; } - return $this; + return $this->filter(function (&$result) { + $this->getResultAttr($result, $this->options['with_attr']); + }, 'with_attr'); } /** @@ -418,20 +442,7 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection return $this->model->toCollection(); } - // 检查动态获取器 - if (!empty($this->options['with_attr'])) { - foreach ($this->options['with_attr'] as $name => $val) { - if (strpos($name, '.')) { - [$relation, $field] = explode('.', $name); - - $withRelationAttr[$relation][$field] = $val; - unset($this->options['with_attr'][$name]); - } - } - } - - $withRelationAttr = $withRelationAttr ?? []; - + $withRelationAttr = $this->getWithRelationAttr(); foreach ($resultSet as $key => &$result) { // 数据转换为模型对象 $this->resultToModel($result, $this->options, true, $withRelationAttr); @@ -452,73 +463,46 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection } /** - * 查询数据转换为模型对象 + * 检查动态获取器 * @access protected - * @param array $result 查询数据 - * @param array $options 查询参数 - * @param bool $resultSet 是否为数据集查询 - * @param array $withRelationAttr 关联字段获取器 - * @return void + * @return array */ - protected function resultToModel(array &$result, array $options = [], bool $resultSet = false, array $withRelationAttr = []): void + protected function getWithRelationAttr(): array { - // 动态获取器 - if (!empty($options['with_attr']) && empty($withRelationAttr)) { - foreach ($options['with_attr'] as $name => $val) { + if (isset($this->options['with_relation_attr'])) { + return $this->options['with_relation_attr']; + } + + $withRelationAttr = []; + if (!empty($this->options['with_attr'])) { + foreach ($this->options['with_attr'] as $name => $val) { if (strpos($name, '.')) { [$relation, $field] = explode('.', $name); $withRelationAttr[$relation][$field] = $val; - unset($options['with_attr'][$name]); + unset($this->options['with_attr'][$name]); } } } - // JSON 数据处理 - if (!empty($options['json'])) { - $this->jsonResult($result, $options['json'], $options['json_assoc'], $withRelationAttr); - } - - $result = $this->model - ->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options)); - - // 动态获取器 - if (!empty($options['with_attr'])) { - $result->withAttribute($options['with_attr']); - } - - // 输出属性控制 - if (!empty($options['visible'])) { - $result->visible($options['visible']); - } elseif (!empty($options['hidden'])) { - $result->hidden($options['hidden']); - } - - if (!empty($options['append'])) { - $result->append($options['append']); - } - - // 关联查询 - if (!empty($options['relation'])) { - $result->relationQuery($options['relation'], $withRelationAttr); - } - - // 预载入查询 - if (!$resultSet && !empty($options['with'])) { - $result->eagerlyResult($result, $options['with'], $withRelationAttr, false, $options['with_cache'] ?? false); - } + $this->options['with_relation_attr'] = $withRelationAttr; + return $withRelationAttr; + } - // JOIN预载入查询 - if (!$resultSet && !empty($options['with_join'])) { - $result->eagerlyResult($result, $options['with_join'], $withRelationAttr, true, $options['with_cache'] ?? false); - } + /** + * 查询数据转换为模型对象 + * @access protected + * @param array $result 查询数据 + * @param array $options 查询参数 + * @param bool $resultSet 是否为数据集查询 + * @param array $withRelationAttr 关联字段获取器 + * @return void + */ + protected function resultToModel(array &$result, array $options = [], bool $resultSet = false, array $withRelationAttr = []): void + { + $options['with_relation_attr'] = $this->getWithRelationAttr(); - // 关联统计 - if (!empty($options['with_count'])) { - foreach ($options['with_count'] as $val) { - $result->relationCount($this, (array) $val[0], $val[1], $val[2], false); - } - } + $result = $this->model->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options), $options); } } diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index 77409d16..45dcf336 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -26,6 +26,23 @@ */ trait ResultOperation { + /** + * 设置数据处理 + * @access public + * @param callable $filter 数据处理Callable + * @param string $index 索引(唯一) + * @return $this + */ + public function filter(callable $filter, string $index = null) + { + if ($index) { + $this->options['filter'][$index] = $filter; + } else { + $this->options['filter'][] = $filter; + } + return $this; + } + /** * 是否允许返回空数据(或空模型) * @access public @@ -58,15 +75,9 @@ public function failException(bool $fail = true) */ protected function result(array &$result): void { - if (!empty($this->options['json'])) { - $this->jsonResult($result, $this->options['json'], true); - } - - if (!empty($this->options['with_attr'])) { - $this->getResultAttr($result, $this->options['with_attr']); + foreach ($this->options['filter'] as $filter) { + call_user_func($filter, $result); } - - $this->filterResult($result); } /** @@ -78,22 +89,8 @@ protected function result(array &$result): void */ protected function resultSet(array &$resultSet, bool $toCollection = true): void { - if (!empty($this->options['json'])) { - foreach ($resultSet as &$result) { - $this->jsonResult($result, $this->options['json'], true); - } - } - - if (!empty($this->options['with_attr'])) { - foreach ($resultSet as &$result) { - $this->getResultAttr($result, $this->options['with_attr']); - } - } - - if (!empty($this->options['visible']) || !empty($this->options['hidden'])) { - foreach ($resultSet as &$result) { - $this->filterResult($result); - } + foreach ($resultSet as &$result) { + $this->result($result); } // 返回Collection对象 @@ -102,28 +99,6 @@ protected function resultSet(array &$resultSet, bool $toCollection = true): void } } - /** - * 处理数据的可见和隐藏 - * @access protected - * @param array $result 查询数据 - * @return void - */ - protected function filterResult(&$result): void - { - $array = []; - if (!empty($this->options['visible'])) { - foreach ($this->options['visible'] as $key) { - $array[] = $key; - } - $result = array_intersect_key($result, array_flip($array)); - } elseif (!empty($this->options['hidden'])) { - foreach ($this->options['hidden'] as $key) { - $array[] = $key; - } - $result = array_diff_key($result, array_flip($array)); - } - } - /** * 使用获取器处理数据 * @access protected diff --git a/src/model/concern/Attribute.php b/src/model/concern/Attribute.php index 34cb59a4..272ad4d1 100644 --- a/src/model/concern/Attribute.php +++ b/src/model/concern/Attribute.php @@ -106,6 +106,12 @@ trait Attribute */ private $withAttr = []; + /** + * 数据处理 + * @var array + */ + private $filter = []; + /** * 获取模型对象的主键 * @access public @@ -177,6 +183,24 @@ public function readOnly(array $field) return $this; } + /** + * 设置模型数据处理 + * @access public + * @param callable $filter 数据处理Callable + * @param string $index 索引(唯一) + * @return $this + */ + public function filter(callable $filter, string $index = null) + { + if ($index) { + $this->filter[$index] = $filter; + } else { + $this->filter[] = $filter; + } + + return $this; + } + /** * 获取实际的字段名 * @access protected diff --git a/src/model/relation/BelongsToMany.php b/src/model/relation/BelongsToMany.php index 5f177c1d..55aba836 100644 --- a/src/model/relation/BelongsToMany.php +++ b/src/model/relation/BelongsToMany.php @@ -121,25 +121,37 @@ protected function newPivot(array $data = []): Pivot } /** - * 合成中间表模型 + * 解析中间表数据 * @access protected - * @param array|Collection|Paginator $models + * @param Model $model */ - protected function hydratePivot(iterable $models) + protected function getPivotData(Model $model) { - foreach ($models as $model) { - $pivot = []; + $pivot = []; - foreach ($model->getData() as $key => $val) { - if (strpos($key, '__')) { - [$name, $attr] = explode('__', $key, 2); + foreach ($model->getData() as $key => $val) { + if (strpos($key, '__')) { + [$name, $attr] = explode('__', $key, 2); - if ('pivot' == $name) { - $pivot[$attr] = $val; - unset($model->$key); - } + if ('pivot' == $name) { + $pivot[$attr] = $val; + unset($model->$key); } } + } + + return $pivot; + } + + /** + * 合成中间表模型 + * @access protected + * @param array|Collection|Paginator $models + */ + protected function hydratePivot(iterable $models) + { + foreach ($models as $model) { + $pivot = $this->getPivotData($model); $model->setRelation($this->pivotDataName, $this->newPivot($pivot)); } @@ -167,55 +179,6 @@ public function getRelation(array $subRelation = [], Closure $closure = null): C return $result; } - /** - * 重载select方法 - * @access public - * @param mixed $data - * @return Collection - */ - public function select($data = null): Collection - { - $this->baseQuery(); - $result = $this->query->select($data); - $this->hydratePivot($result); - - return $result; - } - - /** - * 重载paginate方法 - * @access public - * @param int|array $listRows - * @param int|bool $simple - * @return Paginator - */ - public function paginate($listRows = null, $simple = false): Paginator - { - $this->baseQuery(); - $result = $this->query->paginate($listRows, $simple); - $this->hydratePivot($result); - - return $result; - } - - /** - * 重载find方法 - * @access public - * @param mixed $data - * @return Model - */ - public function find($data = null) - { - $this->baseQuery(); - $result = $this->query->find($data); - - if ($result && !$result->isEmpty()) { - $this->hydratePivot([$result]); - } - - return $result; - } - /** * 根据关联条件查询当前模型 * @access public @@ -673,6 +636,11 @@ protected function baseQuery(): void $foreignKey = $this->foreignKey; $localKey = $this->localKey; + $this->model->filter(function ($result, $options) { + $pivot = $this->getPivotData($result); + $result->setRelation($this->pivotDataName, $this->newPivot($pivot)); + }); + // 关联查询 if (null === $this->parent->getKey()) { $condition = ['pivot.' . $localKey, 'exp', new Raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk())]; From 39a9390629de8a41374c5951f667185c2e3928f3 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Mon, 20 Dec 2021 22:04:15 +0800 Subject: [PATCH 06/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/BaseQuery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index c2fee3a7..962d8db1 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -1183,7 +1183,7 @@ public function parseOptions(): array $this->parseView($options); } - foreach (['data', 'order', 'join', 'union'] as $name) { + foreach (['data', 'order', 'join', 'union', 'filter'] as $name) { if (!isset($options[$name])) { $options[$name] = []; } From 92abd99342264d3c69100d7339d67491ad1917e8 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Mon, 20 Dec 2021 22:37:00 +0800 Subject: [PATCH 07/40] =?UTF-8?q?=E8=B0=83=E6=95=B4json=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model.php | 5 ----- src/db/BaseQuery.php | 4 ---- src/db/concern/ModelRelationQuery.php | 10 +++++++--- src/db/concern/ResultOperation.php | 2 ++ 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Model.php b/src/Model.php index 89d3b40c..17b030d4 100644 --- a/src/Model.php +++ b/src/Model.php @@ -244,11 +244,6 @@ public function __construct(array $data = []) } $this->filter(function ($result, $options) { - // JSON 数据处理 - if (!empty($options['json'])) { - $this->jsonResult($result, $options['json'], $options['json_assoc'], $options['with_relation_attr']); - } - // 动态获取器 if (!empty($options['with_attr'])) { $result->withAttribute($options['with_attr']); diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 962d8db1..88018b9f 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -869,10 +869,6 @@ public function json(array $json = [], bool $assoc = false) { $this->options['json'] = $json; $this->options['json_assoc'] = $assoc; - - return $this->filter(function (&$result) use ($json) { - $this->jsonResult($result, $json, true); - }, 'json'); } /** diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index e0d06319..e8f18e41 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -445,7 +445,7 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection $withRelationAttr = $this->getWithRelationAttr(); foreach ($resultSet as $key => &$result) { // 数据转换为模型对象 - $this->resultToModel($result, $this->options, true, $withRelationAttr); + $this->resultToModel($result, $this->options, true); } if (!empty($this->options['with'])) { @@ -495,13 +495,17 @@ protected function getWithRelationAttr(): array * @param array $result 查询数据 * @param array $options 查询参数 * @param bool $resultSet 是否为数据集查询 - * @param array $withRelationAttr 关联字段获取器 * @return void */ - protected function resultToModel(array &$result, array $options = [], bool $resultSet = false, array $withRelationAttr = []): void + protected function resultToModel(array &$result, array $options = [], bool $resultSet = false): void { $options['with_relation_attr'] = $this->getWithRelationAttr(); + // JSON 数据处理 + if (!empty($options['json'])) { + $this->jsonResult($result, $options['json'], $options['json_assoc'], $options['with_relation_attr']); + } + $result = $this->model->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options), $options); } diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index 45dcf336..06290655 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -75,6 +75,8 @@ public function failException(bool $fail = true) */ protected function result(array &$result): void { + $this->jsonResult($result, $this->options['json'], true); + foreach ($this->options['filter'] as $filter) { call_user_func($filter, $result); } From 0f3727e1bf65f932895f51804a734648bc542790 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Mon, 20 Dec 2021 22:41:57 +0800 Subject: [PATCH 08/40] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/BaseQuery.php | 4 ++-- src/db/concern/ResultOperation.php | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 88018b9f..368028e5 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -137,7 +137,7 @@ public function newQuery(): BaseQuery $query->name($this->name); } - if (isset($this->options['json'])) { + if (!empty($this->options['json'])) { $query->json($this->options['json'], $this->options['json_assoc']); } @@ -1179,7 +1179,7 @@ public function parseOptions(): array $this->parseView($options); } - foreach (['data', 'order', 'join', 'union', 'filter'] as $name) { + foreach (['data', 'order', 'join', 'union', 'filter', 'json'] as $name) { if (!isset($options[$name])) { $options[$name] = []; } diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index 06290655..bd9f0b61 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -75,7 +75,9 @@ public function failException(bool $fail = true) */ protected function result(array &$result): void { - $this->jsonResult($result, $this->options['json'], true); + if (!empty($this->options['json'])) { + $this->jsonResult($result, $this->options['json'], true); + } foreach ($this->options['filter'] as $filter) { call_user_func($filter, $result); From e95b0de15702f19becb62ffd21d94fe2c1ffed8f Mon Sep 17 00:00:00 2001 From: yunwuxin <448901948@qq.com> Date: Tue, 21 Dec 2021 13:19:30 +0800 Subject: [PATCH 09/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3sqlite=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8lock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/builder/Sqlite.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/db/builder/Sqlite.php b/src/db/builder/Sqlite.php index 40cab7f8..78a307d2 100644 --- a/src/db/builder/Sqlite.php +++ b/src/db/builder/Sqlite.php @@ -94,4 +94,16 @@ public function parseKey(Query $query, $key, bool $strict = false): string return $key; } + + /** + * 设置锁机制 + * @access protected + * @param Query $query 查询对象 + * @param bool|string $lock + * @return string + */ + protected function parseLock(Query $query, $lock = false): string + { + return ''; + } } From 28e79af00bdecbac18f078c9479123af2850cb71 Mon Sep 17 00:00:00 2001 From: yunwuxin <448901948@qq.com> Date: Tue, 21 Dec 2021 17:12:57 +0800 Subject: [PATCH 10/40] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E5=AD=97=E6=AE=B5=E7=B1=BB=E5=9E=8B=E4=B8=8D=E5=8C=BA?= =?UTF-8?q?=E5=88=86=E5=A4=A7=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/PDOConnection.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/db/PDOConnection.php b/src/db/PDOConnection.php index 1a3d4a2b..69bfbbc2 100644 --- a/src/db/PDOConnection.php +++ b/src/db/PDOConnection.php @@ -279,7 +279,7 @@ public function fieldCase(array $info): array */ protected function getFieldType(string $type): string { - if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) { + if (0 === stripos($type, 'set') || 0 === stripos($type, 'enum')) { $result = 'string'; } elseif (preg_match('/(double|float|decimal|real|numeric)/is', $type)) { $result = 'float'; @@ -287,11 +287,11 @@ protected function getFieldType(string $type): string $result = 'int'; } elseif (preg_match('/bool/is', $type)) { $result = 'bool'; - } elseif (0 === strpos($type, 'timestamp')) { + } elseif (0 === stripos($type, 'timestamp')) { $result = 'timestamp'; - } elseif (0 === strpos($type, 'datetime')) { + } elseif (0 === stripos($type, 'datetime')) { $result = 'datetime'; - } elseif (0 === strpos($type, 'date')) { + } elseif (0 === stripos($type, 'date')) { $result = 'date'; } else { $result = 'string'; From b74c97e44686a10f89344388c0ef9f743bb992d0 Mon Sep 17 00:00:00 2001 From: yunwuxin <448901948@qq.com> Date: Wed, 22 Dec 2021 13:40:58 +0800 Subject: [PATCH 11/40] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/BaseQuery.php | 2 +- src/db/concern/ResultOperation.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 368028e5..bfccb8c8 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -1125,7 +1125,7 @@ public function select($data = null): Collection * 查找单条记录 * @access public * @param mixed $data 查询数据 - * @return array|Model|null|static + * @return array|Model|null|static|mixed * @throws Exception * @throws ModelNotFoundException * @throws DataNotFoundException diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index bd9f0b61..05e6f3b0 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -149,7 +149,7 @@ protected function resultToEmpty() * 查找单条记录 不存在返回空数据(或者空模型) * @access public * @param mixed $data 数据 - * @return array|Model|static + * @return array|Model|static|mixed */ public function findOrEmpty($data = null) { @@ -221,7 +221,7 @@ public function selectOrFail($data = null) * 查找单条记录 如果不存在则抛出异常 * @access public * @param array|string|Query|Closure $data 数据 - * @return array|Model|static + * @return array|Model|static|mixed * @throws ModelNotFoundException * @throws DataNotFoundException */ From 06fcb0b3bfffb27ae8e4ee50a4383ddb724726be Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 22 Dec 2021 14:31:13 +0800 Subject: [PATCH 12/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3json=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/BaseQuery.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 368028e5..4e6a1a2e 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -869,6 +869,8 @@ public function json(array $json = [], bool $assoc = false) { $this->options['json'] = $json; $this->options['json_assoc'] = $assoc; + + return $this; } /** From 4b7e026d14eca4dec6eb7685adf0b363814a1d10 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 22 Dec 2021 14:44:57 +0800 Subject: [PATCH 13/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=A4=9A=E5=AF=B9?= =?UTF-8?q?=E5=A4=9A=E5=85=B3=E8=81=94=E4=B8=AD=E9=97=B4=E8=A1=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/relation/BelongsToMany.php | 50 ++++++++++++---------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/model/relation/BelongsToMany.php b/src/model/relation/BelongsToMany.php index 55aba836..491752d7 100644 --- a/src/model/relation/BelongsToMany.php +++ b/src/model/relation/BelongsToMany.php @@ -19,7 +19,6 @@ use think\Model; use think\model\Pivot; use think\model\Relation; -use think\Paginator; /** * 多对多关联类 @@ -123,38 +122,25 @@ protected function newPivot(array $data = []): Pivot /** * 解析中间表数据 * @access protected - * @param Model $model + * @param array $result */ - protected function getPivotData(Model $model) + protected function getPivotData(array $result): array { $pivot = []; - foreach ($model->getData() as $key => $val) { + foreach ($result as $key => $val) { if (strpos($key, '__')) { [$name, $attr] = explode('__', $key, 2); if ('pivot' == $name) { $pivot[$attr] = $val; - unset($model->$key); + unset($result[$key]); } } } - return $pivot; - } - - /** - * 合成中间表模型 - * @access protected - * @param array|Collection|Paginator $models - */ - protected function hydratePivot(iterable $models) - { - foreach ($models as $model) { - $pivot = $this->getPivotData($model); - - $model->setRelation($this->pivotDataName, $this->newPivot($pivot)); - } + $result[$this->pivotDataName] = $this->newPivot($pivot); + return $result; } /** @@ -170,13 +156,9 @@ public function getRelation(array $subRelation = [], Closure $closure = null): C $closure($this->getClosureType($closure)); } - $result = $this->relation($subRelation) + return $this->relation($subRelation) ->select() ->setParent(clone $this->parent); - - $this->hydratePivot($result); - - return $result; } /** @@ -636,9 +618,21 @@ protected function baseQuery(): void $foreignKey = $this->foreignKey; $localKey = $this->localKey; - $this->model->filter(function ($result, $options) { - $pivot = $this->getPivotData($result); - $result->setRelation($this->pivotDataName, $this->newPivot($pivot)); + $this->query->filter(function (&$result) { + $pivot = []; + + foreach ($result as $key => $val) { + if (strpos($key, '__')) { + [$name, $attr] = explode('__', $key, 2); + + if ('pivot' == $name) { + $pivot[$attr] = $val; + unset($result[$key]); + } + } + } + + $result[$this->pivotDataName] = $this->newPivot($pivot); }); // 关联查询 From 6ada0dd595627d786458812295c26ce5b2d89442 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 22 Dec 2021 22:49:48 +0800 Subject: [PATCH 14/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=A4=9A=E5=AF=B9?= =?UTF-8?q?=E5=A4=9A=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/concern/ModelRelationQuery.php | 30 +++++-------------------- src/db/concern/ResultOperation.php | 12 ++++++++++ src/model/relation/BelongsToMany.php | 32 ++++----------------------- 3 files changed, 22 insertions(+), 52 deletions(-) diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index e8f18e41..87c95cc8 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -60,10 +60,7 @@ public function getModel() public function hidden(array $hidden) { $this->options['hidden'] = $hidden; - - return $this->filter(function (&$result) { - $result = $this->dataVisibleFilter($result); - }, 'visible'); + return $this; } /** @@ -75,26 +72,7 @@ public function hidden(array $hidden) public function visible(array $visible) { $this->options['visible'] = $visible; - - return $this->filter(function (&$result) { - $result = $this->dataVisibleFilter($result); - }, 'visible'); - } - - protected function dataVisibleFilter($result) - { - if (!empty($this->options['visible'])) { - foreach ($this->options['visible'] as $key) { - $array[] = $key; - } - $result = array_intersect_key($result, array_flip($array)); - } elseif (!empty($this->options['hidden'])) { - foreach ($this->options['hidden'] as $key) { - $array[] = $key; - } - $result = array_diff_key($result, array_flip($array)); - } - return $result; + return $this; } /** @@ -506,6 +484,10 @@ protected function resultToModel(array &$result, array $options = [], bool $resu $this->jsonResult($result, $options['json'], $options['json_assoc'], $options['with_relation_attr']); } + foreach ($this->options['filter'] as $filter) { + call_user_func($filter, $result); + } + $result = $this->model->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options), $options); } diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index 05e6f3b0..247542dd 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -82,6 +82,18 @@ protected function result(array &$result): void foreach ($this->options['filter'] as $filter) { call_user_func($filter, $result); } + + if (!empty($this->options['visible'])) { + foreach ($this->options['visible'] as $key) { + $array[] = $key; + } + $result = array_intersect_key($result, array_flip($array)); + } elseif (!empty($this->options['hidden'])) { + foreach ($this->options['hidden'] as $key) { + $array[] = $key; + } + $result = array_diff_key($result, array_flip($array)); + } } /** diff --git a/src/model/relation/BelongsToMany.php b/src/model/relation/BelongsToMany.php index 491752d7..75eab1e2 100644 --- a/src/model/relation/BelongsToMany.php +++ b/src/model/relation/BelongsToMany.php @@ -119,30 +119,6 @@ protected function newPivot(array $data = []): Pivot } } - /** - * 解析中间表数据 - * @access protected - * @param array $result - */ - protected function getPivotData(array $result): array - { - $pivot = []; - - foreach ($result as $key => $val) { - if (strpos($key, '__')) { - [$name, $attr] = explode('__', $key, 2); - - if ('pivot' == $name) { - $pivot[$attr] = $val; - unset($result[$key]); - } - } - } - - $result[$this->pivotDataName] = $this->newPivot($pivot); - return $result; - } - /** * 延迟获取关联数据 * @access public @@ -618,21 +594,21 @@ protected function baseQuery(): void $foreignKey = $this->foreignKey; $localKey = $this->localKey; - $this->query->filter(function (&$result) { + $this->query->getModel()->filter(function ($result, $options) { $pivot = []; - foreach ($result as $key => $val) { + foreach ($result->getData() as $key => $val) { if (strpos($key, '__')) { [$name, $attr] = explode('__', $key, 2); if ('pivot' == $name) { $pivot[$attr] = $val; - unset($result[$key]); + unset($result->$key); } } } - $result[$this->pivotDataName] = $this->newPivot($pivot); + $result->setRelation($this->pivotDataName, $this->newPivot($pivot)); }); // 关联查询 From 5ce2242d869dc84bcebc612c616e9251121981f1 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 22 Dec 2021 23:18:29 +0800 Subject: [PATCH 15/40] =?UTF-8?q?=E8=B0=83=E6=95=B4db=E7=B1=BBfilter?= =?UTF-8?q?=E5=A4=84=E7=90=86=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/concern/ModelRelationQuery.php | 2 +- src/db/concern/ResultOperation.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index 87c95cc8..41ab320e 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -485,7 +485,7 @@ protected function resultToModel(array &$result, array $options = [], bool $resu } foreach ($this->options['filter'] as $filter) { - call_user_func($filter, $result); + $result = call_user_func($filter, $result); } $result = $this->model->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options), $options); diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index 247542dd..eaccfcd4 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -80,7 +80,7 @@ protected function result(array &$result): void } foreach ($this->options['filter'] as $filter) { - call_user_func($filter, $result); + $result = call_user_func($filter, $result); } if (!empty($this->options['visible'])) { From 39be9523f88c250ab7e6a8b2680ba9a95ba1194e Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Thu, 23 Dec 2021 23:23:02 +0800 Subject: [PATCH 16/40] =?UTF-8?q?=E6=94=B9=E8=BF=9Bdb=E7=B1=BBhidden=20vis?= =?UTF-8?q?ible=20append=20=E6=96=B9=E6=B3=95=E5=A4=84=E7=90=86=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model.php | 11 -------- src/db/BaseQuery.php | 6 +++++ src/db/concern/ModelRelationQuery.php | 36 --------------------------- src/db/concern/ResultOperation.php | 12 --------- 4 files changed, 6 insertions(+), 59 deletions(-) diff --git a/src/Model.php b/src/Model.php index 17b030d4..8f2318dc 100644 --- a/src/Model.php +++ b/src/Model.php @@ -249,17 +249,6 @@ public function __construct(array $data = []) $result->withAttribute($options['with_attr']); } - // 输出属性控制 - if (!empty($options['visible'])) { - $result->visible($options['visible']); - } elseif (!empty($options['hidden'])) { - $result->hidden($options['hidden']); - } - - if (!empty($options['append'])) { - $result->append($options['append']); - } - // 关联查询 if (!empty($options['relation'])) { $result->relationQuery($options['relation'], $options['with_relation_attr']); diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index ba7620ae..157e196d 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -106,6 +106,12 @@ public function __call(string $method, array $args) $name = Str::snake(substr($method, 5)); array_unshift($args, $name); return call_user_func_array([$this, 'where'], $args); + } elseif ($this->model && in_array($method, ['hidden', 'visible', 'append'])) { + // 调用模型类方法 + $this->model->filter(function ($model, $options) use ($method, $args) { + call_user_func_array([$model, $method], $args); + }); + return $this; } elseif ($this->model && method_exists($this->model, 'scope' . $method)) { // 动态调用命名范围 $method = 'scope' . $method; diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index 41ab320e..645eea25 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -51,42 +51,6 @@ public function getModel() return $this->model; } - /** - * 设置需要隐藏的输出属性 - * @access public - * @param array $hidden 需要隐藏的字段名 - * @return $this - */ - public function hidden(array $hidden) - { - $this->options['hidden'] = $hidden; - return $this; - } - - /** - * 设置需要输出的属性 - * @access public - * @param array $visible 需要输出的属性 - * @return $this - */ - public function visible(array $visible) - { - $this->options['visible'] = $visible; - return $this; - } - - /** - * 设置需要追加输出的属性 - * @access public - * @param array $append 需要追加的属性 - * @return $this - */ - public function append(array $append) - { - $this->options['append'] = $append; - return $this; - } - /** * 添加查询范围 * @access public diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index eaccfcd4..d95edd6c 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -82,18 +82,6 @@ protected function result(array &$result): void foreach ($this->options['filter'] as $filter) { $result = call_user_func($filter, $result); } - - if (!empty($this->options['visible'])) { - foreach ($this->options['visible'] as $key) { - $array[] = $key; - } - $result = array_intersect_key($result, array_flip($array)); - } elseif (!empty($this->options['hidden'])) { - foreach ($this->options['hidden'] as $key) { - $array[] = $key; - } - $result = array_diff_key($result, array_flip($array)); - } } /** From 6a977dfe730a9738729abfa612044f3cd1822d9a Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Fri, 24 Dec 2021 23:42:41 +0800 Subject: [PATCH 17/40] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E5=85=B3=E8=81=94?= =?UTF-8?q?=E7=9A=84=E8=BD=AF=E5=88=A0=E9=99=A4=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/concern/ModelRelationQuery.php | 19 ++++++++++++++++ src/model/concern/SoftDelete.php | 31 +++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index 645eea25..daac3c0b 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -455,4 +455,23 @@ protected function resultToModel(array &$result, array $options = [], bool $resu $result = $this->model->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options), $options); } + /** + * 查询软删除数据 + * @access public + * @return Query + */ + public function withTrashed() + { + return $this->model ? $this->model->queryWithTrashed() : $this; + } + + /** + * 只查询软删除数据 + * @access public + * @return Query + */ + public function onlyTrashed() + { + return $this->model ? $this->model->queryOnlyTrashed() : $this; + } } diff --git a/src/model/concern/SoftDelete.php b/src/model/concern/SoftDelete.php index 8d76bb07..117f1ef7 100644 --- a/src/model/concern/SoftDelete.php +++ b/src/model/concern/SoftDelete.php @@ -55,6 +55,16 @@ public static function withTrashed(): Query return $model->withTrashedData(true)->db(); } + /** + * 查询软删除数据 + * @access public + * @return Query + */ + public function queryWithTrashed(): Query + { + return $this->withTrashedData(true)->db(); + } + /** * 是否包含软删除数据 * @access protected @@ -86,6 +96,23 @@ public static function onlyTrashed(): Query return $model->db(); } + /** + * 只查询软删除数据 + * @access public + * @return Query + */ + public function queryOnlyTrashed(): Query + { + $field = $this->getDeleteTimeField(true); + + if ($field) { + return $this->db() + ->useSoftDelete($field, $this->getWithTrashedExp()); + } + + return $this->db(); + } + /** * 获取软删除数据的查询条件 * @access protected @@ -152,12 +179,12 @@ public function delete(): bool public static function destroy($data, bool $force = false): bool { // 传入空值(包括空字符串和空数组)的时候不会做任何的数据删除操作,但传入0则是有效的 - if(empty($data) && $data !== 0){ + if (empty($data) && 0 !== $data) { return false; } // 仅当强制删除时包含软删除数据 $model = (new static()); - if($force){ + if ($force) { $model->withTrashedData(true); } $query = $model->db(false); From 77716982094b8108abe2b54d42f03866f083b7ec Mon Sep 17 00:00:00 2001 From: yunwuxin <448901948@qq.com> Date: Tue, 28 Dec 2021 11:41:41 +0800 Subject: [PATCH 18/40] =?UTF-8?q?=E5=AE=8C=E5=96=84=E8=8E=B7=E5=8F=96sql?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E5=AD=97=E7=AC=A6=E8=BD=AC=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/PDOConnection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/PDOConnection.php b/src/db/PDOConnection.php index 69bfbbc2..40ac99e9 100644 --- a/src/db/PDOConnection.php +++ b/src/db/PDOConnection.php @@ -1273,7 +1273,7 @@ public function getRealSql(string $sql, array $bind = []): string $type = is_array($val) ? $val[1] : PDO::PARAM_STR; if (self::PARAM_FLOAT == $type || PDO::PARAM_STR == $type) { - $value = '\'' . addslashes($value) . '\''; + $value = '\'' . addcslashes($value, "'") . '\''; } elseif (PDO::PARAM_INT == $type && '' === $value) { $value = '0'; } From 51ec287abdb99521dbbc66526b114f2e32b8fff4 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 29 Dec 2021 13:48:27 +0800 Subject: [PATCH 19/40] =?UTF-8?q?=E6=94=B9=E8=BF=9BwithAttr=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model.php | 9 --------- src/db/concern/ModelRelationQuery.php | 4 ++-- src/db/concern/ResultOperation.php | 6 ++++-- src/model/Collection.php | 2 +- src/model/concern/Attribute.php | 4 ++-- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/Model.php b/src/Model.php index 8f2318dc..cb4d9133 100644 --- a/src/Model.php +++ b/src/Model.php @@ -244,11 +244,6 @@ public function __construct(array $data = []) } $this->filter(function ($result, $options) { - // 动态获取器 - if (!empty($options['with_attr'])) { - $result->withAttribute($options['with_attr']); - } - // 关联查询 if (!empty($options['relation'])) { $result->relationQuery($options['relation'], $options['with_relation_attr']); @@ -1075,10 +1070,6 @@ public function __call($method, $args) return call_user_func_array(static::$macro[static::class][$method]->bindTo($this, static::class), $args); } - if ('withattr' == strtolower($method)) { - return call_user_func_array([$this, 'withAttribute'], $args); - } - return call_user_func_array([$this->db(), $method], $args); } diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index daac3c0b..ffec2fb0 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -151,8 +151,8 @@ public function withAttr($name, callable $callback = null) $this->options['with_attr'][$name] = $callback; } - return $this->filter(function (&$result) { - $this->getResultAttr($result, $this->options['with_attr']); + return $this->filter(function ($result) { + return $this->getResultAttr($result, $this->options['with_attr']); }, 'with_attr'); } diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index d95edd6c..d8b5a4c9 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -108,9 +108,9 @@ protected function resultSet(array &$resultSet, bool $toCollection = true): void * @access protected * @param array $result 查询数据 * @param array $withAttr 字段获取器 - * @return void + * @return array */ - protected function getResultAttr(array &$result, array $withAttr = []): void + protected function getResultAttr(array $result, array $withAttr = []): array { foreach ($withAttr as $name => $closure) { $name = Str::snake($name); @@ -126,6 +126,8 @@ protected function getResultAttr(array &$result, array $withAttr = []): void $result[$name] = $closure($result[$name] ?? null, $result); } } + + return $result; } /** diff --git a/src/model/Collection.php b/src/model/Collection.php index f017e328..c8ff385a 100644 --- a/src/model/Collection.php +++ b/src/model/Collection.php @@ -157,7 +157,7 @@ public function setParent(Model $parent) public function withAttr($name, $callback = null) { $this->each(function (Model $model) use ($name, $callback) { - $model->withAttribute($name, $callback); + $model->withAttr($name, $callback); }); return $this; diff --git a/src/model/concern/Attribute.php b/src/model/concern/Attribute.php index 272ad4d1..a48c74ef 100644 --- a/src/model/concern/Attribute.php +++ b/src/model/concern/Attribute.php @@ -657,11 +657,11 @@ protected function readTransform($value, $type) * @param callable $callback 闭包获取器 * @return $this */ - public function withAttribute($name, callable $callback = null) + public function withAttr($name, callable $callback = null) { if (is_array($name)) { foreach ($name as $key => $val) { - $this->withAttribute($key, $val); + $this->withAttr($key, $val); } } else { $name = $this->getRealFieldName($name); From 326e962bd880b6b42ab4efd1c2a7346b5fd0873a Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Fri, 31 Dec 2021 14:06:24 +0800 Subject: [PATCH 20/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=85=B3=E8=81=94?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E9=9B=86=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model.php | 4 ++-- src/db/concern/ModelRelationQuery.php | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Model.php b/src/Model.php index cb4d9133..ead8611d 100644 --- a/src/Model.php +++ b/src/Model.php @@ -250,12 +250,12 @@ public function __construct(array $data = []) } // 预载入查询 - if (!empty($options['with'])) { + if (empty($optios['is_resultSet']) && !empty($options['with'])) { $result->eagerlyResult($result, $options['with'], $options['with_relation_attr'], false, $options['with_cache'] ?? false); } // JOIN预载入查询 - if (!empty($options['with_join'])) { + if (empty($optios['is_resultSet']) && !empty($options['with_join'])) { $result->eagerlyResult($result, $options['with_join'], $options['with_relation_attr'], true, $options['with_cache'] ?? false); } diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index ffec2fb0..3213f755 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -442,6 +442,7 @@ protected function getWithRelationAttr(): array protected function resultToModel(array &$result, array $options = [], bool $resultSet = false): void { $options['with_relation_attr'] = $this->getWithRelationAttr(); + $options['is_resultSet'] = $resultSet; // JSON 数据处理 if (!empty($options['json'])) { From 8861b60f0876447b9ba8ad0ad4c6997f82767dac Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Fri, 31 Dec 2021 14:09:31 +0800 Subject: [PATCH 21/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3parseWhereExp=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/concern/WhereQuery.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/db/concern/WhereQuery.php b/src/db/concern/WhereQuery.php index d2deb03c..ef845f5d 100644 --- a/src/db/concern/WhereQuery.php +++ b/src/db/concern/WhereQuery.php @@ -361,9 +361,7 @@ protected function parseWhereExp(string $logic, $field, $op, $condition, array $ $field = $this->options['via'] . '.' . $field; } - if ($field instanceof Raw) { - return $this->whereRaw($field, is_array($op) ? $op : [], $logic); - } elseif ($strict) { + if ($strict) { // 使用严格模式查询 if ('=' == $op) { $where = $this->whereEq($field, $condition); From e69151fba9dd21f86e392a0ae208825904d6d49a Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Fri, 31 Dec 2021 14:12:13 +0800 Subject: [PATCH 22/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model.php b/src/Model.php index ead8611d..ac591924 100644 --- a/src/Model.php +++ b/src/Model.php @@ -250,12 +250,12 @@ public function __construct(array $data = []) } // 预载入查询 - if (empty($optios['is_resultSet']) && !empty($options['with'])) { + if (empty($options['is_resultSet']) && !empty($options['with'])) { $result->eagerlyResult($result, $options['with'], $options['with_relation_attr'], false, $options['with_cache'] ?? false); } // JOIN预载入查询 - if (empty($optios['is_resultSet']) && !empty($options['with_join'])) { + if (empty($options['is_resultSet']) && !empty($options['with_join'])) { $result->eagerlyResult($result, $options['with_join'], $options['with_relation_attr'], true, $options['with_cache'] ?? false); } From c6712643961a1b73f5641ecebf5e8b5596cdeb4e Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Sun, 2 Jan 2022 14:41:28 +0800 Subject: [PATCH 23/40] =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=A8=A1=E5=9E=8Bfilte?= =?UTF-8?q?r=E6=96=B9=E6=B3=95=20=E7=BB=9F=E4=B8=80=E8=B0=83=E7=94=A8Db?= =?UTF-8?q?=E7=B1=BBfilter=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model.php | 58 +++++++++++++++------------ src/db/concern/ModelRelationQuery.php | 7 ++-- src/db/concern/ResultOperation.php | 3 +- src/model/concern/Attribute.php | 24 ----------- 4 files changed, 38 insertions(+), 54 deletions(-) diff --git a/src/Model.php b/src/Model.php index ac591924..f05c1e5d 100644 --- a/src/Model.php +++ b/src/Model.php @@ -243,29 +243,6 @@ public function __construct(array $data = []) } } - $this->filter(function ($result, $options) { - // 关联查询 - if (!empty($options['relation'])) { - $result->relationQuery($options['relation'], $options['with_relation_attr']); - } - - // 预载入查询 - if (empty($options['is_resultSet']) && !empty($options['with'])) { - $result->eagerlyResult($result, $options['with'], $options['with_relation_attr'], false, $options['with_cache'] ?? false); - } - - // JOIN预载入查询 - if (empty($options['is_resultSet']) && !empty($options['with_join'])) { - $result->eagerlyResult($result, $options['with_join'], $options['with_relation_attr'], true, $options['with_cache'] ?? false); - } - - // 关联统计 - if (!empty($options['with_count'])) { - foreach ($options['with_count'] as $val) { - $result->relationCount($this, (array) $val[0], $val[1], $val[2], false); - } - } - }); // 执行初始化操作 $this->initialize(); } @@ -309,15 +286,44 @@ public function newInstance(array $data = [], $where = null, array $options = [] $model->setUpdateWhere($where); // 查询数据处理 - foreach ($this->filter as $filter) { - call_user_func_array($filter, [$model, $options]); - } + $model->filterData($options); $model->trigger('AfterRead'); return $model; } + /** + * 处理模型数据 + * @access protected + * @param array $options 查询参数 + * @return void + */ + protected function filterData(array $options): void + { + // 关联查询 + if (!empty($options['relation'])) { + $this->relationQuery($options['relation'], $options['with_relation_attr']); + } + + // 预载入查询 + if (empty($options['is_resultSet']) && !empty($options['with'])) { + $this->eagerlyResult($result, $options['with'], $options['with_relation_attr'], false, $options['with_cache'] ?? false); + } + + // JOIN预载入查询 + if (empty($options['is_resultSet']) && !empty($options['with_join'])) { + $this->eagerlyResult($result, $options['with_join'], $options['with_relation_attr'], true, $options['with_cache'] ?? false); + } + + // 关联统计 + if (!empty($options['with_count'])) { + foreach ($options['with_count'] as $val) { + $this->relationCount($this, (array) $val[0], $val[1], $val[2], false); + } + } + } + /** * 设置模型的更新条件 * @access protected diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index 3213f755..6a74e4f3 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -449,11 +449,12 @@ protected function resultToModel(array &$result, array $options = [], bool $resu $this->jsonResult($result, $options['json'], $options['json_assoc'], $options['with_relation_attr']); } + $result = $this->model->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options), $options); + + // 模型数据处理 foreach ($this->options['filter'] as $filter) { - $result = call_user_func($filter, $result); + call_user_func($filter, $result); } - - $result = $this->model->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options), $options); } /** diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index d8b5a4c9..a6aac3eb 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -27,7 +27,7 @@ trait ResultOperation { /** - * 设置数据处理 + * 设置数据处理(支持模型) * @access public * @param callable $filter 数据处理Callable * @param string $index 索引(唯一) @@ -79,6 +79,7 @@ protected function result(array &$result): void $this->jsonResult($result, $this->options['json'], true); } + // 查询数据处理 foreach ($this->options['filter'] as $filter) { $result = call_user_func($filter, $result); } diff --git a/src/model/concern/Attribute.php b/src/model/concern/Attribute.php index a48c74ef..fb19fd11 100644 --- a/src/model/concern/Attribute.php +++ b/src/model/concern/Attribute.php @@ -106,12 +106,6 @@ trait Attribute */ private $withAttr = []; - /** - * 数据处理 - * @var array - */ - private $filter = []; - /** * 获取模型对象的主键 * @access public @@ -183,24 +177,6 @@ public function readOnly(array $field) return $this; } - /** - * 设置模型数据处理 - * @access public - * @param callable $filter 数据处理Callable - * @param string $index 索引(唯一) - * @return $this - */ - public function filter(callable $filter, string $index = null) - { - if ($index) { - $this->filter[$index] = $filter; - } else { - $this->filter[] = $filter; - } - - return $this; - } - /** * 获取实际的字段名 * @access protected From c914df37a6f70aaef265a629ac889436f5b80cd8 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Mon, 3 Jan 2022 12:50:16 +0800 Subject: [PATCH 24/40] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model.php | 34 ------ src/db/BaseQuery.php | 18 ++- src/db/concern/ModelRelationQuery.php | 161 ++++++++++++++++---------- src/db/concern/ResultOperation.php | 20 +--- src/model/concern/Attribute.php | 11 ++ 5 files changed, 126 insertions(+), 118 deletions(-) diff --git a/src/Model.php b/src/Model.php index f05c1e5d..b3a99ea1 100644 --- a/src/Model.php +++ b/src/Model.php @@ -285,45 +285,11 @@ public function newInstance(array $data = [], $where = null, array $options = [] $model->setUpdateWhere($where); - // 查询数据处理 - $model->filterData($options); - $model->trigger('AfterRead'); return $model; } - /** - * 处理模型数据 - * @access protected - * @param array $options 查询参数 - * @return void - */ - protected function filterData(array $options): void - { - // 关联查询 - if (!empty($options['relation'])) { - $this->relationQuery($options['relation'], $options['with_relation_attr']); - } - - // 预载入查询 - if (empty($options['is_resultSet']) && !empty($options['with'])) { - $this->eagerlyResult($result, $options['with'], $options['with_relation_attr'], false, $options['with_cache'] ?? false); - } - - // JOIN预载入查询 - if (empty($options['is_resultSet']) && !empty($options['with_join'])) { - $this->eagerlyResult($result, $options['with_join'], $options['with_relation_attr'], true, $options['with_cache'] ?? false); - } - - // 关联统计 - if (!empty($options['with_count'])) { - foreach ($options['with_count'] as $val) { - $this->relationCount($this, (array) $val[0], $val[1], $val[2], false); - } - } - } - /** * 设置模型的更新条件 * @access protected diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 157e196d..99114825 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -876,7 +876,19 @@ public function json(array $json = [], bool $assoc = false) $this->options['json'] = $json; $this->options['json_assoc'] = $assoc; - return $this; + if ($this->model) { + return $this->filter(function ($result) use ($json, $assoc) { + if (!empty($json)) { + $this->jsonModelResult($result, $json, $assoc); + } + }); + } + + return $this->filter(function ($result) use ($json) { + if (!empty($json)) { + $this->jsonResult($result, $json); + } + }); } /** @@ -1187,7 +1199,7 @@ public function parseOptions(): array $this->parseView($options); } - foreach (['data', 'order', 'join', 'union', 'filter', 'json'] as $name) { + foreach (['data', 'order', 'join', 'union', 'filter', 'json', 'with_relation_attr'] as $name) { if (!isset($options[$name])) { $options[$name] = []; } @@ -1197,7 +1209,7 @@ public function parseOptions(): array $options['strict'] = $this->connection->getConfig('fields_strict'); } - foreach (['master', 'lock', 'fetch_sql', 'array', 'distinct', 'procedure'] as $name) { + foreach (['master', 'lock', 'fetch_sql', 'array', 'distinct', 'procedure', 'with_cache'] as $name) { if (!isset($options[$name])) { $options[$name] = false; } diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index 6a74e4f3..e21724cf 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -94,11 +94,13 @@ public function scope($scope, ...$args) */ public function relation(array $relation) { - if (!empty($relation)) { - $this->options['relation'] = $relation; + if (empty($this->model) || empty($relation)) { + return $this; } - return $this; + return $this->filter(function ($result, $options) use ($relation) { + $result->relationQuery($relation, $this->options['with_relation_attr']); + }); } /** @@ -145,15 +147,30 @@ public function withSearch($fields, $data = [], string $prefix = '') */ public function withAttr($name, callable $callback = null) { + if (empty($this->model)) { + if (is_array($name)) { + $this->options['with_attr'] = $name; + } else { + $this->options['with_attr'][$name] = $callback; + } + return $this->filter(function ($result) { + return $this->getResultAttr($result, $this->options['with_attr']); + }, 'with_attr'); + } + if (is_array($name)) { - $this->options['with_attr'] = $name; + foreach ($name as $key => $val) { + if (strpos($key, '.')) { + [$relation, $field] = explode('.', $key); + + $this->options['with_relation_attr'][$relation][$field] = $val; + } + } } else { - $this->options['with_attr'][$name] = $callback; + $this->options['with_relation_attr'][$name] = $callback; } - return $this->filter(function ($result) { - return $this->getResultAttr($result, $this->options['with_attr']); - }, 'with_attr'); + return $this; } /** @@ -164,11 +181,17 @@ public function withAttr($name, callable $callback = null) */ public function with($with) { - if (!empty($with)) { - $this->options['with'] = (array) $with; + if (empty($this->model) || empty($with)) { + return $this; } - return $this; + $with = (array) $with; + $this->options['with'] = $with; + return $this->filter(function ($result) use ($with) { + if (empty($this->options['is_resultSet'])) { + $result->eagerlyResult($with, $this->options['with_relation_attr'], false, $this->options['with_cache'] ?? false); + } + }, 'with'); } /** @@ -180,7 +203,7 @@ public function with($with) */ public function withJoin($with, string $joinType = '') { - if (empty($with)) { + if (empty($this->model) || empty($with)) { return $this; } @@ -212,10 +235,14 @@ public function withJoin($with, string $joinType = '') } $this->via(); - $this->options['with_join'] = $with; - return $this; + return $this->filter(function ($result) use ($with) { + // JOIN预载入查询 + if (empty($this->options['is_resultSet'])) { + $result->eagerlyResult($with, $this->options['with_relation_attr'], true, $this->options['with_cache'] ?? false); + } + }, 'with_join'); } /** @@ -229,16 +256,24 @@ public function withJoin($with, string $joinType = '') */ protected function withAggregate($relations, string $aggregate = 'count', $field = '*', bool $subQuery = true) { + if (empty($this->model)) { + return $this; + } + if (!$subQuery) { - $this->options['with_count'][] = [$relations, $aggregate, $field]; - } else { - if (!isset($this->options['field'])) { - $this->field('*'); - } + $this->options['with_aggregate'][] = [$relations, $aggregate, $field]; + return $this->filter(function ($result) use ($withAggregate) { + foreach ($this->options['with_aggregate'] as $val) { + $result->relationCount($this, (array) $val[0], $val[1], $val[2], false); + } + }); + } - $this->model->relationCount($this, (array) $relations, $aggregate, $field, true); + if (!isset($this->options['field'])) { + $this->field('*'); } + $this->model->relationCount($this, (array) $relations, $aggregate, $field, true); return $this; } @@ -253,6 +288,10 @@ protected function withAggregate($relations, string $aggregate = 'count', $field */ public function withCache($relation = true, $key = true, $expire = null, string $tag = null) { + if (empty($this->model)) { + return $this; + } + if (false === $relation || false === $key || !$this->getConnection()->getCache()) { return $this; } @@ -372,6 +411,34 @@ public function hasWhere(string $relation, $where = [], string $fields = '*', st return $this->model->hasWhere($relation, $where, $fields, $joinType, $this); } + /** + * JSON字段数据转换 + * @access protected + * @param Model $result 查询数据 + * @param array $json JSON字段 + * @param bool $assoc 是否转换为数组 + * @return void + */ + protected function jsonModelResult(Model $result, array $json = [], bool $assoc = false): void + { + $withRelationAttr = $this->options['with_relation_attr']; + foreach ($json as $name) { + if (!isset($result->$name)) { + continue; + } + + $jsonData = json_decode($result->getData($name), true); + + if (isset($withRelationAttr[$name])) { + foreach ($withRelationAttr[$name] as $key => $closure) { + $jsonData[$key] = $closure($jsonData[$key] ?? null, $jsonData); + } + } + + $result->set($name, !$assoc ? (object) $jsonData : $jsonData); + } + } + /** * 查询数据转换为模型数据集对象 * @access protected @@ -384,77 +451,45 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection return $this->model->toCollection(); } - $withRelationAttr = $this->getWithRelationAttr(); + $this->options['is_resultSet'] = true; foreach ($resultSet as $key => &$result) { // 数据转换为模型对象 - $this->resultToModel($result, $this->options, true); + $this->resultToModel($result); } if (!empty($this->options['with'])) { // 预载入 - $result->eagerlyResultSet($resultSet, $this->options['with'], $withRelationAttr, false, $this->options['with_cache'] ?? false); + $result->eagerlyResultSet($resultSet, $this->options['with'], $this->options['with_relation_attr'], false, $this->options['with_cache'] ?? false); } if (!empty($this->options['with_join'])) { // 预载入 - $result->eagerlyResultSet($resultSet, $this->options['with_join'], $withRelationAttr, true, $this->options['with_cache'] ?? false); + $result->eagerlyResultSet($resultSet, $this->options['with_join'], $this->options['with_relation_attr'], true, $this->options['with_cache'] ?? false); } // 模型数据集转换 return $this->model->toCollection($resultSet); } - /** - * 检查动态获取器 - * @access protected - * @return array - */ - protected function getWithRelationAttr(): array - { - if (isset($this->options['with_relation_attr'])) { - return $this->options['with_relation_attr']; - } - - $withRelationAttr = []; - if (!empty($this->options['with_attr'])) { - foreach ($this->options['with_attr'] as $name => $val) { - if (strpos($name, '.')) { - [$relation, $field] = explode('.', $name); - - $withRelationAttr[$relation][$field] = $val; - unset($this->options['with_attr'][$name]); - } - } - } - - $this->options['with_relation_attr'] = $withRelationAttr; - return $withRelationAttr; - } - /** * 查询数据转换为模型对象 * @access protected * @param array $result 查询数据 - * @param array $options 查询参数 - * @param bool $resultSet 是否为数据集查询 * @return void */ - protected function resultToModel(array &$result, array $options = [], bool $resultSet = false): void + protected function resultToModel(array &$result): void { - $options['with_relation_attr'] = $this->getWithRelationAttr(); - $options['is_resultSet'] = $resultSet; + $options = $this->options; - // JSON 数据处理 - if (!empty($options['json'])) { - $this->jsonResult($result, $options['json'], $options['json_assoc'], $options['with_relation_attr']); - } - - $result = $this->model->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options), $options); + $result = $this->model->newInstance($result, !empty($options['is_resultSet']) ? null : $this->getModelUpdateCondition($options), $options); // 模型数据处理 foreach ($this->options['filter'] as $filter) { - call_user_func($filter, $result); + call_user_func_array($filter, [$result, $options]); } + + // 刷新原始数据 + $result->refreshOrigin(); } /** diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index a6aac3eb..2a6f1477 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -75,13 +75,9 @@ public function failException(bool $fail = true) */ protected function result(array &$result): void { - if (!empty($this->options['json'])) { - $this->jsonResult($result, $this->options['json'], true); - } - // 查询数据处理 foreach ($this->options['filter'] as $filter) { - $result = call_user_func($filter, $result); + $result = call_user_func_array($filter, [$result, $this->options]); } } @@ -164,11 +160,9 @@ public function findOrEmpty($data = null) * @access protected * @param array $result 查询数据 * @param array $json JSON字段 - * @param bool $assoc 是否转换为数组 - * @param array $withRelationAttr 关联获取器 * @return void */ - protected function jsonResult(array &$result, array $json = [], bool $assoc = false, array $withRelationAttr = []): void + protected function jsonResult(array &$result, array $json = []): void { foreach ($json as $name) { if (!isset($result[$name])) { @@ -176,16 +170,6 @@ protected function jsonResult(array &$result, array $json = [], bool $assoc = fa } $result[$name] = json_decode($result[$name], true); - - if (isset($withRelationAttr[$name])) { - foreach ($withRelationAttr[$name] as $key => $closure) { - $result[$name][$key] = $closure($result[$name][$key] ?? null, $result[$name]); - } - } - - if (!$assoc) { - $result[$name] = (object) $result[$name]; - } } } diff --git a/src/model/concern/Attribute.php b/src/model/concern/Attribute.php index fb19fd11..e9e5f9c6 100644 --- a/src/model/concern/Attribute.php +++ b/src/model/concern/Attribute.php @@ -250,6 +250,17 @@ public function appendData(array $data, bool $set = false) return $this; } + /** + * 刷新对象原始数据(为当前数据) + * @access public + * @return $this + */ + public function refreshOrigin() + { + $this->origin = $this->data; + return $this; + } + /** * 获取对象原始数据 如果不存在指定字段返回null * @access public From 5260c10ba8f15df644a39f8aa1b87a33f22e5405 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Mon, 3 Jan 2022 13:16:30 +0800 Subject: [PATCH 25/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/concern/RelationShip.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/model/concern/RelationShip.php b/src/model/concern/RelationShip.php index 33c1b890..dd8346c1 100644 --- a/src/model/concern/RelationShip.php +++ b/src/model/concern/RelationShip.php @@ -298,7 +298,7 @@ public function eagerlyResultSet(array &$resultSet, array $relations, array $wit * @param mixed $cache 关联缓存 * @return void */ - public function eagerlyResult(Model $result, array $relations, array $withRelationAttr = [], bool $join = false, $cache = false): void + public function eagerlyResult(array $relations, array $withRelationAttr = [], bool $join = false, $cache = false): void { foreach ($relations as $key => $relation) { $subRelation = []; @@ -333,7 +333,7 @@ public function eagerlyResult(Model $result, array $relations, array $withRelati $relationCache = $cache[$relationName] ?? []; } - $relationResult->eagerlyResult($result, $relationName, $subRelation, $closure, $relationCache, $join); + $relationResult->eagerlyResult($this, $relationName, $subRelation, $closure, $relationCache, $join); } } From ec19283cfe85b2a1a9290757ed6e3d1d978046ff Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Mon, 3 Jan 2022 13:25:32 +0800 Subject: [PATCH 26/40] =?UTF-8?q?=E6=B3=A8=E9=87=8A=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/concern/RelationShip.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/model/concern/RelationShip.php b/src/model/concern/RelationShip.php index dd8346c1..8faadf47 100644 --- a/src/model/concern/RelationShip.php +++ b/src/model/concern/RelationShip.php @@ -291,7 +291,6 @@ public function eagerlyResultSet(array &$resultSet, array $relations, array $wit /** * 预载入关联查询 返回模型对象 * @access public - * @param Model $result 数据对象 * @param array $relations 关联 * @param array $withRelationAttr 关联获取器 * @param bool $join 是否为JOIN方式 From 2edd4b2d1b91394151e3b8a3195ad566f6c065e2 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Mon, 3 Jan 2022 23:23:11 +0800 Subject: [PATCH 27/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3value=E5=92=8Ccolumn?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/BaseQuery.php | 14 ++++++++++---- src/db/concern/ModelRelationQuery.php | 20 +++++++++++--------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 99114825..0188bc1a 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -269,7 +269,9 @@ public function value(string $field, $default = null) $result = $this->connection->value($this, $field, $default); $array[$field] = $result; - $this->result($array); + + $this->jsonResult($array, $this->options['json']); + $array = $this->getResultAttr($array, $this->options['with_attr']); return $array[$field]; } @@ -284,8 +286,12 @@ public function value(string $field, $default = null) public function column($field, string $key = ''): array { $result = $this->connection->column($this, $field, $key); + if (count($result) != count($result, 1)) { - $this->resultSet($result, false); + foreach ($result as &$val) { + $this->jsonResult($val, $this->options['json']); + $val = $this->getResultAttr($val, $this->options['with_attr']); + } } return $result; } @@ -1170,7 +1176,7 @@ public function find($data = null) if (!empty($this->model)) { // 返回模型对象 - $this->resultToModel($result, $this->options); + $this->resultToModel($result); } else { $this->result($result); } @@ -1199,7 +1205,7 @@ public function parseOptions(): array $this->parseView($options); } - foreach (['data', 'order', 'join', 'union', 'filter', 'json', 'with_relation_attr'] as $name) { + foreach (['data', 'order', 'join', 'union', 'filter', 'json', 'with_attr'] as $name) { if (!isset($options[$name])) { $options[$name] = []; } diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index e21724cf..33128363 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -99,7 +99,7 @@ public function relation(array $relation) } return $this->filter(function ($result, $options) use ($relation) { - $result->relationQuery($relation, $this->options['with_relation_attr']); + $result->relationQuery($relation, $this->options['with_attr']); }); } @@ -163,14 +163,16 @@ public function withAttr($name, callable $callback = null) if (strpos($key, '.')) { [$relation, $field] = explode('.', $key); - $this->options['with_relation_attr'][$relation][$field] = $val; + $this->options['with_attr'][$relation][$field] = $val; } } } else { - $this->options['with_relation_attr'][$name] = $callback; + $this->options['with_attr'][$name] = $callback; } - return $this; + return $this->filter(function ($result) { + $result->withAttr($this->options['with_attr']); + }, 'with_attr'); } /** @@ -189,7 +191,7 @@ public function with($with) $this->options['with'] = $with; return $this->filter(function ($result) use ($with) { if (empty($this->options['is_resultSet'])) { - $result->eagerlyResult($with, $this->options['with_relation_attr'], false, $this->options['with_cache'] ?? false); + $result->eagerlyResult($with, $this->options['with_attr'], false, $this->options['with_cache'] ?? false); } }, 'with'); } @@ -240,7 +242,7 @@ public function withJoin($with, string $joinType = '') return $this->filter(function ($result) use ($with) { // JOIN预载入查询 if (empty($this->options['is_resultSet'])) { - $result->eagerlyResult($with, $this->options['with_relation_attr'], true, $this->options['with_cache'] ?? false); + $result->eagerlyResult($with, $this->options['with_attr'], true, $this->options['with_cache'] ?? false); } }, 'with_join'); } @@ -421,7 +423,7 @@ public function hasWhere(string $relation, $where = [], string $fields = '*', st */ protected function jsonModelResult(Model $result, array $json = [], bool $assoc = false): void { - $withRelationAttr = $this->options['with_relation_attr']; + $withRelationAttr = $this->options['with_attr']; foreach ($json as $name) { if (!isset($result->$name)) { continue; @@ -459,12 +461,12 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection if (!empty($this->options['with'])) { // 预载入 - $result->eagerlyResultSet($resultSet, $this->options['with'], $this->options['with_relation_attr'], false, $this->options['with_cache'] ?? false); + $result->eagerlyResultSet($resultSet, $this->options['with'], $this->options['with_attr'], false, $this->options['with_cache'] ?? false); } if (!empty($this->options['with_join'])) { // 预载入 - $result->eagerlyResultSet($resultSet, $this->options['with_join'], $this->options['with_relation_attr'], true, $this->options['with_cache'] ?? false); + $result->eagerlyResultSet($resultSet, $this->options['with_join'], $this->options['with_attr'], true, $this->options['with_cache'] ?? false); } // 模型数据集转换 From 91be961b091a7409d6bfdc83abb704e7f1c1d60b Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Tue, 4 Jan 2022 09:16:01 +0800 Subject: [PATCH 28/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=99=A8=E5=AF=B9json=E6=95=B0=E6=8D=AE=E7=9A=84=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/BaseQuery.php | 21 ++++++++++---- src/db/concern/ModelRelationQuery.php | 40 ++++++++++++--------------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 0188bc1a..f6f751f0 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -270,8 +270,13 @@ public function value(string $field, $default = null) $array[$field] = $result; - $this->jsonResult($array, $this->options['json']); - $array = $this->getResultAttr($array, $this->options['with_attr']); + if (!empty($this->options['json'])) { + $this->jsonResult($array, $this->options['json']); + } + + if (!empty($this->options['with_attr'])) { + $array = $this->getResultAttr($array, $this->options['with_attr']); + } return $array[$field]; } @@ -289,10 +294,16 @@ public function column($field, string $key = ''): array if (count($result) != count($result, 1)) { foreach ($result as &$val) { - $this->jsonResult($val, $this->options['json']); - $val = $this->getResultAttr($val, $this->options['with_attr']); + if (!empty($this->options['json'])) { + $this->jsonResult($val, $this->options['json']); + } + + if (!empty($this->options['with_attr'])) { + $val = $this->getResultAttr($val, $this->options['with_attr']); + } } } + return $result; } @@ -1205,7 +1216,7 @@ public function parseOptions(): array $this->parseView($options); } - foreach (['data', 'order', 'join', 'union', 'filter', 'json', 'with_attr'] as $name) { + foreach (['data', 'order', 'join', 'union', 'filter', 'json', 'with_attr', 'with_relatioin_attr'] as $name) { if (!isset($options[$name])) { $options[$name] = []; } diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index 33128363..c4dee980 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -99,7 +99,7 @@ public function relation(array $relation) } return $this->filter(function ($result, $options) use ($relation) { - $result->relationQuery($relation, $this->options['with_attr']); + $result->relationQuery($relation, $this->options['with_relatioin_attr']); }); } @@ -141,33 +141,26 @@ public function withSearch($fields, $data = [], string $prefix = '') /** * 设置数据字段获取器 * @access public - * @param string|array $name 字段名 - * @param callable $callback 闭包获取器 + * @param string $name 字段名 + * @param callable $callback 闭包获取器 * @return $this */ - public function withAttr($name, callable $callback = null) + public function withAttr(string $name, callable $callback) { if (empty($this->model)) { - if (is_array($name)) { - $this->options['with_attr'] = $name; - } else { - $this->options['with_attr'][$name] = $callback; - } + $this->options['with_attr'][$name] = $callback; + return $this->filter(function ($result) { return $this->getResultAttr($result, $this->options['with_attr']); }, 'with_attr'); } - if (is_array($name)) { - foreach ($name as $key => $val) { - if (strpos($key, '.')) { - [$relation, $field] = explode('.', $key); + $this->options['with_attr'][$name] = $callback; - $this->options['with_attr'][$relation][$field] = $val; - } - } - } else { - $this->options['with_attr'][$name] = $callback; + if (strpos($name, '.')) { + [$relation, $field] = explode('.', $name); + + $this->options['with_relatioin_attr'][$relation][$field] = $callback; } return $this->filter(function ($result) { @@ -187,11 +180,12 @@ public function with($with) return $this; } - $with = (array) $with; + $with = (array) $with; + $this->options['with'] = $with; return $this->filter(function ($result) use ($with) { if (empty($this->options['is_resultSet'])) { - $result->eagerlyResult($with, $this->options['with_attr'], false, $this->options['with_cache'] ?? false); + $result->eagerlyResult($with, $this->options['with_relatioin_attr'], false, $this->options['with_cache'] ?? false); } }, 'with'); } @@ -242,7 +236,7 @@ public function withJoin($with, string $joinType = '') return $this->filter(function ($result) use ($with) { // JOIN预载入查询 if (empty($this->options['is_resultSet'])) { - $result->eagerlyResult($with, $this->options['with_attr'], true, $this->options['with_cache'] ?? false); + $result->eagerlyResult($with, $this->options['with_relatioin_attr'], true, $this->options['with_cache'] ?? false); } }, 'with_join'); } @@ -461,12 +455,12 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection if (!empty($this->options['with'])) { // 预载入 - $result->eagerlyResultSet($resultSet, $this->options['with'], $this->options['with_attr'], false, $this->options['with_cache'] ?? false); + $result->eagerlyResultSet($resultSet, $this->options['with'], $this->options['with_relatioin_attr'], false, $this->options['with_cache'] ?? false); } if (!empty($this->options['with_join'])) { // 预载入 - $result->eagerlyResultSet($resultSet, $this->options['with_join'], $this->options['with_attr'], true, $this->options['with_cache'] ?? false); + $result->eagerlyResultSet($resultSet, $this->options['with_join'], $this->options['with_relatioin_attr'], true, $this->options['with_cache'] ?? false); } // 模型数据集转换 From 856649f1fad01a3cf227fec790f2fa1b63869ac7 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Tue, 4 Jan 2022 11:22:16 +0800 Subject: [PATCH 29/40] =?UTF-8?q?=E6=94=B9=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/concern/ModelRelationQuery.php | 30 ++++++++++++++++++--------- src/model/concern/Attribute.php | 4 ++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index c4dee980..99fcc55a 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -141,18 +141,17 @@ public function withSearch($fields, $data = [], string $prefix = '') /** * 设置数据字段获取器 * @access public - * @param string $name 字段名 - * @param callable $callback 闭包获取器 + * @param string|array $name 字段名 + * @param callable $callback 闭包获取器 * @return $this */ - public function withAttr(string $name, callable $callback) + public function withAttr($name, callable $callback = null) { - if (empty($this->model)) { - $this->options['with_attr'][$name] = $callback; - - return $this->filter(function ($result) { - return $this->getResultAttr($result, $this->options['with_attr']); - }, 'with_attr'); + if (is_array($name)) { + foreach ($name as $key => $val) { + $this->withAttr($key, $val); + } + return $this; } $this->options['with_attr'][$name] = $callback; @@ -160,7 +159,18 @@ public function withAttr(string $name, callable $callback) if (strpos($name, '.')) { [$relation, $field] = explode('.', $name); - $this->options['with_relatioin_attr'][$relation][$field] = $callback; + if (!empty($this->options['json']) && in_array($relation, $this->options['json'])) { + + } else { + $this->options['with_relatioin_attr'][$relation][$field] = $callback; + unset($this->options['with_attr'][$name]); + } + } + + if (empty($this->model)) { + return $this->filter(function ($result) { + return $this->getResultAttr($result, $this->options['with_attr']); + }, 'with_attr'); } return $this->filter(function ($result) { diff --git a/src/model/concern/Attribute.php b/src/model/concern/Attribute.php index e9e5f9c6..9201f903 100644 --- a/src/model/concern/Attribute.php +++ b/src/model/concern/Attribute.php @@ -542,6 +542,10 @@ protected function getValue(string $name, $value, $relation = false) */ protected function getJsonValue($name, $value) { + if (is_null($value)) { + return $value; + } + foreach ($this->withAttr[$name] as $key => $closure) { if ($this->jsonAssoc) { $value[$key] = $closure($value[$key], $value); From 85045c460c26f1770056dfe183ba84efc3fad446 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 5 Jan 2022 21:28:44 +0800 Subject: [PATCH 30/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3mongo=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/BaseQuery.php | 2 +- src/db/Mongo.php | 6 +----- src/db/concern/ModelRelationQuery.php | 12 ++++++------ 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index f6f751f0..6cd6b015 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -1216,7 +1216,7 @@ public function parseOptions(): array $this->parseView($options); } - foreach (['data', 'order', 'join', 'union', 'filter', 'json', 'with_attr', 'with_relatioin_attr'] as $name) { + foreach (['data', 'order', 'join', 'union', 'filter', 'json', 'with_attr', 'with_relation_attr'] as $name) { if (!isset($options[$name])) { $options[$name] = []; } diff --git a/src/db/Mongo.php b/src/db/Mongo.php index 5e8a09a5..cf6e9c4c 100644 --- a/src/db/Mongo.php +++ b/src/db/Mongo.php @@ -630,7 +630,7 @@ public function parseOptions(): array $options['table'] = $this->getTable(); } - foreach (['where', 'data'] as $name) { + foreach (['where', 'data', 'projection', 'filter', 'json', 'with_attr', 'with_relation_attr'] as $name) { if (!isset($options[$name])) { $options[$name] = []; } @@ -649,10 +649,6 @@ public function parseOptions(): array $options['modifiers'] = $modifiers; } - if (!isset($options['projection'])) { - $options['projection'] = []; - } - if (!isset($options['typeMap'])) { $options['typeMap'] = $this->getConfig('type_map'); } diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index 99fcc55a..2821bf39 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -99,7 +99,7 @@ public function relation(array $relation) } return $this->filter(function ($result, $options) use ($relation) { - $result->relationQuery($relation, $this->options['with_relatioin_attr']); + $result->relationQuery($relation, $this->options['with_relation_attr']); }); } @@ -162,7 +162,7 @@ public function withAttr($name, callable $callback = null) if (!empty($this->options['json']) && in_array($relation, $this->options['json'])) { } else { - $this->options['with_relatioin_attr'][$relation][$field] = $callback; + $this->options['with_relation_attr'][$relation][$field] = $callback; unset($this->options['with_attr'][$name]); } } @@ -195,7 +195,7 @@ public function with($with) $this->options['with'] = $with; return $this->filter(function ($result) use ($with) { if (empty($this->options['is_resultSet'])) { - $result->eagerlyResult($with, $this->options['with_relatioin_attr'], false, $this->options['with_cache'] ?? false); + $result->eagerlyResult($with, $this->options['with_relation_attr'], false, $this->options['with_cache'] ?? false); } }, 'with'); } @@ -246,7 +246,7 @@ public function withJoin($with, string $joinType = '') return $this->filter(function ($result) use ($with) { // JOIN预载入查询 if (empty($this->options['is_resultSet'])) { - $result->eagerlyResult($with, $this->options['with_relatioin_attr'], true, $this->options['with_cache'] ?? false); + $result->eagerlyResult($with, $this->options['with_relation_attr'], true, $this->options['with_cache'] ?? false); } }, 'with_join'); } @@ -465,12 +465,12 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection if (!empty($this->options['with'])) { // 预载入 - $result->eagerlyResultSet($resultSet, $this->options['with'], $this->options['with_relatioin_attr'], false, $this->options['with_cache'] ?? false); + $result->eagerlyResultSet($resultSet, $this->options['with'], $this->options['with_relation_attr'], false, $this->options['with_cache'] ?? false); } if (!empty($this->options['with_join'])) { // 预载入 - $result->eagerlyResultSet($resultSet, $this->options['with_join'], $this->options['with_relatioin_attr'], true, $this->options['with_cache'] ?? false); + $result->eagerlyResultSet($resultSet, $this->options['with_join'], $this->options['with_relation_attr'], true, $this->options['with_cache'] ?? false); } // 模型数据集转换 From ffaa727afe6b3f0b8acb1d5854d6bd8f71a80b20 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 5 Jan 2022 21:53:53 +0800 Subject: [PATCH 31/40] =?UTF-8?q?=E6=94=B9=E8=BF=9Bhidden=20visible=20appe?= =?UTF-8?q?nd=E6=96=B9=E6=B3=95=E7=9A=84=E5=A4=84=E7=90=86=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/BaseQuery.php | 6 ---- src/db/concern/ModelRelationQuery.php | 45 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 6cd6b015..50761207 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -106,12 +106,6 @@ public function __call(string $method, array $args) $name = Str::snake(substr($method, 5)); array_unshift($args, $name); return call_user_func_array([$this, 'where'], $args); - } elseif ($this->model && in_array($method, ['hidden', 'visible', 'append'])) { - // 调用模型类方法 - $this->model->filter(function ($model, $options) use ($method, $args) { - call_user_func_array([$model, $method], $args); - }); - return $this; } elseif ($this->model && method_exists($this->model, 'scope' . $method)) { // 动态调用命名范围 $method = 'scope' . $method; diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index 2821bf39..a23803c7 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -51,6 +51,45 @@ public function getModel() return $this->model; } + /** + * 设置需要隐藏的输出属性 + * @access public + * @param array $hidden 属性列表 + * @return $this + */ + public function hidden(array $hidden = []) + { + $this->options['hidden'] = $hidden; + + return $this; + } + + /** + * 设置需要输出的属性 + * @access public + * @param array $visible + * @return $this + */ + public function visible(array $visible = []) + { + $this->options['visible'] = $visible; + + return $this; + } + + /** + * 设置需要附加的输出属性 + * @access public + * @param array $append 属性列表 + * @return $this + */ + public function append(array $append = []) + { + $this->options['append'] = $append; + + return $this; + } + /** * 添加查询范围 * @access public @@ -494,6 +533,12 @@ protected function resultToModel(array &$result): void call_user_func_array($filter, [$result, $options]); } + foreach (['hidden', 'visible', 'append'] as $name) { + if (!empty($this->options[$name])) { + $result->$name($this->options[$name]); + } + } + // 刷新原始数据 $result->refreshOrigin(); } From 17accf90d16f892e0e8129a5ccb9ef59e1b40356 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 5 Jan 2022 22:14:07 +0800 Subject: [PATCH 32/40] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/concern/ModelRelationQuery.php | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index a23803c7..ae1aea42 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -466,7 +466,7 @@ public function hasWhere(string $relation, $where = [], string $fields = '*', st */ protected function jsonModelResult(Model $result, array $json = [], bool $assoc = false): void { - $withRelationAttr = $this->options['with_attr']; + $withAttr = $this->options['with_attr']; foreach ($json as $name) { if (!isset($result->$name)) { continue; @@ -474,8 +474,8 @@ protected function jsonModelResult(Model $result, array $json = [], bool $assoc $jsonData = json_decode($result->getData($name), true); - if (isset($withRelationAttr[$name])) { - foreach ($withRelationAttr[$name] as $key => $closure) { + if (isset($withAttr[$name])) { + foreach ($withAttr[$name] as $key => $closure) { $jsonData[$key] = $closure($jsonData[$key] ?? null, $jsonData); } } @@ -502,14 +502,11 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection $this->resultToModel($result); } - if (!empty($this->options['with'])) { - // 预载入 - $result->eagerlyResultSet($resultSet, $this->options['with'], $this->options['with_relation_attr'], false, $this->options['with_cache'] ?? false); - } - - if (!empty($this->options['with_join'])) { - // 预载入 - $result->eagerlyResultSet($resultSet, $this->options['with_join'], $this->options['with_relation_attr'], true, $this->options['with_cache'] ?? false); + foreach (['with', 'with_join'] as $with) { + // 关联预载入 + if (!empty($this->options[$with])) { + $result->eagerlyResultSet($resultSet, $this->options[$with], $this->options['with_relation_attr'], false, $this->options['with_cache'] ?? false); + } } // 模型数据集转换 @@ -524,13 +521,11 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection */ protected function resultToModel(array &$result): void { - $options = $this->options; - - $result = $this->model->newInstance($result, !empty($options['is_resultSet']) ? null : $this->getModelUpdateCondition($options), $options); + $result = $this->model->newInstance($result, !empty($this->options['is_resultSet']) ? null : $this->getModelUpdateCondition($this->options), $this->options); // 模型数据处理 foreach ($this->options['filter'] as $filter) { - call_user_func_array($filter, [$result, $options]); + call_user_func_array($filter, [$result, $this->options]); } foreach (['hidden', 'visible', 'append'] as $name) { From 091ad5e023c15fcce4ceaea2f3814bdf71045cde Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Thu, 6 Jan 2022 10:48:16 +0800 Subject: [PATCH 33/40] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/BaseQuery.php | 33 +------- src/db/concern/ModelRelationQuery.php | 105 +++++++++++++++----------- src/db/concern/ResultOperation.php | 23 ++++-- 3 files changed, 81 insertions(+), 80 deletions(-) diff --git a/src/db/BaseQuery.php b/src/db/BaseQuery.php index 50761207..cccd8ef8 100644 --- a/src/db/BaseQuery.php +++ b/src/db/BaseQuery.php @@ -263,14 +263,7 @@ public function value(string $field, $default = null) $result = $this->connection->value($this, $field, $default); $array[$field] = $result; - - if (!empty($this->options['json'])) { - $this->jsonResult($array, $this->options['json']); - } - - if (!empty($this->options['with_attr'])) { - $array = $this->getResultAttr($array, $this->options['with_attr']); - } + $this->result($array); return $array[$field]; } @@ -287,15 +280,7 @@ public function column($field, string $key = ''): array $result = $this->connection->column($this, $field, $key); if (count($result) != count($result, 1)) { - foreach ($result as &$val) { - if (!empty($this->options['json'])) { - $this->jsonResult($val, $this->options['json']); - } - - if (!empty($this->options['with_attr'])) { - $val = $this->getResultAttr($val, $this->options['with_attr']); - } - } + $this->resultSet($result, false); } return $result; @@ -887,19 +872,7 @@ public function json(array $json = [], bool $assoc = false) $this->options['json'] = $json; $this->options['json_assoc'] = $assoc; - if ($this->model) { - return $this->filter(function ($result) use ($json, $assoc) { - if (!empty($json)) { - $this->jsonModelResult($result, $json, $assoc); - } - }); - } - - return $this->filter(function ($result) use ($json) { - if (!empty($json)) { - $this->jsonResult($result, $json); - } - }); + return $this; } /** diff --git a/src/db/concern/ModelRelationQuery.php b/src/db/concern/ModelRelationQuery.php index ae1aea42..0015a24a 100644 --- a/src/db/concern/ModelRelationQuery.php +++ b/src/db/concern/ModelRelationQuery.php @@ -137,9 +137,8 @@ public function relation(array $relation) return $this; } - return $this->filter(function ($result, $options) use ($relation) { - $result->relationQuery($relation, $this->options['with_relation_attr']); - }); + $this->options['relation'] = $relation; + return $this; } /** @@ -206,15 +205,7 @@ public function withAttr($name, callable $callback = null) } } - if (empty($this->model)) { - return $this->filter(function ($result) { - return $this->getResultAttr($result, $this->options['with_attr']); - }, 'with_attr'); - } - - return $this->filter(function ($result) { - $result->withAttr($this->options['with_attr']); - }, 'with_attr'); + return $this; } /** @@ -229,14 +220,8 @@ public function with($with) return $this; } - $with = (array) $with; - - $this->options['with'] = $with; - return $this->filter(function ($result) use ($with) { - if (empty($this->options['is_resultSet'])) { - $result->eagerlyResult($with, $this->options['with_relation_attr'], false, $this->options['with_cache'] ?? false); - } - }, 'with'); + $this->options['with'] = (array) $with; + return $this; } /** @@ -282,12 +267,7 @@ public function withJoin($with, string $joinType = '') $this->via(); $this->options['with_join'] = $with; - return $this->filter(function ($result) use ($with) { - // JOIN预载入查询 - if (empty($this->options['is_resultSet'])) { - $result->eagerlyResult($with, $this->options['with_relation_attr'], true, $this->options['with_cache'] ?? false); - } - }, 'with_join'); + return $this; } /** @@ -306,12 +286,8 @@ protected function withAggregate($relations, string $aggregate = 'count', $field } if (!$subQuery) { - $this->options['with_aggregate'][] = [$relations, $aggregate, $field]; - return $this->filter(function ($result) use ($withAggregate) { - foreach ($this->options['with_aggregate'] as $val) { - $result->relationCount($this, (array) $val[0], $val[1], $val[2], false); - } - }); + $this->options['with_aggregate'][] = [(array) $relations, $aggregate, $field]; + return $this; } if (!isset($this->options['field'])) { @@ -459,20 +435,18 @@ public function hasWhere(string $relation, $where = [], string $fields = '*', st /** * JSON字段数据转换 * @access protected - * @param Model $result 查询数据 - * @param array $json JSON字段 - * @param bool $assoc 是否转换为数组 + * @param array $result 查询数据 * @return void */ - protected function jsonModelResult(Model $result, array $json = [], bool $assoc = false): void + protected function jsonModelResult(array &$result): void { $withAttr = $this->options['with_attr']; - foreach ($json as $name) { - if (!isset($result->$name)) { + foreach ($this->options['json'] as $name) { + if (!isset($result[$name])) { continue; } - $jsonData = json_decode($result->getData($name), true); + $jsonData = json_decode($result[$name], true); if (isset($withAttr[$name])) { foreach ($withAttr[$name] as $key => $closure) { @@ -480,7 +454,7 @@ protected function jsonModelResult(Model $result, array $json = [], bool $assoc } } - $result->set($name, !$assoc ? (object) $jsonData : $jsonData); + $result[$name] = !$this->options['json_assoc'] ? (object) $jsonData : $jsonData; } } @@ -497,6 +471,7 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection } $this->options['is_resultSet'] = true; + foreach ($resultSet as $key => &$result) { // 数据转换为模型对象 $this->resultToModel($result); @@ -505,7 +480,13 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection foreach (['with', 'with_join'] as $with) { // 关联预载入 if (!empty($this->options[$with])) { - $result->eagerlyResultSet($resultSet, $this->options[$with], $this->options['with_relation_attr'], false, $this->options['with_cache'] ?? false); + $result->eagerlyResultSet( + $resultSet, + $this->options[$with], + $this->options['with_relation_attr'], + 'with_join' == $with ? true : false, + $this->options['with_cache'] ?? false + ); } } @@ -521,13 +502,53 @@ protected function resultSetToModelCollection(array $resultSet): ModelCollection */ protected function resultToModel(array &$result): void { - $result = $this->model->newInstance($result, !empty($this->options['is_resultSet']) ? null : $this->getModelUpdateCondition($this->options), $this->options); + // JSON数据处理 + if (!empty($this->options['json'])) { + $this->jsonModelResult($result); + } + + $result = $this->model->newInstance( + $result, + !empty($this->options['is_resultSet']) ? null : $this->getModelUpdateCondition($this->options), + $this->options + ); // 模型数据处理 foreach ($this->options['filter'] as $filter) { call_user_func_array($filter, [$result, $this->options]); } + // 关联查询 + if (!empty($this->options['relation'])) { + $result->relationQuery($this->options['relation'], $this->options['with_relation_attr']); + } + + // 关联预载入查询 + if (empty($this->options['is_resultSet'])) { + foreach (['with', 'with_join'] as $with) { + if (!empty($this->options[$with])) { + $result->eagerlyResult( + $this->options[$with], + $this->options['with_relation_attr'], + 'with_join' == $with ? true : false, + $this->options['with_cache'] ?? false + ); + } + } + } + + // 关联统计查询 + if (!empty($this->options['with_aggregate'])) { + foreach ($this->options['with_aggregate'] as $val) { + $result->relationCount($this, $val[0], $val[1], $val[2], false); + } + } + + // 动态获取器 + if (!empty($this->options['with_attr'])) { + $result->withAttr($this->options['with_attr']); + } + foreach (['hidden', 'visible', 'append'] as $name) { if (!empty($this->options[$name])) { $result->$name($this->options[$name]); diff --git a/src/db/concern/ResultOperation.php b/src/db/concern/ResultOperation.php index 2a6f1477..ea269163 100644 --- a/src/db/concern/ResultOperation.php +++ b/src/db/concern/ResultOperation.php @@ -75,10 +75,20 @@ public function failException(bool $fail = true) */ protected function result(array &$result): void { + // JSON数据处理 + if (!empty($this->options['json'])) { + $this->jsonResult($result); + } + // 查询数据处理 foreach ($this->options['filter'] as $filter) { $result = call_user_func_array($filter, [$result, $this->options]); } + + // 获取器 + if (!empty($this->options['with_attr'])) { + $this->getResultAttr($result, $this->options['with_attr']); + } } /** @@ -105,9 +115,9 @@ protected function resultSet(array &$resultSet, bool $toCollection = true): void * @access protected * @param array $result 查询数据 * @param array $withAttr 字段获取器 - * @return array + * @return void */ - protected function getResultAttr(array $result, array $withAttr = []): array + protected function getResultAttr(array &$result, array $withAttr = []): void { foreach ($withAttr as $name => $closure) { $name = Str::snake($name); @@ -123,8 +133,6 @@ protected function getResultAttr(array $result, array $withAttr = []): array $result[$name] = $closure($result[$name] ?? null, $result); } } - - return $result; } /** @@ -158,13 +166,12 @@ public function findOrEmpty($data = null) /** * JSON字段数据转换 * @access protected - * @param array $result 查询数据 - * @param array $json JSON字段 + * @param array $result 查询数据 * @return void */ - protected function jsonResult(array &$result, array $json = []): void + protected function jsonResult(array &$result): void { - foreach ($json as $name) { + foreach ($this->options['json'] as $name) { if (!isset($result[$name])) { continue; } From 874c34e368d154c954b25c977acf5401536cabd2 Mon Sep 17 00:00:00 2001 From: yunwuxin <448901948@qq.com> Date: Tue, 11 Jan 2022 17:33:42 +0800 Subject: [PATCH 34/40] =?UTF-8?q?=E5=AE=8C=E5=96=84sqlite=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/builder/Sqlite.php | 24 ++++++++++++++---------- src/db/connector/Sqlite.php | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/db/builder/Sqlite.php b/src/db/builder/Sqlite.php index 78a307d2..ff17c5d6 100644 --- a/src/db/builder/Sqlite.php +++ b/src/db/builder/Sqlite.php @@ -24,8 +24,8 @@ class Sqlite extends Builder /** * limit * @access public - * @param Query $query 查询对象 - * @param mixed $limit + * @param Query $query 查询对象 + * @param mixed $limit * @return string */ public function parseLimit(Query $query, string $limit): string @@ -47,7 +47,7 @@ public function parseLimit(Query $query, string $limit): string /** * 随机排序 * @access protected - * @param Query $query 查询对象 + * @param Query $query 查询对象 * @return string */ protected function parseRand(Query $query): string @@ -58,9 +58,9 @@ protected function parseRand(Query $query): string /** * 字段和表名处理 * @access public - * @param Query $query 查询对象 - * @param mixed $key 字段名 - * @param bool $strict 严格检测 + * @param Query $query 查询对象 + * @param mixed $key 字段名 + * @param bool $strict 严格检测 * @return string */ public function parseKey(Query $query, $key, bool $strict = false): string @@ -73,7 +73,7 @@ public function parseKey(Query $query, $key, bool $strict = false): string $key = trim($key); - if (strpos($key, '.')) { + if (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) { [$table, $key] = explode('.', $key, 2); $alias = $query->getOptions('alias'); @@ -88,8 +88,12 @@ public function parseKey(Query $query, $key, bool $strict = false): string } } + if ('*' != $key && !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { + $key = '`' . $key . '`'; + } + if (isset($table)) { - $key = $table . '.' . $key; + $key = '`' . $table . '`.' . $key; } return $key; @@ -98,8 +102,8 @@ public function parseKey(Query $query, $key, bool $strict = false): string /** * 设置锁机制 * @access protected - * @param Query $query 查询对象 - * @param bool|string $lock + * @param Query $query 查询对象 + * @param bool|string $lock * @return string */ protected function parseLock(Query $query, $lock = false): string diff --git a/src/db/connector/Sqlite.php b/src/db/connector/Sqlite.php index c664f202..3e42a909 100644 --- a/src/db/connector/Sqlite.php +++ b/src/db/connector/Sqlite.php @@ -42,7 +42,7 @@ protected function parseDsn(array $config): string public function getFields(string $tableName): array { [$tableName] = explode(' ', $tableName); - $sql = 'PRAGMA table_info( ' . $tableName . ' )'; + $sql = 'PRAGMA table_info( \'' . $tableName . '\' )'; $pdo = $this->getPDOStatement($sql); $result = $pdo->fetchAll(PDO::FETCH_ASSOC); From 7e7b34bb94049ffe7d277d87d1860277febf2f2d Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Tue, 11 Jan 2022 20:43:29 +0800 Subject: [PATCH 35/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3Fetch=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/Fetch.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/db/Fetch.php b/src/db/Fetch.php index 16caed2b..a997a859 100644 --- a/src/db/Fetch.php +++ b/src/db/Fetch.php @@ -421,10 +421,8 @@ public function count(string $field = '*'): string if (!empty($options['group'])) { // 支持GROUP - $bind = $this->query->getBind(); - $subSql = $this->query->options($options)->field('count(' . $field . ') AS think_count')->bind($bind)->buildSql(); - - $query = $this->query->newQuery()->table([$subSql => '_group_count_']); + $subSql = $this->query->field('count(' . $field . ') AS think_count')->buildSql(); + $query = $this->query->newQuery()->table([$subSql => '_group_count_']); return $query->fetchsql()->aggregate('COUNT', '*'); } else { From 9f785471bed3c09cdaa4889c89596c3044bc6444 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 12 Jan 2022 12:31:30 +0800 Subject: [PATCH 36/40] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E5=A4=9A=E5=AF=B9?= =?UTF-8?q?=E5=A4=9A=E5=85=B3=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/relation/BelongsToMany.php | 62 +++++++++++++++------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/src/model/relation/BelongsToMany.php b/src/model/relation/BelongsToMany.php index 75eab1e2..f82a64a6 100644 --- a/src/model/relation/BelongsToMany.php +++ b/src/model/relation/BelongsToMany.php @@ -132,9 +132,39 @@ public function getRelation(array $subRelation = [], Closure $closure = null): C $closure($this->getClosureType($closure)); } - return $this->relation($subRelation) + $resultSet = $this->relation($subRelation) ->select() ->setParent(clone $this->parent); + + foreach ($resultSet as $result) { + $this->matchPivot($result); + } + + return $resultSet; + } + + /** + * 组装Pivot模型 + * @access public + * @param Model $result 模型对象 + * @return array + */ + protected function matchPivot(Model $result): array + { + $pivot = []; + foreach ($result->getData() as $key => $val) { + if (strpos($key, '__')) { + [$name, $attr] = explode('__', $key, 2); + + if ('pivot' == $name) { + $pivot[$attr] = $val; + unset($result->$key); + } + } + } + + $result->setRelation($this->pivotDataName, $this->newPivot($pivot)); + return $pivot; } /** @@ -326,24 +356,13 @@ protected function eagerlyManyToMany(array $where, array $subRelation = [], Clos // 组装模型数据 $data = []; foreach ($list as $set) { - $pivot = []; - foreach ($set->getData() as $key => $val) { - if (strpos($key, '__')) { - [$name, $attr] = explode('__', $key, 2); - if ('pivot' == $name) { - $pivot[$attr] = $val; - unset($set->$key); - } - } - } - $key = $pivot[$this->localKey]; + $pivot = $this->matchPivot($set); + $key = $pivot[$this->localKey]; if ($this->withLimit && isset($data[$key]) && count($data[$key]) >= $this->withLimit) { continue; } - $set->setRelation($this->pivotDataName, $this->newPivot($pivot)); - $data[$key][] = $set; } @@ -595,20 +614,7 @@ protected function baseQuery(): void $localKey = $this->localKey; $this->query->getModel()->filter(function ($result, $options) { - $pivot = []; - - foreach ($result->getData() as $key => $val) { - if (strpos($key, '__')) { - [$name, $attr] = explode('__', $key, 2); - - if ('pivot' == $name) { - $pivot[$attr] = $val; - unset($result->$key); - } - } - } - - $result->setRelation($this->pivotDataName, $this->newPivot($pivot)); + $this->matchPivot($result); }); // 关联查询 From 2bd628d70444fb4053bc87f3c855c62df0259109 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Wed, 12 Jan 2022 14:55:51 +0800 Subject: [PATCH 37/40] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=A4=9A=E5=AF=B9?= =?UTF-8?q?=E5=A4=9A=E5=85=B3=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/relation/BelongsToMany.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/model/relation/BelongsToMany.php b/src/model/relation/BelongsToMany.php index f82a64a6..98909068 100644 --- a/src/model/relation/BelongsToMany.php +++ b/src/model/relation/BelongsToMany.php @@ -132,15 +132,9 @@ public function getRelation(array $subRelation = [], Closure $closure = null): C $closure($this->getClosureType($closure)); } - $resultSet = $this->relation($subRelation) + return $this->relation($subRelation) ->select() ->setParent(clone $this->parent); - - foreach ($resultSet as $result) { - $this->matchPivot($result); - } - - return $resultSet; } /** @@ -613,7 +607,7 @@ protected function baseQuery(): void $foreignKey = $this->foreignKey; $localKey = $this->localKey; - $this->query->getModel()->filter(function ($result, $options) { + $this->query->filter(function ($result, $options) { $this->matchPivot($result); }); From 14606afecb309d746799e5bd6e2d63f1a6a66112 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Thu, 13 Jan 2022 14:06:27 +0800 Subject: [PATCH 38/40] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=86=99=E5=85=A5=E5=AF=B9=E5=AF=B9=E8=B1=A1=E5=80=BC=E7=9A=84?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/concern/Attribute.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/model/concern/Attribute.php b/src/model/concern/Attribute.php index 9201f903..e4aa07b4 100644 --- a/src/model/concern/Attribute.php +++ b/src/model/concern/Attribute.php @@ -382,6 +382,9 @@ public function setAttr(string $name, $value, array $data = []): void } elseif (isset($this->type[$name])) { // 类型转换 $value = $this->writeTransform($value, $this->type[$name]); + } elseif (is_object($value) && method_exists($value, '__toString')) { + // 对象类型 + $value = $value->__toString(); } // 设置数据对象属性 From 6f5c7f60f90f54125b139b7b362121f92735c901 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Mon, 17 Jan 2022 23:47:39 +0800 Subject: [PATCH 39/40] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E4=B8=80=E5=AF=B9?= =?UTF-8?q?=E4=B8=80=E5=85=B3=E8=81=94=E5=86=99=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/relation/BelongsTo.php | 6 +++--- src/model/relation/HasOne.php | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/model/relation/BelongsTo.php b/src/model/relation/BelongsTo.php index 941e1d44..08aecaa7 100644 --- a/src/model/relation/BelongsTo.php +++ b/src/model/relation/BelongsTo.php @@ -277,12 +277,12 @@ protected function eagerlyOne(Model $result, string $relation, array $subRelatio $relationModel->exists(true); } + // 设置关联属性 + $result->setRelation($relation, $relationModel); + if (!empty($this->bindAttr)) { // 绑定关联属性 $this->bindAttr($result, $relationModel); - } else { - // 设置关联属性 - $result->setRelation($relation, $relationModel); } } diff --git a/src/model/relation/HasOne.php b/src/model/relation/HasOne.php index be4927b6..e1b6486b 100644 --- a/src/model/relation/HasOne.php +++ b/src/model/relation/HasOne.php @@ -276,11 +276,12 @@ protected function eagerlyOne(Model $result, string $relation, array $subRelatio $relationModel->exists(true); } + // 设置关联属性 + $result->setRelation($relation, $relationModel); + if (!empty($this->bindAttr)) { // 绑定关联属性 $this->bindAttr($result, $relationModel); - } else { - $result->setRelation($relation, $relationModel); } } From 2eb8d027c06b7d1b711d41079ae43fa192735885 Mon Sep 17 00:00:00 2001 From: ThinkPHP Date: Mon, 17 Jan 2022 23:59:22 +0800 Subject: [PATCH 40/40] =?UTF-8?q?=E4=B8=80=E5=AF=B9=E4=B8=80=E5=85=B3?= =?UTF-8?q?=E8=81=94=E6=9F=A5=E8=AF=A2=E7=BB=91=E5=AE=9A=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/relation/BelongsTo.php | 5 ++--- src/model/relation/HasOne.php | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/model/relation/BelongsTo.php b/src/model/relation/BelongsTo.php index 08aecaa7..0802b11a 100644 --- a/src/model/relation/BelongsTo.php +++ b/src/model/relation/BelongsTo.php @@ -236,12 +236,11 @@ protected function eagerlySet(array &$resultSet, string $relation, array $subRel $relationModel->exists(true); } + // 设置关联属性 + $result->setRelation($relation, $relationModel); if (!empty($this->bindAttr)) { // 绑定关联属性 $this->bindAttr($result, $relationModel); - } else { - // 设置关联属性 - $result->setRelation($relation, $relationModel); } } } diff --git a/src/model/relation/HasOne.php b/src/model/relation/HasOne.php index e1b6486b..269f0d7f 100644 --- a/src/model/relation/HasOne.php +++ b/src/model/relation/HasOne.php @@ -234,13 +234,12 @@ protected function eagerlySet(array &$resultSet, string $relation, array $subRel $relationModel->setParent(clone $result); $relationModel->exists(true); } + // 设置关联属性 + $result->setRelation($relation, $relationModel); if (!empty($this->bindAttr)) { // 绑定关联属性 $this->bindAttr($result, $relationModel); - } else { - // 设置关联属性 - $result->setRelation($relation, $relationModel); } } }