diff --git a/library/think/Model.php b/library/think/Model.php index 1e6e32a8..e6d7661f 100644 --- a/library/think/Model.php +++ b/library/think/Model.php @@ -36,6 +36,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess protected static $links = []; // 数据库配置 protected $connection = []; + // 父关联模型对象 + protected $parent; // 数据库查询对象 protected $query; // 当前模型名称 @@ -219,6 +221,29 @@ abstract class Model implements \JsonSerializable, \ArrayAccess { } + /** + * 设置父关联对象 + * @access public + * @param Model $model 模型对象 + * @return $this + */ + public function setParent($model) + { + $this->parent = $model; + + return $this; + } + + /** + * 获取父关联对象 + * @access public + * @return Model + */ + public function getParent() + { + return $this->parent; + } + /** * 设置数据对象值 * @access public @@ -458,10 +483,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } elseif ($notFound) { $method = Loader::parseName($name, 1, false); if (method_exists($this, $method) && $this->$method() instanceof Relation) { - // 清空之前的查询参数 - $this->$method()->removeOption(); + $modelRelation = $this->$method(); // 不存在该字段 获取关联数据 - $value = $this->$method()->getRelation(); + $value = $this->getRelationData($modelRelation); // 保存关联对象值 $this->data[$name] = $value; } else { @@ -471,6 +495,24 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return $value; } + /** + * 获取关联模型数据 + * @access public + * @param mixed $value 值 + * @param string|array $type 要转换的类型 + * @return mixed + */ + protected function getRelationData($modelRelation) + { + if ($this->parent && get_class($this->parent) == $modelRelation->getModel()) { + $value = $this->parent; + } else { + // 首先获取关联数据 + $value = $modelRelation->removeOption()->getRelation(); + } + return $value; + } + /** * 数据读取 类型转换 * @access public diff --git a/library/think/model/relation/BelongsTo.php b/library/think/model/relation/BelongsTo.php index f693ef6d..d0973614 100644 --- a/library/think/model/relation/BelongsTo.php +++ b/library/think/model/relation/BelongsTo.php @@ -130,6 +130,8 @@ class BelongsTo extends OneToOne $relationModel = null; } else { $relationModel = $data[$result->$foreignKey]; + $relationModel->setParent($result); + $relationModel->isUpdate(true); } if ($relationModel && !empty($this->bindAttr)) { @@ -161,6 +163,8 @@ class BelongsTo extends OneToOne $relationModel = null; } else { $relationModel = $data[$result->$foreignKey]; + $relationModel->setParent($result); + $relationModel->isUpdate(true); } if ($relationModel && !empty($this->bindAttr)) { // 绑定关联属性 diff --git a/library/think/model/relation/HasMany.php b/library/think/model/relation/HasMany.php index 4c045494..3fc9f746 100644 --- a/library/think/model/relation/HasMany.php +++ b/library/think/model/relation/HasMany.php @@ -84,6 +84,11 @@ class HasMany extends Relation if (!isset($data[$result->$localKey])) { $data[$result->$localKey] = []; } + + foreach ($data[$result->$localKey] as &$relationModel) { + $relationModel->setParent($result); + } + $result->setAttr($attr, $this->resultSetBuild($data[$result->$localKey])); } } @@ -108,6 +113,11 @@ class HasMany extends Relation if (!isset($data[$result->$localKey])) { $data[$result->$localKey] = []; } + + foreach ($data[$result->$localKey] as &$relationModel) { + $relationModel->setParent($result); + } + $result->setAttr(Loader::parseName($relation), $this->resultSetBuild($data[$result->$localKey])); } } diff --git a/library/think/model/relation/HasOne.php b/library/think/model/relation/HasOne.php index 95a401bf..a19d9a4b 100644 --- a/library/think/model/relation/HasOne.php +++ b/library/think/model/relation/HasOne.php @@ -132,10 +132,12 @@ class HasOne extends OneToOne $relationModel = null; } else { $relationModel = $data[$result->$localKey]; - } - if ($relationModel && !empty($this->bindAttr)) { - // 绑定关联属性 - $this->bindAttr($relationModel, $result, $this->bindAttr); + $relationModel->setParent($result); + $relationModel->isUpdate(true); + if (!empty($this->bindAttr)) { + // 绑定关联属性 + $this->bindAttr($relationModel, $result, $this->bindAttr); + } } // 设置关联属性 $result->setAttr($attr, $relationModel); @@ -163,12 +165,14 @@ class HasOne extends OneToOne $relationModel = null; } else { $relationModel = $data[$result->$localKey]; + $relationModel->setParent($result); + $relationModel->isUpdate(true); + if (!empty($this->bindAttr)) { + // 绑定关联属性 + $this->bindAttr($relationModel, $result, $this->bindAttr); + } } - if ($relationModel && !empty($this->bindAttr)) { - // 绑定关联属性 - $this->bindAttr($relationModel, $result, $this->bindAttr); - } $result->setAttr(Loader::parseName($relation), $relationModel); } diff --git a/library/think/model/relation/MorphMany.php b/library/think/model/relation/MorphMany.php index 964d3d3a..7142314b 100644 --- a/library/think/model/relation/MorphMany.php +++ b/library/think/model/relation/MorphMany.php @@ -119,6 +119,10 @@ class MorphMany extends Relation if (!isset($data[$result->$pk])) { $data[$result->$pk] = []; } + foreach ($data[$result->$pk] as &$relationModel) { + $relationModel->setParent($result); + $relationModel->isUpdate(true); + } $result->setAttr($attr, $this->resultSetBuild($data[$result->$pk])); } } @@ -141,6 +145,12 @@ class MorphMany extends Relation $this->morphKey => $result->$pk, $this->morphType => $this->type, ], $relation, $subRelation, $closure); + + foreach ($data[$result->$pk] as &$relationModel) { + $relationModel->setParent($result); + $relationModel->isUpdate(true); + } + $result->setAttr(Loader::parseName($relation), $this->resultSetBuild($data[$result->$pk])); } } diff --git a/library/think/model/relation/MorphOne.php b/library/think/model/relation/MorphOne.php index 1bcc7710..c2547c0a 100644 --- a/library/think/model/relation/MorphOne.php +++ b/library/think/model/relation/MorphOne.php @@ -117,9 +117,14 @@ class MorphOne extends Relation // 关联数据封装 foreach ($resultSet as $result) { if (!isset($data[$result->$pk])) { - $data[$result->$pk] = []; + $relationModel = null; + } else { + $relationModel = $data[$result->$pk]; + $relationModel->setParent($result); + $relationModel->isUpdate(true); } - $result->setAttr($attr, $this->resultSetBuild($data[$result->$pk])); + + $result->setAttr($attr, $relationModel); } } } @@ -137,11 +142,21 @@ class MorphOne extends Relation { $pk = $result->getPk(); if (isset($result->$pk)) { + $pk = $result->$pk; $data = $this->eagerlyMorphToOne([ - $this->morphKey => $result->$pk, + $this->morphKey => $pk, $this->morphType => $this->type, ], $relation, $subRelation, $closure); - $result->setAttr(Loader::parseName($relation), $this->resultSetBuild($data[$result->$pk])); + + if (isset($data[$pk])) { + $relationModel = $data[$pk]; + $data[$pk]->setParent($result); + $relationModel->isUpdate(true); + } else { + $relationModel = null; + } + + $result->setAttr(Loader::parseName($relation), $relationModel); } } diff --git a/library/think/model/relation/MorphTo.php b/library/think/model/relation/MorphTo.php index 9c020b85..304186dc 100644 --- a/library/think/model/relation/MorphTo.php +++ b/library/think/model/relation/MorphTo.php @@ -168,7 +168,11 @@ class MorphTo extends Relation if (!isset($data[$result->$morphKey])) { throw new Exception('relation data not exists :' . $this->model); } else { - $result->setAttr($attr, $data[$result->$morphKey]); + $relationModel = $data[$result->$morphKey]; + $relationModel->setParent($result); + $relationModel->isUpdate(true); + + $result->setAttr($attr, $relationModel); } } } @@ -220,6 +224,7 @@ class MorphTo extends Relation $pk = $this->parent->{$this->morphKey}; $data = (new $model)->with($subRelation)->find($pk); if ($data) { + $data->setParent($result); $data->isUpdate(true); } $result->setAttr(Loader::parseName($relation), $data ?: null); diff --git a/library/think/model/relation/OneToOne.php b/library/think/model/relation/OneToOne.php index b0cf931d..7dc5e47e 100644 --- a/library/think/model/relation/OneToOne.php +++ b/library/think/model/relation/OneToOne.php @@ -245,13 +245,19 @@ abstract class OneToOne extends Relation } } } + if (isset($list[$relation])) { $relationModel = new $model($list[$relation]); + $relationModel->setParent($result); + $relationModel->isUpdate(true); + if (!empty($this->bindAttr)) { $this->bindAttr($relationModel, $result, $this->bindAttr); } + } else { + $relationModel = null; } - $result->setAttr(Loader::parseName($relation), !isset($relationModel) ? null : $relationModel->isUpdate(true)); + $result->setAttr(Loader::parseName($relation), $relationModel); } /**