/** * inserts node as parent of given node * * @param NodeWrapper $node */ public function insertAsParentOf(NodeWrapper $node) { if ($node === $this) { throw new \InvalidArgumentException('Cannot insert node as a parent of itself'); } if ($this->isValidNode()) { throw new \InvalidArgumentException('Cannot insert a node that already has a place within the tree'); } if ($node->isRoot()) { throw new \InvalidArgumentException('Cannot insert as parent of root'); } $em = $this->getManager()->getEntityManager(); $lftField = $this->getLeftFieldName(); $rgtField = $this->getRightFieldName(); $newLft = $node->getLeftValue(); $newRgt = $node->getRightValue() + 2; $newRoot = $this->hasManyRoots() ? $node->getRootValue() : null; // beginTransaction $em->getConnection()->beginTransaction(); try { // Make space for new node $this->shiftRLRange($newRgt - 1, 0, 2, $newRoot); // Slide child nodes over one and down one to allow new parent to wrap them $qb = $em->createQueryBuilder()->update(get_class($this->getNode()), 'n')->set("n.{$lftField}", "n.{$lftField} + 1")->set("n.{$rgtField}", "n.{$rgtField} + 1")->where("n.{$lftField} >= ?1")->setParameter(1, $newLft)->andWhere("n.{$rgtField} <= ?2")->setParameter(2, $newRgt); if ($this->hasManyRoots()) { $qb->andWhere("n." . $this->getRootFieldName() . " = ?3")->setParameter(3, $newRoot); } $qb->getQuery()->execute(); $this->getManager()->updateValues($newLft, $newRgt, 1, $newRoot); $this->insertNode($newLft, $newRgt, $newRoot); $em->flush(); $em->getConnection()->commit(); } catch (\Exception $e) { // @codeCoverageIgnoreStart $em->close(); $em->getConnection()->rollback(); throw $e; // @codeCoverageIgnoreEnd } // endTransaction }