/** * 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; } }