Esempio n. 1
0
 /**
  * @param  \Phalcon\Mvc\ModelInterface $target
  * @param  int $key
  * @param  int $levelUp
  *
  * @return boolean
  * @throws PMMException
  */
 private function moveNode($target, $key, $levelUp)
 {
     $owner = $this->getOwner();
     if (!$target) {
         throw new PMMException('Target node is not defined.');
     }
     if ($this->getIsNewRecord()) {
         throw new PMMException('The node should not be new record.');
     }
     if ($this->getIsDeletedRecord()) {
         throw new PMMException('The node should not be deleted.');
     }
     if ($target->getIsDeletedRecord()) {
         throw new PMMException('The target node should not be deleted.');
     }
     if ($owner == $target) {
         throw new PMMException('The target node should not be self.');
     }
     if ($target->isDescendantOf($owner)) {
         throw new PMMException('The target node should not be descendant.');
     }
     if (!$levelUp && $target->isRoot()) {
         throw new PMMException('The target node should not be root.');
     }
     $owner->getDI()->getDb()->begin();
     $left = $owner->{$this->leftAttribute};
     $right = $owner->{$this->rightAttribute};
     $levelDelta = $target->{$this->levelAttribute} - $owner->{$this->levelAttribute} + $levelUp;
     if ($this->hasManyRoots && $owner->{$this->rootAttribute} !== $target->{$this->rootAttribute}) {
         $this->ignoreEvent = true;
         foreach (array($this->leftAttribute, $this->rightAttribute) as $attribute) {
             $condition = $attribute . '>=' . $key . ' AND ' . $this->rootAttribute . '=' . $target->{$this->rootAttribute};
             foreach ($owner::find($condition) as $i) {
                 if ($i->update(array($attribute => $i->{$attribute} + $right - $left + 1)) == false) {
                     $owner->getDI()->getDb()->rollback();
                     $this->ignoreEvent = false;
                     return false;
                 }
             }
         }
         $delta = $key - $left;
         $condition = $this->leftAttribute . '>=' . $left . ' AND ';
         $condition .= $this->rightAttribute . '<=' . $right . ' AND ';
         $condition .= $this->rootAttribute . '=' . $target->{$this->rootAttribute};
         foreach ($owner::find($condition) as $i) {
             $arr = array($this->leftAttribute => $i->{$this->leftAttribute} + $delta, $this->rightAttribute => $i->{$this->rightAttribute} + $delta, $this->levelAttribute => $i->{$this->levelAttribute} + $levelDelta, $this->rootAttribute => $target->{$this->rootAttribute});
             if ($i->update($arr) == false) {
                 $owner->getDI()->getDb()->rollback();
                 $this->ignoreEvent = false;
                 return false;
             }
         }
         $this->ignoreEvent = false;
         $this->shiftLeftRight($right + 1, $left - $right - 1);
         $owner->getDI()->getDb()->commit();
     } else {
         $delta = $right - $left + 1;
         $this->shiftLeftRight($key, $delta);
         if ($left >= $key) {
             $left += $delta;
             $right += $delta;
         }
         $condition = $this->leftAttribute . '>=' . $left . ' AND ' . $this->rightAttribute . '<=' . $right;
         if ($this->hasManyRoots) {
             $condition .= ' AND ' . $this->rootAttribute . '=' . $owner->{$this->rootAttribute};
         }
         $this->ignoreEvent = true;
         foreach ($owner::find($condition) as $i) {
             if ($i->update(array($this->levelAttribute => $i->{$this->levelAttribute} + $levelDelta)) == false) {
                 $owner->getDI()->getDb()->rollback();
                 $this->ignoreEvent = false;
                 return false;
             }
         }
         foreach (array($this->leftAttribute, $this->rightAttribute) as $attribute) {
             $condition = $attribute . '>=' . $left . ' AND ' . $attribute . '<=' . $right;
             if ($this->hasManyRoots) {
                 $condition .= ' AND ' . $this->rootAttribute . '=' . $owner->{$this->rootAttribute};
             }
             foreach ($owner::find($condition) as $i) {
                 if ($i->update(array($attribute => $i->{$attribute} + $key - $left)) == false) {
                     $owner->getDI()->getDb()->rollback();
                     $this->ignoreEvent = false;
                     return false;
                 }
             }
         }
         $this->ignoreEvent = false;
         $this->shiftLeftRight($right + 1, -$delta);
         $owner->getDI()->getDb()->commit();
     }
     return true;
 }
Esempio n. 2
0
 /**
  * @param  ModelInterface $target
  * @param  int $key
  * @param  int $levelUp
  *
  * @return boolean
  * @throws Exception
  */
 private function moveNode(ModelInterface $target, $key, $levelUp)
 {
     $owner = $this->getOwner();
     if ($this->getIsNewRecord()) {
         throw new Exception('The node should not be new record.');
     }
     if ($this->getIsDeletedRecord()) {
         throw new Exception('The node should not be deleted.');
     }
     if ($target->getIsDeletedRecord()) {
         throw new Exception('The target node should not be deleted.');
     }
     if ($owner == $target) {
         throw new Exception('The target node should not be self.');
     }
     if ($target->isDescendantOf($owner)) {
         throw new Exception('The target node should not be descendant.');
     }
     if (!$levelUp && $target->isRoot()) {
         throw new Exception('The target node should not be root.');
     }
     $this->db->begin();
     $left = $owner->{$this->leftAttribute};
     $right = $owner->{$this->rightAttribute};
     $levelDelta = $target->{$this->levelAttribute} - $owner->{$this->levelAttribute} + $levelUp;
     if ($this->hasManyRoots && $owner->{$this->rootAttribute} !== $target->{$this->rootAttribute}) {
         $this->ignoreEvent = true;
         // 1. Rebuild the target tree
         foreach ([$this->leftAttribute, $this->rightAttribute] as $attribute) {
             $condition = join(' AND ', [$attribute . '>=' . $key, $this->rootAttribute . '=' . $target->{$this->rootAttribute}]);
             foreach ($target::find($condition) as $i) {
                 $delta = $right - $left + 1;
                 /** @var ModelInterface $i */
                 if (!$i->update([$attribute => $i->{$attribute} + $delta])) {
                     $this->db->rollback();
                     $this->ignoreEvent = false;
                     return false;
                 }
             }
         }
         $delta = $key - $left;
         // 2. Rebuild the owner's tree of children (owner sub-tree)
         $condition = $this->leftAttribute . '>=' . $left . ' AND ';
         $condition .= $this->rightAttribute . '<=' . $right . ' AND ';
         $condition .= $this->rootAttribute . '=' . $owner->{$this->rootAttribute};
         foreach ($owner::find($condition) as $i) {
             $arr = [$this->leftAttribute => $i->{$this->leftAttribute} + $delta, $this->rightAttribute => $i->{$this->rightAttribute} + $delta, $this->levelAttribute => $i->{$this->levelAttribute} + $levelDelta, $this->rootAttribute => $target->{$this->rootAttribute}];
             if ($i->update($arr) == false) {
                 $this->db->rollback();
                 $this->ignoreEvent = false;
                 return false;
             }
         }
         // 3. Rebuild the owner tree
         $this->shiftLeftRight($right + 1, $left - $right - 1, $owner);
         $this->ignoreEvent = false;
         $this->db->commit();
     } else {
         $delta = $right - $left + 1;
         $this->ignoreEvent = true;
         $this->shiftLeftRight($key, $delta);
         if ($left >= $key) {
             $left += $delta;
             $right += $delta;
         }
         $condition = $this->leftAttribute . '>=' . $left . ' AND ' . $this->rightAttribute . '<=' . $right;
         if ($this->hasManyRoots) {
             $condition .= ' AND ' . $this->rootAttribute . '=' . $owner->{$this->rootAttribute};
         }
         foreach ($owner::find($condition) as $i) {
             if ($i->update([$this->levelAttribute => $i->{$this->levelAttribute} + $levelDelta]) == false) {
                 $this->db->rollback();
                 $this->ignoreEvent = false;
                 return false;
             }
         }
         foreach ([$this->leftAttribute, $this->rightAttribute] as $attribute) {
             $condition = $attribute . '>=' . $left . ' AND ' . $attribute . '<=' . $right;
             if ($this->hasManyRoots) {
                 $condition .= ' AND ' . $this->rootAttribute . '=' . $owner->{$this->rootAttribute};
             }
             foreach ($owner::find($condition) as $i) {
                 if ($i->update([$attribute => $i->{$attribute} + $key - $left]) == false) {
                     $this->db->rollback();
                     $this->ignoreEvent = false;
                     return false;
                 }
             }
         }
         $this->shiftLeftRight($right + 1, -$delta);
         $this->ignoreEvent = false;
         $this->ignoreEvent = false;
         $this->db->commit();
     }
     return true;
 }