Skip to content

Instantly share code, notes, and snippets.

@jaromirnyklicek
Created August 29, 2017 21:53
Show Gist options
  • Save jaromirnyklicek/780768864a7a60c76b0e8e3791556432 to your computer and use it in GitHub Desktop.
Save jaromirnyklicek/780768864a7a60c76b0e8e3791556432 to your computer and use it in GitHub Desktop.
Tree traversal - move subtree
<?php
public function moveSubtree($node, $parent)
{
$lft = $parent->getRgt();
$lvl = $parent->getLvl() + 1;
$diff = $node->getRgt() - $node->getLft() + 1;
if ($lft > $node->getLft()) {
$lft -= $diff;
}
if ($lft !== $node->getLft()) {
$minLft = min($lft, $node->getLft());
$maxRgt = max($lft + $diff - 1, $node->getRgt());
$move = $lft - $node->getLft();
if ($lft > $node->getLft()) {
$diff = -$diff;
}
$nodesToModify = $this->getQueryBuilder()
->select('c')
->from(Category::class, 'c')
->andWhere('c.rgt >= :minLft')
->andWhere('c.lft <= :maxRgt')
->setParameter('minLft', $minLft)
->setParameter('maxRgt', $maxRgt)
->getQuery()->getResult();
foreach ($nodesToModify as $nodeToModify) {
if ($nodeToModify->getId() === $node->getId()) {
$nodeToModify->setParent($parent);
}
$subtree = $nodeToModify->getLft() >= $node->getLft()
&& $nodeToModify->getRgt() <= $node->getRgt();
$nodeLft = $subtree
? $nodeToModify->getLft() + $move
: $nodeToModify->getLft() + ($nodeToModify->getLft() >= $minLft ? $diff : 0);
$nodeRgt = $subtree
? $nodeToModify->getRgt() + $move
: $nodeToModify->getRgt() + ($nodeToModify->getRgt() <= $maxRgt ? $diff : 0);
$nodeLvl = $subtree ? $nodeToModify->getLvl() : $nodeToModify->getLvl() + $lvl - $node->getLvl();
$nodeToModify->setTreeValues($nodeLft, $nodeRgt, $nodeLvl);
$this->_em->persist($nodeToModify);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment