/** * Returns a QueryBuilder to grab the siblings of the given node * * @param \DoctrineExtensions\Hierarchical\MaterializedPath\MaterializedPathNodeInfo $node * @return \Doctrine\ORM\QueryBuilder */ public function getSiblingQueryBuilder(MaterializedPathNodeInfo $node) { $qb = $this->getBaseQueryBuilder(); $expr = $qb->expr(); $andX = $expr->andX(); $andX->add($expr->eq('e.' . $node->getDepthFieldName(), $node->getDepth())); if ($node->getDepth() > 1) { $parentPath = PathHelper::getBasePath($node, $node->getPath(), $node->getDepth() - 1); $pathInterval = PathHelper::getChildrenPathInterval($node, $parentPath); $andX->add($expr->between('e.' . $node->getPathFieldName(), $expr->literal($pathInterval[0]), $expr->literal($pathInterval[1]))); } $qb->where($andX); return $qb; }
/** * Returns the base path of another path up to the specified depth * * @param string $path * @param string $depth * @return string */ protected function _getBasePath($path, $depth) { return PathHelper::getBasePath($this, $path, $depth); }
public function deleteQuerySet($qb, $knownChildren = false) { if ($knownChildren) { $batch = 20; $i = 0; $iterableResult = $qb->getQuery()->iterate(); while (($row = $iterableResult->next()) !== false) { $this->em->remove($row[0]); if ($i++ % $batch == 0) { $this->em->flush(); $this->em->clear(); } } $this->em->flush(); $this->em->clear(); return; } $expr = $qb->expr(); $qb->orderBy('e.' . $this->getDepthFieldName())->addOrderBy('e.' . $this->getPathFieldName()); $removed = array(); foreach ($qb->getQuery()->getResult() as $node) { $node = $this->getNode($node); $found = false; $range = array_slice(range(1, strlen($node->getPath()) / $this->getStepLength()), 0, -1); foreach ($range as $depth) { $path = PathHelper::getBasePath($node, $node->getPath(), $depth); if (isset($removed[$path])) { // already removing a parent of this node $found = true; break; } } if (!$found) { $removed[$node->getPath()] = $node; } } $parents = array(); $toRemove = array(); foreach ($removed as $path => $node) { $parentPath = PathHelper::getBasePath($node, $node->getPath(), $node->getDepth() - 1); if ($parentPath) { if (!isset($parents[$parentPath])) { $parents[$parentPath] = $node->getParent(true); } $parent = $parents[$parentPath]; if ($parent && $parent->getNumberOfChildren() > 0) { $parent->setValue($this->getNumChildrenFieldName(), $parent->getNumberOfChildren() - 1); } } if (!$node->isLeaf()) { $toRemove[] = $expr->like('e.' . $this->getPathFieldName(), $expr->literal($node->getPath() . '%')); } else { $toRemove[] = $expr->eq('e.' . $this->getPathFieldName(), $expr->literal($node->getPath())); } } if ($toRemove) { $orX = $expr->orX(); $orX->addMultiple($toRemove); $qb->where($orX); $this->deleteQuerySet($qb, true); } }