Browse Source

make tree recovery much, much simpler

Andy Dawson 13 years ago
parent
commit
8ea0212265
1 changed files with 57 additions and 13 deletions
  1. 57 13
      lib/Cake/Model/Behavior/TreeBehavior.php

+ 57 - 13
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) {
@@ -655,6 +644,61 @@ class TreeBehavior extends ModelBehavior {
 	}
 
 /**
+ * _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.
  *
  * Reorders the nodes (and child nodes) of the tree according to the field and direction specified in the parameters.