예제 #1
0
 /**
  * Move an element into another as its child.
  *
  * @param $model|NestedSet_Model    Nested set model
  * @param $element|array            Element to move
  * @param $reference|array          Reference element to move into
  *
  * @return $this
  */
 public function moveInto(NestedSet_Model $nestedset, array $element, array $reference)
 {
     $db = $nestedset->getDb();
     try {
         // Check it can be moved into. XXX change when we'll get one level
         if ($element[0][$nestedset->getStructureLeft()] > $reference[0][$nestedset->getStructureLeft()] && $element[0][$nestedset->getStructureLeft()] < $reference[0][$nestedset->getStructureRight()]) {
             // already into
             return false;
         }
         $db->beginTransaction();
         // first make room into reference
         // @TODO make a protected method to make room
         // with must always be a pair number
         $elementWidth = $nestedset->getNodeWidth($element[0][$nestedset->getStructureId()]);
         // move right
         $referenceRight = $reference[0][$nestedset->getStructureRight()];
         $db->query("\n                UPDATE {$nestedset->getTableName()}\n                   SET {$nestedset->getStructureRight()} = {$nestedset->getStructureRight()} + {$elementWidth}\n                 WHERE {$nestedset->getStructureRight()} >= {$referenceRight};\n            ");
         // move left
         $db->query("\n                UPDATE {$nestedset->getTableName()}\n                   SET {$nestedset->getStructureLeft()} = {$nestedset->getStructureLeft()} + {$elementWidth}\n                 WHERE {$nestedset->getStructureLeft()} > {$referenceRight};\n            ");
         // then move element (and it's children)
         $element = $nestedset->getElement($element[0][$nestedset->getStructureId()]);
         $elementIds = array();
         foreach ($element as $one) {
             array_push($elementIds, $one[$nestedset->getStructureId()]);
         }
         $elementIds = implode(', ', $elementIds);
         $difference = $reference[0][$nestedset->getStructureRight()] - $element[0][$nestedset->getStructureLeft()];
         $db->query("\n                UPDATE {$nestedset->getTableName()}\n                   SET {$nestedset->getStructureLeft()}  = {$nestedset->getStructureLeft()}  + {$difference},\n                       {$nestedset->getStructureRight()} = {$nestedset->getStructureRight()} + {$difference}\n                 WHERE {$nestedset->getStructureId()} IN ({$elementIds});\n            ");
         // move what was on the right of the element
         $db->query("\n                UPDATE {$nestedset->getTableName()}\n                   SET {$nestedset->getStructureLeft()} = {$nestedset->getStructureLeft()} - {$elementWidth}\n                 WHERE {$nestedset->getStructureLeft()} > {$element[0][$nestedset->getStructureLeft()]};\n            ");
         $db->query("\n                UPDATE {$nestedset->getTableName()}\n                   SET {$nestedset->getStructureRight()} = {$nestedset->getStructureRight()} - {$elementWidth}\n                 WHERE {$nestedset->getStructureRight()} > {$element[0][$nestedset->getStructureRight()]};\n            ");
         $db->commit();
     } catch (Exception $e) {
         $db->rollBack();
         throw $e;
     }
 }