From 45be270a7b40d063d576e75aa100604a8e90237b Mon Sep 17 00:00:00 2001 From: Rachman Chavik Date: Tue, 7 Oct 2014 13:20:57 +0700 Subject: [PATCH] Enable use of Containable with TreeBehaviors This patch allows Containable use with: - TreeBehavior::getParentNode() - TreeBehavior::children() - TreeBehavior::getPath() --- lib/Cake/Model/Behavior/TreeBehavior.php | 50 ++++++++++++++++--- .../Test/Case/Model/ModelIntegrationTest.php | 26 ++++++++++ 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/lib/Cake/Model/Behavior/TreeBehavior.php b/lib/Cake/Model/Behavior/TreeBehavior.php index fc4379aec..11bbb5bb1 100644 --- a/lib/Cake/Model/Behavior/TreeBehavior.php +++ b/lib/Cake/Model/Behavior/TreeBehavior.php @@ -306,7 +306,9 @@ class TreeBehavior extends ModelBehavior { * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::children */ public function children(Model $Model, $id = null, $direct = false, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) { + $options = array(); if (is_array($id)) { + $options = $this->_getOptions($id); extract(array_merge(array('id' => null), $id)); } $overrideRecursive = $recursive; @@ -348,7 +350,10 @@ class TreeBehavior extends ModelBehavior { $Model->escapeField($left) . ' >' => $result[0][$left] ); } - return $Model->find('all', compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive')); + $options = array_merge(compact( + 'conditions', 'fields', 'order', 'limit', 'page', 'recursive' + ), $options); + return $Model->find('all', $options); } /** @@ -426,7 +431,9 @@ class TreeBehavior extends ModelBehavior { * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::getParentNode */ public function getParentNode(Model $Model, $id = null, $fields = null, $recursive = null) { + $options = array(); if (is_array($id)) { + $options = $this->_getOptions($id); extract(array_merge(array('id' => null), $id)); } $overrideRecursive = $recursive; @@ -446,18 +453,32 @@ class TreeBehavior extends ModelBehavior { if ($parentId) { $parentId = $parentId[$Model->alias][$parent]; - $parent = $Model->find('first', array( + $options = array_merge(array( 'conditions' => array($Model->escapeField() => $parentId), 'fields' => $fields, 'order' => false, 'recursive' => $recursive - )); + ), $options); + $parent = $Model->find('first', $options); return $parent; } return false; } +/** + * Convenience method to create default find() options from $arg when it is an + * associative array. + * + * @param array $arg Array + * @return array Options array + */ + protected function _getOptions($arg) { + return count(array_filter(array_keys($arg), 'is_string') > 0) ? + $arg : + array(); + } + /** * Get the path to the given node * @@ -469,9 +490,21 @@ class TreeBehavior extends ModelBehavior { * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::getPath */ public function getPath(Model $Model, $id = null, $fields = null, $recursive = null) { + $options = array(); if (is_array($id)) { + $options = $this->_getOptions($id); extract(array_merge(array('id' => null), $id)); } + + if (!empty($options)) { + $fields = null; + if (!empty($options['fields'])) { + $fields = $options['fields']; + } + if (!empty($options['recursive'])) { + $recursive = $options['recursive']; + } + } $overrideRecursive = $recursive; if (empty($id)) { $id = $Model->id; @@ -492,12 +525,17 @@ class TreeBehavior extends ModelBehavior { return array(); } $item = $result[0]; - $results = $Model->find('all', array( - 'conditions' => array($scope, $Model->escapeField($left) . ' <=' => $item[$left], $Model->escapeField($right) . ' >=' => $item[$right]), + $options = array_merge(array( + 'conditions' => array( + $scope, + $Model->escapeField($left) . ' <=' => $item[$left], + $Model->escapeField($right) . ' >=' => $item[$right], + ), 'fields' => $fields, 'order' => array($Model->escapeField($left) => 'asc'), 'recursive' => $recursive - )); + ), $options); + $results = $Model->find('all', $options); return $results; } diff --git a/lib/Cake/Test/Case/Model/ModelIntegrationTest.php b/lib/Cake/Test/Case/Model/ModelIntegrationTest.php index 4ec77e6d0..839af6671 100644 --- a/lib/Cake/Test/Case/Model/ModelIntegrationTest.php +++ b/lib/Cake/Test/Case/Model/ModelIntegrationTest.php @@ -239,6 +239,32 @@ class ModelIntegrationTest extends BaseModelTest { $this->assertFalse(isset($TestModel->Behaviors->Tree)); } +/** + * testTreeWithContainable method + * + * @return void + */ + public function testTreeWithContainable() { + $this->loadFixtures('Ad', 'Campaign'); + $TestModel = new Ad(); + $TestModel->Behaviors->load('Tree'); + $TestModel->Behaviors->load('Containable'); + + $node = $TestModel->findById(2); + $node['Ad']['parent_id'] = 1; + $TestModel->save($node); + + $result = $TestModel->getParentNode(array('id' => 2, 'contain' => 'Campaign')); + $this->assertTrue(array_key_exists('Campaign', $result)); + + $result = $TestModel->children(array('id' => 1, 'contain' => 'Campaign')); + $this->assertTrue(array_key_exists('Campaign', $result[0])); + + $result = $TestModel->getPath(array('id' => 2, 'contain' => 'Campaign')); + $this->assertTrue(array_key_exists('Campaign', $result[0])); + $this->assertTrue(array_key_exists('Campaign', $result[1])); + } + /** * testFindWithJoinsOption method *