I
I
Igor2019-10-25 19:28:11
symfony
Igor, 2019-10-25 19:28:11

Nested tree removal, how to recalculate lft, rgt?

Colleagues, good evening!
I'm deleting the entire thread.
Like this

/**
     * @param $node
     * @return void
     */
    public function removeTree(Service $node)
    {
        $this->createQueryBuilder("s")
            ->delete()
            ->where("s.lft = :lft")->setParameter("lft", $node->getLft())
            ->andWhere("s.rgt = :rgt")->setParameter("rgt", $node->getRgt())
            ->andWhere("s.root = :root")->setParameter("root", $node->getRoot())
            ->getQuery()
            ->execute();
    }

Everything is perfectly removed, but how now to recalculate lft, rgt?
When I create nodes, the indices are recalculated, but up.
5db3244ebd8c1638593133.png
5db32467cf841968588652.png
I use

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
Igor, 2019-10-28
@IgorPI

Decision.
As a first approximation, I recalculate as follows.

class ServiceRepository extends NestedTreeRepository
{
...
/**
     * @param Service $node
     * @return void
     * @throws ORMException
     * @throws OptimisticLockException
     */
    public function removeTree(Service $node)
    {
        $this->createQueryBuilder("s")
            ->delete()
            ->where("s.lft >= :lft")->setParameter("lft", $node->getLft())
            ->andWhere("s.rgt <= :rgt")->setParameter("rgt", $node->getRgt())
            ->andWhere("s.root = :root")->setParameter("root", $node->getRoot())
            ->getQuery()
            ->execute();

        $em = $this->getEntityManager();
        $em->beginTransaction();
        $repository = $em->getRepository("App:Service");
        $refreshLeftAndRight = function($root, $left) use ($repository, &$refreshLeftAndRight) {
            $right = $left + 1;
            $children = $repository->findBy(['parent' => $root,]);

            foreach ($children as $entity) {
                $right = $refreshLeftAndRight($entity, $right);
            }
            $root->setlft($left);
            $root->setRgt($right);
            return $right + 1;
        };

        foreach ($repository->findBy(["parent" => null]) as $rootEntry) {
            $refreshLeftAndRight($rootEntry, 1);
        }

        $em->flush();
        $em->commit();
    }

...

Who in the subject will understand what is happening here.
Certainly not perfect.
In the future, it is worth recalculating only those root branches in which the deletion occurred.
In this case, we recalculate everything.

A
Alexander Zemlyanoy, 2019-10-29
@Galamoon

Good time of the day.
To implement the tree, there is a ready-made bundle of extensions for doctrine .
Look, it can be easier to use a ready-made solution.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question