diff --git a/cake/libs/set.php b/cake/libs/set.php index eaa867700..0986e4567 100644 --- a/cake/libs/set.php +++ b/cake/libs/set.php @@ -230,7 +230,7 @@ class Set extends Object { $out = get_object_vars($out); } $out[$key] = Set::__map($value, $class, true); - } elseif ($primary === true && is_array($value)) { + } elseif ($primary === true && is_array($value)) { $out->_name_ = $key; $primary = false; foreach($value as $key2 => $value2) { @@ -371,14 +371,11 @@ class Set extends Object { if (is_object($data)) { $data = get_object_vars($data); } - if (!is_array($path)) { - if (strpos($path, '/') !== 0 && strpos($path, './') === false) { - $path = explode('.', $path); - } else { - } + $path = String::tokenize($path, '.', '{', '}'); } $tmp = array(); + if (!is_array($path) || empty($path)) { return null; } @@ -402,6 +399,32 @@ class Set extends Object { } } return $tmp; + } elseif ($key == '{s}') { + foreach ($data as $j => $val) { + if (is_string($j)) { + $tmpPath = array_slice($path, $i + 1); + if (empty($tmpPath)) { + $tmp[] = $val; + } else { + $tmp[] = Set::extract($val, $tmpPath); + } + } + } + return $tmp; + } elseif (false !== strpos($key,'{') && false !== strpos($key,'}')) { + $pattern = substr($key, 1, -1); + + foreach ($data as $j => $val) { + if (preg_match('/^'.$pattern.'/s', $j) !== 0) { + $tmpPath = array_slice($path, $i + 1); + if (empty($tmpPath)) { + $tmp[$j] = $val; + } else { + $tmp[$j] = Set::extract($val, $tmpPath); + } + } + } + return $tmp; } else { if (isset($data[$key])) { $data = $data[$key]; diff --git a/cake/tests/cases/libs/set.test.php b/cake/tests/cases/libs/set.test.php index 2611a877a..c8832593b 100644 --- a/cake/tests/cases/libs/set.test.php +++ b/cake/tests/cases/libs/set.test.php @@ -178,10 +178,62 @@ class SetTest extends UnitTestCase { $expected = array (array('Comment 10', 'Comment 11', 'Comment 12'), array('Comment 13', 'Comment 14'), null); $this->assertIdentical($result, $expected); - $a = array(array( '1day' => '20 sales'),array( '1day' => '2 sales')); + $a = array(array('1day' => '20 sales'), array('1day' => '2 sales')); $result = Set::extract($a, '{n}.1day'); $expected = array('20 sales', '2 sales'); $this->assertIdentical($result, $expected); + + $a = array( + 'pages' => array('name' => 'page'), + 'fruites' => array('name' => 'fruit'), + 0 => array('name' => 'zero') + ); + $result = Set::extract($a, '{s}.name'); + $expected = array('page','fruit'); + $this->assertIdentical($result, $expected); + + $a = array( + 0 => array('pages' => array('name' => 'page')), + 1 => array('fruites'=> array('name' => 'fruit')), + 'test' => array(array('name' => 'jippi')), + 'dot.test' => array(array('name' => 'jippi')) + ); + + $result = Set::extract($a, '{n}.{s}.name'); + $expected = array(0 => array('page'), 1 => array('fruit')); + $this->assertIdentical($result, $expected); + + $result = Set::extract($a, '{s}.{n}.name'); + $expected = array(array('jippi'), array('jippi')); + $this->assertIdentical($result, $expected); + + $result = Set::extract($a,'{\w+}.{\w+}.name'); + $expected = array(array('pages' => 'page'), array('fruites' => 'fruit'), 'test' => array('jippi'), 'dot.test' => array('jippi')); + $this->assertIdentical($result, $expected); + + $result = Set::extract($a,'{\d+}.{\w+}.name'); + $expected = array(array('pages' => 'page'), array('fruites' => 'fruit')); + $this->assertIdentical($result, $expected); + + $result = Set::extract($a,'{n}.{\w+}.name'); + $expected = array(array('pages' => 'page'), array('fruites' => 'fruit')); + $this->assertIdentical($result, $expected); + + $result = Set::extract($a,'{s}.{\d+}.name'); + $expected = array(array('jippi'), array('jippi')); + $this->assertIdentical($result, $expected); + + $result = Set::extract($a,'{s}'); + $expected = array(array(array('name' => 'jippi')), array(array('name' => 'jippi'))); + $this->assertIdentical($result, $expected); + + $result = Set::extract($a,'{[a-z]}'); + $expected = array('test' => array(array('name' => 'jippi')), 'dot.test' => array(array('name' => 'jippi'))); + $this->assertIdentical($result, $expected); + + $result = Set::extract($a, '{dot\.test}.{n}'); + $expected = array('dot.test' => array(array('name' => 'jippi'))); + $this->assertIdentical($result, $expected); } function testCheck() { @@ -519,7 +571,7 @@ class SetTest extends UnitTestCase { 'hasMany' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'dependent', 'exclusive', 'finderQuery', 'counterQuery'), 'hasAndBelongsToMany' => array('className', 'joinTable', 'with', 'foreignKey', 'associationForeignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'unique', 'finderQuery', 'deleteQuery', 'insertQuery')), '__associations' => array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany'), '__backAssociation' => array(), '__insertID' => null, '__numRows' => null, '__affectedRows' => null, - '__findMethods' => array('all' => true, 'first' => true, 'count' => true, 'neighbors' => true), '_log' => null); + '__findMethods' => array('all' => true, 'first' => true, 'count' => true, 'neighbors' => true, 'list' => true), '_log' => null); $result = Set::reverse($model); ksort($result);