diff --git a/lib/Cake/Model/Behavior/TreeBehavior.php b/lib/Cake/Model/Behavior/TreeBehavior.php index b770aa6d6..b871d9ee6 100644 --- a/lib/Cake/Model/Behavior/TreeBehavior.php +++ b/lib/Cake/Model/Behavior/TreeBehavior.php @@ -627,19 +627,8 @@ class TreeBehavior extends ModelBehavior { $Model->updateAll(array($Model->escapeField($parent) => $missingParentAction), array($Model->escapeField($Model->primaryKey) => array_flip($missingParents))); } } - $count = 1; - foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey), 'order' => $left)) as $array) { - $lft = $count++; - $rght = $count++; - $Model->create(false); - $Model->id = $array[$Model->alias][$Model->primaryKey]; - $Model->save(array($left => $lft, $right => $rght), array('callbacks' => false, 'validate' => false)); - } - foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey, $parent), 'order' => $left)) as $array) { - $Model->create(false); - $Model->id = $array[$Model->alias][$Model->primaryKey]; - $this->_setParent($Model, $array[$Model->alias][$parent]); - } + + $this->_recoverByParentId($Model); } else { $db = ConnectionManager::getDataSource($Model->useDbConfig); foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey, $parent), 'order' => $left)) as $array) { @@ -654,6 +643,61 @@ class TreeBehavior extends ModelBehavior { return true; } +/** + * _recoverByParentId + * + * Recursive helper function used by recover + * + * @param Model $Model + * @param integer $counter + * @param mixed $parentId + * @return integer $counter + */ + protected function _recoverByParentId(Model $Model, $counter = 1, $parentId = null) { + if (!is_null($parentId)) { + $Model->updateAll( + array($this->settings[$Model->alias]['left'] => $counter), + array($Model->escapeField() => $parentId) + ); + $counter++; + } + + $params = array( + 'conditions' => array( + $this->settings[$Model->alias]['parent'] => $parentId + ), + 'fields' => array($Model->primaryKey), + 'page' => 1, + 'limit' => 100, + 'order' => array($Model->primaryKey) + ); + + $scope = $this->settings[$Model->alias]['scope']; + if ($scope && ($scope !== '1 = 1' && $scope !== true)) { + $conditions[] = $scope; + } + + while ($rows = $Model->find('all', $params)) { + foreach ($rows as $row) { + $counter = $this->_recoverByParentId($Model, $counter, $row[$Model->alias][$Model->primaryKey]); + } + $params['page']++; + if (count($rows) !== $params['limit']) { + break; + } + } + + if (!is_null($parentId)) { + $Model->updateAll( + array($this->settings[$Model->alias]['right'] => $counter), + array($Model->escapeField() => $parentId) + ); + $counter++; + } + + return $counter; + } + /** * Reorder method. *