/** * Fetches a branch of a tree, returning a flat array of node wrappers with * parent, children, ancestors and descendants pre-populated. * * @param mixed $pk the primary key used to locate the node to traverse * the tree from * @param int $depth the depth to retrieve or null for unlimited * * @return array */ public function fetchBranchAsArray($pk, $depth = null) { $config = $this->getConfiguration(); $lftField = $config->getLeftFieldName(); $rgtField = $config->getRightFieldName(); $rootField = $config->getRootFieldName(); $hasManyRoots = $config->hasManyRoots(); if ($depth === 0) { return array(); } $node = $this->getEntityManager()->find($this->getConfiguration()->getClassname(), $pk); if (!$node) { return array(); } $qb = $config->getBaseQueryBuilder(); $alias = $config->getQueryBuilderAlias(); $qb->andWhere("{$alias}.{$lftField} >= :lowerbound")->setParameter('lowerbound', $node->getLeftValue())->andWhere("{$alias}.{$rgtField} <= :upperbound")->setParameter('upperbound', $node->getRightValue())->orderBy("{$alias}.{$lftField}", "ASC"); // TODO: Add support for depth via a cross join if ($hasManyRoots) { $qb->andWhere("{$alias}.{$rootField} = :rootid")->setParameter('rootid', $node->getRootValue()); } $q = $qb->getQuery(); if ($this->config->isQueryHintSet()) { $q = $this->addHintToQuery($q); } $nodes = $q->execute(); // @codeCoverageIgnoreStart if (empty($nodes)) { return null; } // @codeCoverageIgnoreEnd // TODO: Filter depth using a cross join instead of this if ($depth !== null) { $nodes = $this->filterNodeDepth($nodes, $depth); } $wrappers = array(); foreach ($nodes as $node) { $wrappers[] = $this->wrapNode($node); } $this->buildTree($wrappers); return $wrappers; }