| | <?php |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | namespace think\model\relation; |
| |
|
| | use think\Db; |
| | use think\db\Query; |
| | use think\Exception; |
| | use think\Loader; |
| | use think\Model; |
| | use think\model\Relation; |
| |
|
| | class MorphMany extends Relation |
| | { |
| | |
| | protected $morphKey; |
| | protected $morphType; |
| | |
| | protected $type; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function __construct(Model $parent, $model, $morphKey, $morphType, $type) |
| | { |
| | $this->parent = $parent; |
| | $this->model = $model; |
| | $this->type = $type; |
| | $this->morphKey = $morphKey; |
| | $this->morphType = $morphType; |
| | $this->query = (new $model)->db(); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | public function getRelation($subRelation = '', $closure = null) |
| | { |
| | if ($closure) { |
| | call_user_func_array($closure, [ & $this->query]); |
| | } |
| | $list = $this->relation($subRelation)->select(); |
| | $parent = clone $this->parent; |
| |
|
| | foreach ($list as &$model) { |
| | $model->setParent($parent); |
| | } |
| |
|
| | return $list; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') |
| | { |
| | throw new Exception('relation not support: has'); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function hasWhere($where = [], $fields = null) |
| | { |
| | throw new Exception('relation not support: hasWhere'); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) |
| | { |
| | $morphType = $this->morphType; |
| | $morphKey = $this->morphKey; |
| | $type = $this->type; |
| | $range = []; |
| | foreach ($resultSet as $result) { |
| | $pk = $result->getPk(); |
| | |
| | if (isset($result->$pk)) { |
| | $range[] = $result->$pk; |
| | } |
| | } |
| |
|
| | if (!empty($range)) { |
| | $data = $this->eagerlyMorphToMany([ |
| | $morphKey => ['in', $range], |
| | $morphType => $type, |
| | ], $relation, $subRelation, $closure); |
| | |
| | $attr = Loader::parseName($relation); |
| | |
| | foreach ($resultSet as $result) { |
| | if (!isset($data[$result->$pk])) { |
| | $data[$result->$pk] = []; |
| | } |
| | foreach ($data[$result->$pk] as &$relationModel) { |
| | $relationModel->setParent(clone $result); |
| | $relationModel->isUpdate(true); |
| | } |
| | $result->setRelation($attr, $this->resultSetBuild($data[$result->$pk])); |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function eagerlyResult(&$result, $relation, $subRelation, $closure) |
| | { |
| | $pk = $result->getPk(); |
| | if (isset($result->$pk)) { |
| | $data = $this->eagerlyMorphToMany([ |
| | $this->morphKey => $result->$pk, |
| | $this->morphType => $this->type, |
| | ], $relation, $subRelation, $closure); |
| |
|
| | if (!isset($data[$result->$pk])) { |
| | $data[$result->$pk] = []; |
| | } |
| |
|
| | foreach ($data[$result->$pk] as &$relationModel) { |
| | $relationModel->setParent(clone $result); |
| | $relationModel->isUpdate(true); |
| | } |
| |
|
| | $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$result->$pk])); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function relationCount($result, $closure) |
| | { |
| | $pk = $result->getPk(); |
| | $count = 0; |
| | if (isset($result->$pk)) { |
| | if ($closure) { |
| | call_user_func_array($closure, [ & $this->query]); |
| | } |
| | $count = $this->query->where([$this->morphKey => $result->$pk, $this->morphType => $this->type])->count(); |
| | } |
| | return $count; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function getRelationCountQuery($closure, &$name = null) |
| | { |
| | if ($closure) { |
| | $return = call_user_func_array($closure, [ & $this->query]); |
| | if ($return && is_string($return)) { |
| | $name = $return; |
| | } |
| | } |
| |
|
| | return $this->query->where([ |
| | $this->morphKey => [ |
| | 'exp', |
| | Db::raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk()), |
| | ], |
| | $this->morphType => $this->type, |
| | ])->fetchSql()->count(); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | protected function eagerlyMorphToMany($where, $relation, $subRelation = '', $closure = false) |
| | { |
| | |
| | if ($closure) { |
| | call_user_func_array($closure, [ & $this]); |
| | } |
| | $list = $this->query->where($where)->with($subRelation)->select(); |
| | $morphKey = $this->morphKey; |
| | |
| | $data = []; |
| | foreach ($list as $set) { |
| | $data[$set->$morphKey][] = $set; |
| | } |
| | return $data; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | public function save($data) |
| | { |
| | if ($data instanceof Model) { |
| | $data = $data->getData(); |
| | } |
| |
|
| | |
| | $pk = $this->parent->getPk(); |
| |
|
| | $data[$this->morphKey] = $this->parent->$pk; |
| | $data[$this->morphType] = $this->type; |
| |
|
| | $model = new $this->model(); |
| |
|
| | return $model->save() ? $model : false; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | public function make($data = []) |
| | { |
| | if ($data instanceof Model) { |
| | $data = $data->getData(); |
| | } |
| |
|
| | |
| | $pk = $this->parent->getPk(); |
| |
|
| | $data[$this->morphKey] = $this->parent->$pk; |
| | $data[$this->morphType] = $this->type; |
| |
|
| | return new $this->model($data); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | public function saveAll(array $dataSet) |
| | { |
| | $result = false; |
| | foreach ($dataSet as $key => $data) { |
| | $result = $this->save($data); |
| | } |
| | return $result; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | protected function baseQuery() |
| | { |
| | if (empty($this->baseQuery) && $this->parent->getData()) { |
| | $pk = $this->parent->getPk(); |
| | $map[$this->morphKey] = $this->parent->$pk; |
| | $map[$this->morphType] = $this->type; |
| | $this->query->where($map); |
| | $this->baseQuery = true; |
| | } |
| | } |
| |
|
| | } |
| |
|