Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
move find threaded logic to the set class
  • Loading branch information
AD7six committed Jan 9, 2012
1 parent b8598c5 commit 7b640b8
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 49 deletions.
43 changes: 6 additions & 37 deletions lib/Cake/Model/Model.php
Expand Up @@ -2812,43 +2812,12 @@ protected function _findThreaded($state, $query, $results = array()) {
if ($state === 'before') {
return $query;
} elseif ($state === 'after') {
$return = $idMap = array();
$ids = Set::extract($results, '{n}.' . $this->alias . '.' . $this->primaryKey);

foreach ($results as $result) {
$result['children'] = array();
$id = $result[$this->alias][$this->primaryKey];
if (!isset($result[$this->alias]['parent_id'])) {
trigger_error(
__d('cake_dev', 'You cannot use find("threaded") on models without a "parent_id" field.'),
E_USER_WARNING
);
return $return;
}
$parentId = $result[$this->alias]['parent_id'];
if (isset($idMap[$id]['children'])) {
$idMap[$id] = array_merge($result, (array)$idMap[$id]);
} else {
$idMap[$id] = array_merge($result, array('children' => array()));
}
if (!$parentId || !in_array($parentId, $ids)) {
$return[] =& $idMap[$id];
} else {
$idMap[$parentId]['children'][] =& $idMap[$id];
}
}
if (count($return) > 1) {
$ids = array_unique(Set::extract('/' . $this->alias . '/parent_id', $return));
if (count($ids) > 1) {
$root = $return[0][$this->alias]['parent_id'];
foreach ($return as $key => $value) {
if ($value[$this->alias]['parent_id'] != $root) {
unset($return[$key]);
}
}
}
}
return $return;
return Set::nest($results, array(
'alias' => $this->alias,
'primaryKey' => $this->primaryKey,
'parent' => 'parent_id',
'children' => 'children'
));
}
}

Expand Down
12 changes: 0 additions & 12 deletions lib/Cake/Test/Case/Model/ModelReadTest.php
Expand Up @@ -2990,18 +2990,6 @@ public function testSelfAssociationAfterFind() {
$this->assertEquals($afterFindData, $noAfterFindData);
}

/**
* find(threaded) should trigger errors whne there is no parent_id field.
*
* @expectedException PHPUnit_Framework_Error_Warning
* @return void
*/
public function testFindThreadedError() {
$this->loadFixtures('Apple', 'Sample');
$Apple = new Apple();
$Apple->find('threaded');
}

/**
* testFindAllThreaded method
*
Expand Down
60 changes: 60 additions & 0 deletions lib/Cake/Utility/Set.php
Expand Up @@ -1114,4 +1114,64 @@ public static function apply($path, $data, $callback, $options = array()) {
}
return null;
}

/**
* Takes in a flat 2 dimensional array and returns a nested array
*
* @param mixed $data
* @param array $options Options are:
* alias - the first array key to look for
* primaryKey - the key to use to identify the rows
* parentId - the key to use to identify the parent
* children - the key name to use in the resultset for children
* @return array of results, nested
* @link
*/
public static function nest($data, $options = array()) {
if (!$data) {
return $data;
}

$options = array(
'alias' => key(current($data)),
'primaryKey' => 'id',
'parentId' => 'parent_id',
'children' => 'children'
) + $options;

$return = $idMap = array();
$ids = Set::extract($data, '{n}.' . $options['alias'] . '.' . $options['primaryKey']);

foreach ($data as $result) {
$result[$options['children']] = array();
$id = $result[$options['alias']][$options['primaryKey']];
if (isset($result[$options['alias']][$options['parentId']])) {
$parentId = $result[$options['alias']][$options['parentId']];
} else {
$parentId = null;
}
if (isset($idMap[$id]['children'])) {
$idMap[$id] = array_merge($result, (array)$idMap[$id]);
} else {
$idMap[$id] = array_merge($result, array('children' => array()));
}
if (!$parentId || !in_array($parentId, $ids)) {
$return[] =& $idMap[$id];
} else {
$idMap[$parentId]['children'][] =& $idMap[$id];
}
}
if (count($return) > 1) {
$ids = array_unique(Set::extract('/' . $options['alias'] . '/' . $options['parentId'], $return));
if (count($ids) > 1) {
$root = $return[0][$options['alias']][$options['parentId']];
foreach ($return as $key => $value) {
if ($value[$options['alias']][$options['parentId']] != $root) {
unset($return[$key]);
}
}
}
}
return $return;
}
}

0 comments on commit 7b640b8

Please sign in to comment.