summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/controllers/welcome.php2
-rw-r--r--core/libraries/ORM_MPTT.php97
-rw-r--r--core/models/item.php26
-rw-r--r--modules/rearrange/controllers/rearrange.php26
-rw-r--r--modules/rearrange/js/jquery.gallery.rearrange.tree.js18
5 files changed, 146 insertions, 23 deletions
diff --git a/core/controllers/welcome.php b/core/controllers/welcome.php
index 8f8421d3..1d2082d4 100644
--- a/core/controllers/welcome.php
+++ b/core/controllers/welcome.php
@@ -125,7 +125,7 @@ class Welcome_Controller extends Template_Controller {
$data = "digraph G {\n";
foreach ($items as $item) {
$data .= " $item->parent_id -> $item->id\n";
- $data .= " $item->id [label=\"$item->id <$item->left, $item->right>\"]\n";
+ $data .= " $item->id [label=\"$item->id $item->title <$item->left, $item->right>\"]\n";
}
$data .= "}\n";
diff --git a/core/libraries/ORM_MPTT.php b/core/libraries/ORM_MPTT.php
index bac4da92..2290c83a 100644
--- a/core/libraries/ORM_MPTT.php
+++ b/core/libraries/ORM_MPTT.php
@@ -53,7 +53,7 @@ class ORM_MPTT_Core extends ORM {
* @return ORM
*/
function add_to_parent($parent_id) {
- $this->_lock();
+ $this->lock();
try {
// Make a hole in the parent for this new item
@@ -71,11 +71,11 @@ class ORM_MPTT_Core extends ORM {
$this->level = $parent->level + 1;
$this->save();
} catch (Exception $e) {
- $this->_unlock();
+ $this->unlock();
throw $e;
}
- $this->_unlock();
+ $this->unlock();
return $this;
}
@@ -93,18 +93,18 @@ class ORM_MPTT_Core extends ORM {
$this->reload();
}
- $this->_lock();
+ $this->lock();
try {
$this->db->query(
- "UPDATE `{$this->table_name}` SET `left` = `left` - 2 WHERE `left` >= {$this->right}");
+ "UPDATE `{$this->table_name}` SET `left` = `left` - 2 WHERE `left` > {$this->right}");
$this->db->query(
- "UPDATE `{$this->table_name}` SET `right` = `right` - 2 WHERE `right` >= {$this->right}");
+ "UPDATE `{$this->table_name}` SET `right` = `right` - 2 WHERE `right` > {$this->right}");
} catch (Exception $e) {
- $this->_unlock();
+ $this->unlock();
throw $e;
}
- $this->_unlock();
+ $this->unlock();
parent::delete();
}
@@ -225,11 +225,88 @@ class ORM_MPTT_Core extends ORM {
return parent::reload();
}
+ /**
+ * Move this item to the specified target.
+ *
+ * @chainable
+ * @param Item_Model $target Target item (must be an album
+ * @param boolean $locked The called is already holding the lock
+ * @return ORM_MTPP
+ */
+ function moveTo($target, $locked=false) {
+ if ($target->type != "album") {
+ throw new Exception("@todo '{$target->type}' IS NOT A VALID MOVE TARGET");
+ }
+
+ if ($this->id == 1) {
+ throw new Exception("@todo '{$this->title}' IS NOT A VALID SOURCE");
+ }
+
+ $numberToMove = (int)(($this->right - $this->left) / 2 + 1);
+ $size_of_hole = $numberToMove * 2;
+ $original_parent = $this->parent;
+
+ if (empty($locked)) {
+ $this->lock();
+ }
+ try {
+ // Make a hole in the target for the move
+ $target->db->query(
+ "UPDATE `{$target->table_name}` SET `left` = `left` + $size_of_hole" .
+ " WHERE `left` >= {$target->right}");
+ $target->db->query(
+ "UPDATE `{$target->table_name}` SET `right` = `right` + $size_of_hole" .
+ " WHERE `right` >= {$target->right}");
+
+ // Change the parent.
+ $this->db->query(
+ "UPDATE `{$this->table_name}` SET `parent_id` = {$target->id}" .
+ " WHERE `id` = {$this->id}");
+
+ // If the source is to the right of the target then we just adjusted its left and right above.
+ $left = $this->left;
+ $right = $this->right;
+ if ($this->left > $target->right) {
+ $left += $size_of_hole;
+ $right += $size_of_hole;
+ }
+
+ $newOffset = $target->left - $left + 1;
+ $this->db->query(
+ "UPDATE `{$this->table_name}`" .
+ " SET `left` = `left` + $newOffset," .
+ " `right` = `right` + $newOffset" .
+ " WHERE `left` >= $left" .
+ " AND `right` <= $right");
+
+ // Close the hole in the source's parent after the move
+ $this->db->query(
+ "UPDATE `{$this->table_name}` SET `left` = `left` - $size_of_hole" .
+ " WHERE `left` > $right");
+ $this->db->query(
+ "UPDATE `{$this->table_name}` SET `right` = `right` - $size_of_hole" .
+ " WHERE `right` > $right");
+
+ } catch (Exception $e) {
+ if (empty($locked)) {
+ $this->unlock();
+ }
+ throw $e;
+ }
+
+ if (empty($locked)) {
+ $this->_unlock();
+ }
+
+ // Lets reload to get the changes.
+ $this->reload();
+ return $this;
+ }
/**
* Lock the tree to prevent concurrent modification.
*/
- private function _lock() {
+ protected function lock() {
$result = $this->db->query("SELECT GET_LOCK('{$this->table_name}', 1) AS L")->current();
if (empty($result->L)) {
throw new Exception("@todo UNABLE_TO_LOCK_EXCEPTION");
@@ -239,7 +316,7 @@ class ORM_MPTT_Core extends ORM {
/**
* Unlock the tree.
*/
- private function _unlock() {
+ protected function unlock() {
$this->db->query("SELECT RELEASE_LOCK('{$this->table_name}')");
}
}
diff --git a/core/models/item.php b/core/models/item.php
index fbaca0e7..495508ec 100644
--- a/core/models/item.php
+++ b/core/models/item.php
@@ -53,6 +53,32 @@ class Item_Model extends ORM_MPTT {
}
/**
+ * Move this item to the specified target.
+ *
+ * @chainable
+ * @param Item_Model $target Target item (must be an album
+ * @return ORM_MTPP
+ */
+ function moveTo($target) {
+ $this->lock();
+ try {
+ $original_path = $this->file_path();
+
+ parent::moveTo($target, true);
+
+ $new_path = $this->file_path();
+ rename($original_path, $new_path);
+
+ } catch (Exception $e) {
+ $this->unlock();
+ throw $e;
+ }
+
+ $this->unlock();
+ return $this;
+ }
+
+ /**
* album: /var/albums/album1/album2
* photo: /var/albums/album1/album2/photo.jpg
*/
diff --git a/modules/rearrange/controllers/rearrange.php b/modules/rearrange/controllers/rearrange.php
index 59c1b069..6118e07e 100644
--- a/modules/rearrange/controllers/rearrange.php
+++ b/modules/rearrange/controllers/rearrange.php
@@ -22,14 +22,26 @@ class Rearrange_Controller extends Controller {
public function show($id=null) {
$view = new View("rearrange_item_list.html");
- if (empty($id)) {
- $item = ORM::factory("item", 1);
- $view->children = array($item);
- } else {
- $item = ORM::factory("item", $id);
- $view->children = $item->children();
- }
+ $isRoot = empty($id);
+ $item = ORM::factory("item", $isRoot ? 1 : $id);
+
+ $view->children = $isRoot ? array($item) : $item->children();
print $view;
}
+
+ public function move($source_id, $target_id) {
+ $source = ORM_MPTT::factory("item", $source_id);
+ $target = ORM_MPTT::factory("item", $target_id);
+
+ try {
+ $source->moveTo($target);
+ print "success";
+ } catch (Exception $e) {
+ Kohana::log("error", $e->getMessage() . "\n" + $e->getTraceAsString());
+ header("HTTP/1.1 500");
+ print $e->getMessage();
+ }
+ }
+
} \ No newline at end of file
diff --git a/modules/rearrange/js/jquery.gallery.rearrange.tree.js b/modules/rearrange/js/jquery.gallery.rearrange.tree.js
index 09284a25..c423becd 100644
--- a/modules/rearrange/js/jquery.gallery.rearrange.tree.js
+++ b/modules/rearrange/js/jquery.gallery.rearrange.tree.js
@@ -70,9 +70,19 @@ if(jQuery) (function($){
hoverClass: "droppable-hover",
drop: function(ev, ui) {
source_element = ui.draggable;
- source_parent = source_element.parent();
+ source_parent = getParent(source_element);
target = ui.element;
- alert(source_element.attr("id") + "\n" + target.attr("id"));
+
+ $.ajax({
+ url: "rearrange/move/" + source_element.attr("id") + "/" + target.attr("id"),
+ success: function(data, textStatus) {
+ collapse(source_parent);
+ showTree(source_parent, source_parent.attr("id"));
+ },
+ error: function(xhr, textStatus, errorThrown) {
+ alert("Http Error Code: " + xhr.status + "Text Status: " + textStatus);
+ }
+ });
}
});
bindTree(c);
@@ -168,9 +178,7 @@ if(jQuery) (function($){
showTree(parent, parent.attr("id"));
},
error: function(xhr, textStatus, errorThrown) {
- alert(xhr.status);
- alert(textStatus);
- alert(errorThrown);
+ alert("Http Error Code: " + xhr.status + "Text Status: " + textStatus);
},
type: "DELETE"
});