public function deleteSubtree(Section $section) { //Update deleted subtree $queryBuilder = $this->_em->createQueryBuilder(); $queryBuilder->update('Icap\\WikiBundle\\Entity\\Section', 'section')->set('section.left', 0)->set('section.right', 0)->set('section.level', -1)->set('section.parent', '?1')->set('section.deleted', '?2')->set('section.deletionDate', '?3')->andWhere('section.root = :root')->andWhere($queryBuilder->expr()->gte('section.left', $section->getLeft()))->andWhere($queryBuilder->expr()->lte('section.right', $section->getRight()))->setParameter(1, null)->setParameter(2, true)->setParameter(3, new \DateTime('NOW'))->setParameter('root', $section->getRoot()); $queryBuilder->getQuery()->getSingleScalarResult(); $boundaryWidth = $section->getRight() - $section->getLeft() + 1; //Update boundaries (left and right) for all nodes after deleted node $queryBuilder = $this->_em->createQueryBuilder(); $queryBuilder->update('Icap\\WikiBundle\\Entity\\Section', 'section')->set('section.right', 'section.right-?1')->andWhere('section.root = :root')->andWhere($queryBuilder->expr()->gt('section.right', $section->getRight()))->setParameter(1, $boundaryWidth)->setParameter('root', $section->getRoot()); $queryBuilder->getQuery()->getSingleScalarResult(); $queryBuilder = $this->_em->createQueryBuilder(); $queryBuilder->update('Icap\\WikiBundle\\Entity\\Section', 'section')->set('section.left', 'section.left-?1')->andWhere('section.root = :root')->andWhere($queryBuilder->expr()->gt('section.left', $section->getRight()))->setParameter(1, $boundaryWidth)->setParameter('root', $section->getRoot()); $queryBuilder->getQuery()->getSingleScalarResult(); }
/** * Move a section around the tree. * * @param Wiki $wiki * @param Section $section * * @return mixed[] * * @Post( * "/api/wikis/{wiki}/sections/{section}", * name="icap_wiki_api_move_wiki_section", * requirements={ "wiki" = "\d+", "section" = "\d+" }, * options = { "expose" = true } * ) */ public function moveWikiSectionAction(Wiki $wiki, Section $section) { $this->checkAccess('EDIT', $wiki); $repo = $this->get('icap.wiki.section_repository'); $response = new JsonResponse(); $payload = $this->get('request')->request->all(); try { $newParentId = $payload['newParent']; $newPreviousSiblingId = $payload['newPreviousSibling']; // If new parent is root, get its ID if (is_null($newParentId)) { $newParentId = $wiki->getRoot()->getId(); } $oldParent = $section->getparent(); $oldLeft = $section->getLeft(); $newParent = $this->getSection($wiki, $newParentId); if (!is_null($newPreviousSiblingId)) { $newPreviousSibling = $this->getSection($wiki, $newPreviousSiblingId); $repo->persistAsNextSiblingOf($section, $newPreviousSibling); } else { $repo->persistAsFirstChildOf($section, $newParent); } $em = $this->getDoctrine()->getManager(); $em->persist($section); $em->flush(); $changeSet = $section->getMoveEventChangeSet($oldParent, $oldLeft, $newParent); $this->dispatchSectionMoveEvent($wiki, $section, $changeSet); return $response->setData(['response' => 'moved']); } catch (Exception $e) { // Something went wrong, send the last known version of the sections to the client $isAdmin = $this->isUserGranted('EDIT', $wiki); return $response->setStatusCode(400)->setData(['sections' => $repo->buildSectionTree($wiki, $isAdmin)]); } }