Named scope. Gets descendants for node.

@param bool $includeSelf
@param int  $depth       the depth

@return $this
186271
public function descendants($includeSelf = false, $depth = null)
    {
        $this
            ->getQuerySet()
            ->descendants($includeSelf, $depth);

        return $this;
    }
1221386
public function load($entities, $depth = 1)
    {
        if (!\is_array($entities) && !$entities instanceof \Traversable) {
            throw new \InvalidArgumentException(self::E_MSG);
        }

        $entitiesByValueClassByIds = $this->sortEntitiesByValueClass($entities);
        foreach ($entitiesByValueClassByIds as $valueClass => $entitiesById) {
            $this->loadEntityValues($valueClass, $entitiesById);
        }

        $this->loadRelatedEntities($entities, $depth);
    }
61299
protected function insertNearInternal($forward)
    {
        $this->checkNode(true);
        $item = $this->owner->getAttribute($this->itemAttribute);

        if ($item !== null) {
            $path = $this->node->getParentPath();
            $this->owner->setAttribute($this->pathAttribute, $path . $this->delimiter . $item);
        }

        $this->owner->setAttribute($this->depthAttribute, $this->node->getAttribute($this->depthAttribute));

        if ($this->treeAttribute !== null) {
            $this->owner->setAttribute($this->treeAttribute, $this->node->getAttribute($this->treeAttribute));
        }

        if ($this->sortable !== false) {
            if ($forward) {
                $this->behavior->moveAfter($this->node);
            } else {
                $this->behavior->moveBefore($this->node);
            }
        }
    }
1102396
public static function getNextNode($originalNode, $ignoreSelfAndKids = false)
    {
        /*
         * Traverse the DOM from node to node, starting at the node passed in.
         * Pass true for the second parameter to indicate this node itself
         * (and its kids) are going away, and we want the next node over.
         *
         * Calling this in a loop will traverse the DOM depth-first.
         */

        // First check for kids if those aren't being ignored
        if (!$ignoreSelfAndKids && $originalNode->firstChild) {
            return $originalNode->firstChild;
        }

        // Then for siblings...
        if ($originalNode->nextSibling) {
            return $originalNode->nextSibling;
        }

        // And finally, move up the parent chain *and* find a sibling
        // (because this is depth-first traversal, we will have already
        // seen the parent nodes themselves).
        do {
            $originalNode = $originalNode->parentNode;
        } while ($originalNode && !$originalNode->nextSibling);

        return ($originalNode) ? $originalNode->nextSibling : $originalNode;
    }
1334202
public function populateTree($depth = null, $with = null)
    {
        /** @var ActiveRecord[]|static[] $nodes */
        $depths = [$this->owner->getPrimaryKey() => 0];
        $data = $this->getDescendantsIds($depth);
        foreach ($data as $i => $ids) {
            foreach ($ids as $id) {
                $depths[$id] = $i + 1;
            }
        }
        $query = $this->getDescendants($depth);
        if ($with) {
            $query->with($with);
        }
        $nodes = $query
            ->orderBy($this->sortable !== false ? [$this->behavior->sortAttribute => SORT_ASC] : null)
            ->all();

        $relates = [];
        foreach ($nodes as $node) {
            $key = $node->getAttribute($this->parentAttribute);
            if (!isset($relates[$key])) {
                $relates[$key] = [];
            }
            $relates[$key][] = $node;
        }

        $nodes[] = $this->owner;
        foreach ($nodes as $node) {
            $key = $node->getPrimaryKey();
            if (isset($relates[$key])) {
                $node->populateRelation('children', $relates[$key]);
            } elseif ($depth === null || (isset($depths[$node->getPrimaryKey()]) && $depths[$node->getPrimaryKey()] < $depth)) {
                $node->populateRelation('children', []);
            }
        }

        return $this->owner;
    }
7645
function extendsOrImplementsInterface($interfaceName, $includeSelf) {
    $interfacesAll = $this->getAllInterfaces($includeSelf);
    return isset($interfacesAll[$interfaceName]);
  }
73973
public function limitObject($var, $depth, array &$references)
    {
        $hash = spl_object_hash($var);

        if (in_array($hash, $references)) {
            return '*RECURSION*';
        }

        $references[] = $hash;
        $ref = new \ReflectionObject($var);
        foreach ($ref->getProperties() as $prop) {
            $prop->setAccessible(true);

            $prop->setValue($var, $this->limit($prop->getValue($var), $depth + 1, $references));
        }

        return $var;
    }
52732
protected function loadRelatedEntities($entities, $depth)
    {
        if (0 <= $depth) {
            return;
        }
        $relatedEntities = [];
        foreach ($entities as $entity) {
            if (null === $entity) {
                continue;
            }
            $family = $entity->getFamily();
            foreach ($family->getAttributes() as $attribute) {
                $this->appendRelatedEntities($relatedEntities, $attribute, $entity);
            }
        }

        $this->load($relatedEntities, $depth - 1);
    }
809317
private function getNodeChildren(array $options)
    {
        /** @noinspection PhpUnusedParameterInspection */
        $options = (new OptionsResolver)->setDefaults([
            'depth'           => 1,
            'refName'         => null,
            'parent'          => null,
            'lang'            => $this->currentLocale->getCurrentLocale(),
            'include_root'    => false,
            'include_hidden'  => false,
            'include_offline' => false,
            'flatten'         => false,
            'limit'           => 0,
        ])
            ->setNormalizer('refName', function ($options, $value) {
                return $value ? (array)$value : [];
            })
            ->setAllowedTypes('parent', ['null', Node::class])
            ->setAllowedTypes('depth', 'integer')
            ->setAllowedTypes('limit', 'integer')
            ->setAllowedTypes('include_root', 'bool')
            ->setAllowedTypes('include_hidden', 'bool')
            ->setAllowedTypes('flatten', 'bool')
            ->resolve($options);

        $qb = $this->nodeRepository
            ->createQueryBuilder('node')
            ->leftJoin('node.nodeTranslations', 'nt', Join::WITH, 'nt.node = node and nt.lang = :lang')
            ->leftJoin('nt.publicNodeVersion', 'nv')
            ->leftJoin('node.parent', 'parent')
            ->select('parent.id as parentId', 'node.id', 'nt.title', 'nt.url', 'nt.lang', 'nv.refId', 'nv.refEntityName', 'node.internalName')
            ->where('nt.lang = :lang')
            ->andWhere('node.deleted = 0')
            ->orderBy('node.lvl, nt.weight')
            ->setParameter('lang', $options['lang']);

        if ($options['limit']) {
            $qb->setMaxResults($options['limit']);
        }

        if (false === $options['include_hidden']) {
            $qb->andWhere('node.hiddenFromNav = 0');
        }

        if (false === $options['include_offline']) {
            $qb->andWhere('nt.online = 1');
        }

        if ($options['refName']) {
            $qb
                ->andWhere('node.refEntityName in (:refName)')
                ->setParameter('refName', $options['refName']);
        }

        $level = 0;
        $nodeId = null;
        if ($options['parent']) {
            /** @var Node $parent */
            $parent = $options['parent'];
            $nodeId = $parent->getId();
            $level = $parent->getLevel();


            $qb->andWhere('node.lft >= :minLeft')
                ->andWhere('node.rgt <= :maxRight')
                ->setParameter('minLeft', $parent->getLeft())
                ->setParameter('maxRight', $parent->getRight());

            if (false === $options['include_root']) {
                $qb->andWhere('node.id != :nodeId')
                    ->setParameter('nodeId', $nodeId);
            }
        }

        if ($options['depth']) {
            $qb->andWhere('node.lvl <= :maxLevel')
                ->setParameter('maxLevel', $level + $options['depth']);
        }

        $children = $qb->getQuery()->getResult();

        $flatten = $options['flatten'];

        /** @noinspection PhpInternalEntityUsedInspection */
        return array_reduce($children, function (TreeBuilder $treeBuilder, $item) use ($nodeId, $flatten) {
            $branch = new Branch($item['title'], $item['id'], $item['url'], $item['lang'], $item['refId'], $item['refEntityName'], $item['internalName']);

            if ($branch->getNodeId() === $nodeId) {
                $item['parentId'] = null;
            } elseif ($flatten) {
                $item['parentId'] = $nodeId;
            }

            return $treeBuilder->add($item['parentId'], $branch);
        }, new TreeBuilder)->getRoot();

    }
311070
public function getDescendants($depth = null, $andSelf = false)
    {
        /** @var \yii\db\ActiveQuery|MaterializedPathQueryTrait $query */
        $query = $this->owner->find();
        return $query->descendantsOf($this->owner, $depth, $andSelf);
    }
591420
public function depthFirst($tree = [], \Closure $callback = null)
    {
        if (!$tree) {
            $tree = $this->tree;
        }
        foreach ($tree as $node) {
            if ($callback) {
                call_user_func_array($callback, ['node' => $node]);
            }
            $children = $node['children'];
            if ($children) {
                $this->depthFirst($children, $callback);
            }
        }
    }
593436
private function recurse_children($parent, &$options, $depth = 1) {
    $parent->childrens->map(function($child) use (&$options, $depth) {
      $options[$child->id] = str_repeat('-', $depth) .' '. $child->name;

      if ($child->childrens) {
        $this->recurse_children($child, $options, $depth+1);
      }
    });
  }
495357
public function findChildren(callable $callback, $depth = null, $level = null)
    {

        $level = $level ?: 0;

        foreach ($this->children as $child) {

            /** @var NodeInterface $child */
            if ($child->is($callback))
                yield $child;

            if ($depth === null || $level < $depth) {

                if ($child instanceof NodeInterface)
                    foreach ($child->findChildren($callback, $depth, $level + 1) as $subChild)
                        yield $subChild;
            }
        }
    }
530155
private function searchTree(int $depth = 0)
    {
        $this->depth = $depth;
        foreach ($this->children->getList() as $node) {
            if ($depth > count($this->treePath)) {
                break;
            }

            if ($this->treePath[$depth] != $node->key) {
                continue;
            }

            /**
             * @var $node TreeNode
             */
            if (count($this->treePath) > $depth && $this->allowedToDiveDeeper($depth)) {
                $node->setTreePath($this->treePath);

                return $node->searchTree(++$depth);
            }
        }

        return $this;
    }
495220
public function parents($depth = null) {
        $condition = [
            'and',
            [$this->leftAttribute => ['$lt' => $this->owner->getAttribute($this->leftAttribute)]],
            [$this->rightAttribute => ['$gt' => $this->owner->getAttribute($this->rightAttribute)]],
        ];

        if ($depth !== null) {
            $condition[] = [$this->depthAttribute => ['$gte' => $this->owner->getAttribute($this->depthAttribute) - $depth]];
        }

        $this->applyTreeAttributeCondition($condition);

        return $this->owner->find()->andWhere($condition)->addOrderBy([$this->leftAttribute => SORT_ASC]);
    }
956903
public function getChildren($includeHiddenFromNav = true)
    {
        if (is_null($this->children)) {
            $children = $this->menu->getChildren($this->node, true);
            /* @var NodeMenuItem $child */
            foreach ($children as $child) {
                $child->setParent($this);
            }
            $this->children = $children;
        }

        $children = array_filter($this->children, function (NodeMenuItem $entry) use ($includeHiddenFromNav) {
            if ($entry->getNode()->isHiddenFromNav() && !$includeHiddenFromNav) {
                return false;
            }

            return true;
        });

        return $children;
    }
36803
public function getAbsoluteLiveLink($includeStageEqualsLive = true)
    {
        $oldReadingMode = Versioned::get_reading_mode();
        Versioned::set_stage(Versioned::LIVE);
        /** @var SiteTree $live */
        $live = Versioned::get_one_by_stage(self::class, Versioned::LIVE, array(
            '"SiteTree"."ID"' => $this->ID
        ));
        if ($live) {
            $link = $live->AbsoluteLink();
            if ($includeStageEqualsLive) {
                $link = Controller::join_links($link, '?stage=Live');
            }
        } else {
            $link = null;
        }

        Versioned::set_reading_mode($oldReadingMode);
        return $link;
    }