Skip to content

Instantly share code, notes, and snippets.

@sevein
Created June 21, 2012 22:07
Show Gist options
  • Save sevein/2968861 to your computer and use it in GitHub Desktop.
Save sevein/2968861 to your computer and use it in GitHub Desktop.
Extra NestedSet functionality
<?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