Created
June 21, 2012 22:07
-
-
Save sevein/2968861 to your computer and use it in GitHub Desktop.
Extra NestedSet functionality
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Extra operations for nested sets | |
| */ | |
| public function moveToPrevSiblingOf($sibling, PropelPDO $con = null) | |
| { | |
| /* | |
| if (!$this->isInTree()) | |
| { | |
| throw new PropelException('A QubitInformationObject object must be already in the tree to be moved. Use the insertAsPrevSiblingOf() instead.'); | |
| } | |
| if ($sibling->isRoot()) | |
| { | |
| throw new PropelException('Cannot move to previous sibling of a root node.'); | |
| } | |
| if ($sibling->isDescendantOf($this)) | |
| { | |
| throw new PropelException('Cannot move a node as sibling of one of its subtree nodes.'); | |
| } | |
| */ | |
| $this->moveSubtreeTo($sibling->lft, $con); | |
| return $this; | |
| } | |
| public function moveToNextSiblingOf($sibling, PropelPDO $con = null) | |
| { | |
| /* | |
| if (!$this->isInTree()) | |
| { | |
| throw new PropelException('A QubitInformationObject object must be already in the tree to be moved. Use the insertAsPrevSiblingOf() instead.'); | |
| } | |
| if ($sibling->isRoot()) | |
| { | |
| throw new PropelException('Cannot move to previous sibling of a root node.'); | |
| } | |
| if ($sibling->isDescendantOf($this)) | |
| { | |
| throw new PropelException('Cannot move a node as sibling of one of its subtree nodes.'); | |
| } | |
| */ | |
| $this->moveSubtreeTo($sibling->rgt + 1, $con); | |
| return $this; | |
| } | |
| protected function moveSubtreeTo($destLeft, PropelPDO $con = null) | |
| { | |
| $left = $this->lft; | |
| $right = $this->rgt; | |
| $treeSize = $right - $left +1; | |
| if ($con === null) | |
| { | |
| $con = Propel::getConnection(); | |
| } | |
| $con->beginTransaction(); | |
| try | |
| { | |
| // make room next to the target for the subtree | |
| self::shiftRLValues($treeSize, $destLeft, null, $con); | |
| if ($left >= $destLeft) // src was shifted too? | |
| { | |
| $left += $treeSize; | |
| $right += $treeSize; | |
| } | |
| // move the subtree to the target | |
| self::shiftRLValues($destLeft - $left, $left, $right, $con); | |
| // remove the empty room at the previous location of the subtree | |
| self::shiftRLValues(-$treeSize, $right + 1, null, $con); | |
| // update all loaded nodes | |
| // self::updateLoadedNodes(null, $con); | |
| $con->commit(); | |
| // $con->rollback(); | |
| } | |
| catch (PropelException $e) | |
| { | |
| $con->rollback(); | |
| throw $e; | |
| } | |
| } | |
| /** | |
| * Adds $delta to all L and R values that are >= $first and <= $last. | |
| * '$delta' can also be negative. | |
| * | |
| * @param int $delta Value to be shifted by, can be negative | |
| * @param int $first First node to be shifted | |
| * @param int $last Last node to be shifted (optional) | |
| * @param PropelPDO $con Connection to use. | |
| */ | |
| public static function shiftRLValues($delta, $first, $last = null, PropelPDO $con = null) | |
| { | |
| if ($con === null) | |
| { | |
| $con = Propel::getConnection(); | |
| } | |
| // Shift left column values | |
| $whereCriteria = new Criteria; | |
| $criterion = $whereCriteria->getNewCriterion(QubitInformationObject::LFT, $first, Criteria::GREATER_EQUAL); | |
| if (null !== $last) | |
| { | |
| $criterion->addAnd($whereCriteria->getNewCriterion(QubitInformationObject::LFT, $last, Criteria::LESS_EQUAL)); | |
| } | |
| $whereCriteria->add($criterion); | |
| $valuesCriteria = new Criteria; | |
| $valuesCriteria->add(QubitInformationObject::LFT, array('raw' => QubitInformationObject::LFT . ' + ?', 'value' => $delta), Criteria::CUSTOM_EQUAL); | |
| BasePeer::doUpdate($whereCriteria, $valuesCriteria, $con); | |
| // Shift right column values | |
| $whereCriteria = new Criteria; | |
| $criterion = $whereCriteria->getNewCriterion(QubitInformationObject::RGT, $first, Criteria::GREATER_EQUAL); | |
| if (null !== $last) | |
| { | |
| $criterion->addAnd($whereCriteria->getNewCriterion(QubitInformationObject::RGT, $last, Criteria::LESS_EQUAL)); | |
| } | |
| $whereCriteria->add($criterion); | |
| $valuesCriteria = new Criteria; | |
| $valuesCriteria->add(QubitInformationObject::RGT, array('raw' => QubitInformationObject::RGT . ' + ?', 'value' => $delta), Criteria::CUSTOM_EQUAL); | |
| BasePeer::doUpdate($whereCriteria, $valuesCriteria, $con); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment