owner->innerJoinWith('oldTreePathsChild oldTreePathsChild', $eagerLoading) ->andWhere(['oldTreePathsChild.parent_id' => $ownerId]); if (!$withParent) { $this->owner ->andWhere(['!=', 'oldTreePathsChild.child_id', $ownerId]); } if ($depth !== null) { $this->depthCheck($depth); /** @var self $subQuery */ $subQuery = ($this->owner->modelClass::findOld()) ->select(new Expression('oldTreePathsChild.child_level + :depth', [':depth' => $depth])) ->owner($ownerId); $this->owner ->andWhere(['<=', 'oldTreePathsChild.child_level', $subQuery]); } return $this->owner; } /** * 获取元素的所有父节点 * * @param int $ownerId * @param bool|false $withChild * @param int|null $depth * @param bool|false $eagerLoading * @return ActiveQuery * @throws LogicException */ public function parents( int $ownerId, bool $withChild = false, ?int $depth = null, bool $eagerLoading = false ): ActiveQuery { $this->owner ->innerJoinWith('oldTreePathsChild oldTreePathsChild', $eagerLoading) ->andWhere(['oldTreePathsChild.child_id' => $ownerId]); if (!$withChild) { $this->owner ->andWhere(['!=', 'oldTreePathsChild.parent_id', $ownerId]); } if ($depth !== null) { $this->depthCheck($depth); /** @var self $subQuery */ $subQuery = ($this->owner->modelClass::findOld()) ->select( new Expression( 'IF(oldTreePathsChild.child_level <= :depth, 1, oldTreePathsChild.child_level - :depth)', [':depth' => $depth] ) ) ->owner($ownerId); $this->owner ->andWhere(['>=', 'oldTreePathsChild.parent_level', $subQuery]); } return $this->owner; } /** * 获取元素父节点 * * @param int $ownerId * @param bool $eagerLoading * @return ActiveQuery */ public function parent(int $ownerId, bool $eagerLoading = false): ActiveQuery { return $this->owner ->innerJoinWith('oldTreePathsNearestParent oldTreePathsNearestParent', $eagerLoading) ->andWhere(['oldTreePathsNearestParent.parent_id' => $ownerId]) ->andWhere(['oldTreePathsNearestParent.child_id' => $ownerId]); } /** * 获取所有根节点 * * @param bool $eagerLoading * @return ActiveQuery */ public function roots(bool $eagerLoading = false): ActiveQuery { return $this->owner ->innerJoinWith('oldTreePathsParent oldTreePathsParent', $eagerLoading) ->andWhere(['oldTreePathsParent.nearest_parent_id' => 0]); } /** * 获取元素直系子节点 * * @param int $ownerId * @param bool $eagerLoading * @return ActiveQuery */ public function nearestChilds(int $ownerId, bool $eagerLoading = false): ActiveQuery { return $this->owner ->innerJoinWith('oldTreePathsChild oldTreePathsChild', $eagerLoading) ->andWhere(['oldTreePathsChild.nearest_parent_id' => $ownerId]) ->andWhere(['oldTreePathsChild.parent_id' => $ownerId]); } /** * 查询元素条件 * * @param int $ownerId * @param bool $eagerLoading * @return ActiveQuery */ public function owner(int $ownerId, bool $eagerLoading = false): ActiveQuery { return $this->owner ->innerJoinWith('oldTreePathOwner oldTreePathOwner', $eagerLoading) ->andWhere(['oldTreePathOwner.parent_id' => $ownerId]) ->andWhere(['oldTreePathOwner.child_id' => $ownerId]); } }