move.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <?php
  2. include '../connection.php';
  3. try {
  4. $params = json_decode(file_get_contents('php://input'));
  5. $db->beginTransaction();
  6. // if the node is being appended to the root node, change relatedId and position so that the node will be appended after the last node in the db
  7. // this is necessary because we do not store the actual root node in the db
  8. if($params->relatedId == -1) {
  9. $statement = $db->prepare("select id from list where rgt = (select max(rgt) from list)");
  10. if(!$statement->execute()) {
  11. throw new Exception(implode(', ', $statement->errorInfo()));
  12. }
  13. $result = $statement->fetch(PDO::FETCH_ASSOC);
  14. $params->relatedId = $result['id'];
  15. $params->position = 'after';
  16. }
  17. // Step 1: figure out how much space the node to be moved takes up (nodeSize)
  18. $statement = $db->prepare("select lft, rgt from list where id = $params->id");
  19. if(!$statement->execute()) {
  20. throw new Exception(implode(', ', $statement->errorInfo()));
  21. }
  22. $nodeBounds = $statement->fetch(PDO::FETCH_ASSOC);
  23. $nodeSize = $nodeBounds['rgt'] - $nodeBounds['lft'] + 1;
  24. // Step 2: calculate the insertion point where the node is being moved to.
  25. // this will be the left bound of the node after it is moved
  26. $statement = $db->prepare("select lft, rgt from list where id = $params->relatedId");
  27. if(!$statement->execute()) {
  28. throw new Exception(implode(', ', $statement->errorInfo()));
  29. }
  30. $relatedNodeBounds = $statement->fetch(PDO::FETCH_ASSOC);
  31. if($params->position == 'after') {
  32. $insertionPoint = $relatedNodeBounds['rgt'] + 1;
  33. } else if($params->position == 'before') {
  34. $insertionPoint = $relatedNodeBounds['lft'];
  35. } else if($params->position == 'append') {
  36. $insertionPoint = $relatedNodeBounds['rgt'];
  37. }
  38. // Step 3: before moving the node and its descendants, make room at the insertion point
  39. // this is done by incrementing by nodeSize the left/right values for all nodes to the right of the insertion point
  40. $statement = $db->prepare("update list set lft = lft + $nodeSize where lft >= $insertionPoint");
  41. if(!$statement->execute()) {
  42. $db->rollBack();
  43. throw new Exception(implode(', ', $statement->errorInfo()));
  44. }
  45. $statement = $db->prepare("update list set rgt = rgt + $nodeSize where rgt >= $insertionPoint");
  46. if(!$statement->execute()) {
  47. $db->rollBack();
  48. throw new Exception(implode(', ', $statement->errorInfo()));
  49. }
  50. // Step 4: calculate how far the node has to move to get to the insertion point
  51. // to do this, we need to first recalculate the node's bounds, since they may have changed in Step 3
  52. // if the node's existing position is to the right of the insertion point
  53. $statement = $db->prepare("select lft, rgt from list where id = $params->id");
  54. if(!$statement->execute()) {
  55. throw new Exception(implode(', ', $statement->errorInfo()));
  56. }
  57. $nodeBounds = $statement->fetch(PDO::FETCH_ASSOC);
  58. $leftBound = $nodeBounds['lft'];
  59. $rightBound = $nodeBounds['rgt'];
  60. $distance = $insertionPoint - $nodeBounds['lft'];
  61. // Step 5: "move" the node to the insertion point by incrementing by $distance
  62. // the left/right values for the node being moved and all its descendants
  63. $statement = $db->prepare("update list set lft = lft + $distance, rgt = rgt + $distance where lft >= $leftBound and rgt <= $rightBound");
  64. if(!$statement->execute()) {
  65. $db->rollBack();
  66. throw new Exception(implode(', ', $statement->errorInfo()));
  67. }
  68. // Step 6: decrement the left/right values for all the nodes to the right of the empty space left by the node that was moved
  69. $statement = $db->prepare("update list set lft = lft - $nodeSize where lft > $rightBound");
  70. if(!$statement->execute()) {
  71. $db->rollBack();
  72. throw new Exception(implode(', ', $statement->errorInfo()));
  73. }
  74. $statement = $db->prepare("update list set rgt = rgt - $nodeSize where rgt > $rightBound");
  75. if(!$statement->execute()) {
  76. $db->rollBack();
  77. throw new Exception(implode(', ', $statement->errorInfo()));
  78. }
  79. $jsonResult = array('success' => true);
  80. $db->commit();
  81. } catch(Exception $e) {
  82. $jsonResult = array(
  83. 'success' => false,
  84. 'message' => $e->getMessage()
  85. );
  86. }
  87. echo json_encode($jsonResult);
  88. ?>