mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-31 09:06:17 +00:00
WIP, adding sort() and remove()
This commit is contained in:
parent
31181f58d6
commit
e72127e359
2 changed files with 277 additions and 4 deletions
|
@ -626,7 +626,7 @@ class Set2Test extends CakeTestCase {
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testExtractNumbericMixedKeys() {
|
public function testExtractNumericMixedKeys() {
|
||||||
$data = array(
|
$data = array(
|
||||||
'User' => array(
|
'User' => array(
|
||||||
0 => array(
|
0 => array(
|
||||||
|
@ -796,4 +796,197 @@ class Set2Test extends CakeTestCase {
|
||||||
$this->assertEquals($expected, $result);
|
$this->assertEquals($expected, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testSort method
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSort() {
|
||||||
|
$this->markTestIncomplete('Not done, sort() is broken.');
|
||||||
|
$a = array(
|
||||||
|
0 => array(
|
||||||
|
'Person' => array('name' => 'Jeff'),
|
||||||
|
'Friend' => array(array('name' => 'Nate'))
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'Person' => array('name' => 'Tracy'),
|
||||||
|
'Friend' => array(array('name' => 'Lindsay'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$b = array(
|
||||||
|
0 => array(
|
||||||
|
'Person' => array('name' => 'Tracy'),
|
||||||
|
'Friend' => array(array('name' => 'Lindsay'))
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'Person' => array('name' => 'Jeff'),
|
||||||
|
'Friend' => array(array('name' => 'Nate'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$a = Set2::sort($a, '{n}.Friend.{n}.name', 'asc');
|
||||||
|
$this->assertEquals($a, $b);
|
||||||
|
|
||||||
|
$b = array(
|
||||||
|
0 => array(
|
||||||
|
'Person' => array('name' => 'Jeff'),
|
||||||
|
'Friend' => array(array('name' => 'Nate'))
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'Person' => array('name' => 'Tracy'),
|
||||||
|
'Friend' => array(array('name' => 'Lindsay'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$a = array(
|
||||||
|
0 => array(
|
||||||
|
'Person' => array('name' => 'Tracy'),
|
||||||
|
'Friend' => array(array('name' => 'Lindsay'))
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'Person' => array('name' => 'Jeff'),
|
||||||
|
'Friend' => array(array('name' => 'Nate'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$a = Set2::sort($a, '{n}.Friend.{n}.name', 'desc');
|
||||||
|
$this->assertEquals($a, $b);
|
||||||
|
|
||||||
|
$a = array(
|
||||||
|
0 => array(
|
||||||
|
'Person' => array('name' => 'Jeff'),
|
||||||
|
'Friend' => array(array('name' => 'Nate'))
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'Person' => array('name' => 'Tracy'),
|
||||||
|
'Friend' => array(array('name' => 'Lindsay'))
|
||||||
|
),
|
||||||
|
2 => array(
|
||||||
|
'Person' => array('name' => 'Adam'),
|
||||||
|
'Friend' => array(array('name' => 'Bob'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$b = array(
|
||||||
|
0 => array(
|
||||||
|
'Person' => array('name' => 'Adam'),
|
||||||
|
'Friend' => array(array('name' => 'Bob'))
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'Person' => array('name' => 'Jeff'),
|
||||||
|
'Friend' => array(array('name' => 'Nate'))
|
||||||
|
),
|
||||||
|
2 => array(
|
||||||
|
'Person' => array('name' => 'Tracy'),
|
||||||
|
'Friend' => array(array('name' => 'Lindsay'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$a = Set2::sort($a, '{n}.Person.name', 'asc');
|
||||||
|
$this->assertEquals($a, $b);
|
||||||
|
|
||||||
|
$a = array(
|
||||||
|
array(7,6,4),
|
||||||
|
array(3,4,5),
|
||||||
|
array(3,2,1),
|
||||||
|
);
|
||||||
|
|
||||||
|
$b = array(
|
||||||
|
array(3,2,1),
|
||||||
|
array(3,4,5),
|
||||||
|
array(7,6,4),
|
||||||
|
);
|
||||||
|
|
||||||
|
$a = Set2::sort($a, '{n}.{n}', 'asc');
|
||||||
|
$this->assertEquals($a, $b);
|
||||||
|
|
||||||
|
$a = array(
|
||||||
|
array(7,6,4),
|
||||||
|
array(3,4,5),
|
||||||
|
array(3,2,array(1,1,1)),
|
||||||
|
);
|
||||||
|
|
||||||
|
$b = array(
|
||||||
|
array(3,2,array(1,1,1)),
|
||||||
|
array(3,4,5),
|
||||||
|
array(7,6,4),
|
||||||
|
);
|
||||||
|
|
||||||
|
$a = Set2::sort($a, '{n}', 'asc');
|
||||||
|
$this->assertEquals($a, $b);
|
||||||
|
|
||||||
|
$a = array(
|
||||||
|
0 => array('Person' => array('name' => 'Jeff')),
|
||||||
|
1 => array('Shirt' => array('color' => 'black'))
|
||||||
|
);
|
||||||
|
$b = array(
|
||||||
|
0 => array('Shirt' => array('color' => 'black')),
|
||||||
|
1 => array('Person' => array('name' => 'Jeff')),
|
||||||
|
);
|
||||||
|
$a = Set2::sort($a, '{n}.Person.name', 'ASC');
|
||||||
|
$this->assertEquals($a, $b);
|
||||||
|
|
||||||
|
$names = array(
|
||||||
|
array('employees' => array(
|
||||||
|
array('name' => array('first' => 'John', 'last' => 'Doe')))
|
||||||
|
),
|
||||||
|
array('employees' => array(
|
||||||
|
array('name' => array('first' => 'Jane', 'last' => 'Doe')))
|
||||||
|
),
|
||||||
|
array('employees' => array(array('name' => array()))),
|
||||||
|
array('employees' => array(array('name' => array())))
|
||||||
|
);
|
||||||
|
$result = Set2::sort($names, '{n}.employees.0.name', 'asc', 1);
|
||||||
|
$expected = array(
|
||||||
|
array('employees' => array(
|
||||||
|
array('name' => array('first' => 'John', 'last' => 'Doe')))
|
||||||
|
),
|
||||||
|
array('employees' => array(
|
||||||
|
array('name' => array('first' => 'Jane', 'last' => 'Doe')))
|
||||||
|
),
|
||||||
|
array('employees' => array(array('name' => array()))),
|
||||||
|
array('employees' => array(array('name' => array())))
|
||||||
|
);
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test sorting with out of order keys.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSortWithOutOfOrderKeys() {
|
||||||
|
$data = array(
|
||||||
|
9 => array('class' => 510, 'test2' => 2),
|
||||||
|
1 => array('class' => 500, 'test2' => 1),
|
||||||
|
2 => array('class' => 600, 'test2' => 2),
|
||||||
|
5 => array('class' => 625, 'test2' => 4),
|
||||||
|
0 => array('class' => 605, 'test2' => 3),
|
||||||
|
);
|
||||||
|
$expected = array(
|
||||||
|
array('class' => 500, 'test2' => 1),
|
||||||
|
array('class' => 510, 'test2' => 2),
|
||||||
|
array('class' => 600, 'test2' => 2),
|
||||||
|
array('class' => 605, 'test2' => 3),
|
||||||
|
array('class' => 625, 'test2' => 4),
|
||||||
|
);
|
||||||
|
$result = Set2::sort($data, '{n}.class', 'asc');
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
|
||||||
|
$result = Set2::sort($data, '{n}.test2', 'asc');
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test remove()
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testRemove() {
|
||||||
|
$data = self::articleData();
|
||||||
|
|
||||||
|
$result = Set2::insert($data, '{n}.Article', array('test'));
|
||||||
|
debug($result);
|
||||||
|
|
||||||
|
$result = Set2::remove($data, '{n}.Article');
|
||||||
|
debug($result);
|
||||||
|
$this->assertFalse(isset($data[0]['Article']));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@ App::uses('String', 'Utility');
|
||||||
*
|
*
|
||||||
* `Set2` provides an improved interface and more consistent and
|
* `Set2` provides an improved interface and more consistent and
|
||||||
* predictable set of features over `Set`. While it lacks the spotty
|
* predictable set of features over `Set`. While it lacks the spotty
|
||||||
* support for pseudo Xpath, its more fully feature dot notation provides
|
* support for pseudo Xpath, its more fully featured dot notation provides
|
||||||
* the same utility.
|
* the similar features in a more consistent way.
|
||||||
*
|
*
|
||||||
* @package Cake.Utility
|
* @package Cake.Utility
|
||||||
*/
|
*/
|
||||||
|
@ -137,8 +137,9 @@ class Set2 {
|
||||||
// any numeric key
|
// any numeric key
|
||||||
foreach ($item as $k => $v) {
|
foreach ($item as $k => $v) {
|
||||||
if (is_numeric($k)) {
|
if (is_numeric($k)) {
|
||||||
$next[] = $v;
|
$next[] =& $v;
|
||||||
}
|
}
|
||||||
|
unset($v);
|
||||||
}
|
}
|
||||||
} elseif ($token === '{s}') {
|
} elseif ($token === '{s}') {
|
||||||
// any string key
|
// any string key
|
||||||
|
@ -146,6 +147,7 @@ class Set2 {
|
||||||
if (is_string($k)) {
|
if (is_string($k)) {
|
||||||
$next[] = $v;
|
$next[] = $v;
|
||||||
}
|
}
|
||||||
|
unset($v);
|
||||||
}
|
}
|
||||||
} elseif (is_numeric($token)) {
|
} elseif (is_numeric($token)) {
|
||||||
// numeric keys like 0, 1, 2
|
// numeric keys like 0, 1, 2
|
||||||
|
@ -153,6 +155,7 @@ class Set2 {
|
||||||
if ($k == $token) {
|
if ($k == $token) {
|
||||||
$next[] = $v;
|
$next[] = $v;
|
||||||
}
|
}
|
||||||
|
unset($v);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// bare string key
|
// bare string key
|
||||||
|
@ -161,6 +164,7 @@ class Set2 {
|
||||||
if ($k === $token) {
|
if ($k === $token) {
|
||||||
$next[] = $v;
|
$next[] = $v;
|
||||||
}
|
}
|
||||||
|
unset($v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,11 +245,33 @@ class Set2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function insert(array $data, $path, $values = null) {
|
public static function insert(array $data, $path, $values = null) {
|
||||||
|
if (empty($path)) {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = self::_traverse($data, $path, function (&$value) use ($values) {
|
||||||
|
$value['test'] = $values;
|
||||||
|
return $value;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove data matching $path from the $data array.
|
||||||
|
*
|
||||||
|
* @param array $data The data to operate on
|
||||||
|
* @param string $path A path expression to use to remove.
|
||||||
|
* @return array The modified array.
|
||||||
|
*/
|
||||||
public static function remove(array $data, $path) {
|
public static function remove(array $data, $path) {
|
||||||
|
if (empty($path)) {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::_traverse($data, $path, function ($value) {
|
||||||
|
return $value;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function combine(array $data, $keyPath, $valuePath = null) {
|
public static function combine(array $data, $keyPath, $valuePath = null) {
|
||||||
|
@ -464,8 +490,62 @@ class Set2 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts an array by any value, determined by a Set-compatible path
|
||||||
|
*
|
||||||
|
* @param array $data An array of data to sort
|
||||||
|
* @param string $path A Set-compatible path to the array value
|
||||||
|
* @param string $dir Direction of sorting - either ascending (ASC), or descending (DESC)
|
||||||
|
* @return array Sorted array of data
|
||||||
|
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::sort
|
||||||
|
*/
|
||||||
public static function sort(array $data, $path, $dir) {
|
public static function sort(array $data, $path, $dir) {
|
||||||
|
$originalKeys = array_keys($data);
|
||||||
|
if (is_numeric(implode('', $originalKeys))) {
|
||||||
|
$data = array_values($data);
|
||||||
|
}
|
||||||
|
$result = self::_squash(self::extract($data, $path));
|
||||||
|
$keys = self::extract($result, '{n}.id');
|
||||||
|
$values = self::extract($result, '{n}.value');
|
||||||
|
|
||||||
|
$dir = strtolower($dir);
|
||||||
|
if ($dir === 'asc') {
|
||||||
|
$dir = SORT_ASC;
|
||||||
|
} elseif ($dir === 'desc') {
|
||||||
|
$dir = SORT_DESC;
|
||||||
|
}
|
||||||
|
array_multisort($values, $dir, $keys, $dir);
|
||||||
|
$sorted = array();
|
||||||
|
$keys = array_unique($keys);
|
||||||
|
|
||||||
|
foreach ($keys as $k) {
|
||||||
|
$sorted[] = $data[$k];
|
||||||
|
}
|
||||||
|
return $sorted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for sort()
|
||||||
|
* Sqaushes an array to a single hash so it can be sorted.
|
||||||
|
*
|
||||||
|
* @param array $data The data to squash.
|
||||||
|
* @param string $key The key for the data.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected static function _squash($data, $key = null) {
|
||||||
|
$stack = array();
|
||||||
|
foreach ($data as $k => $r) {
|
||||||
|
$id = $k;
|
||||||
|
if (!is_null($key)) {
|
||||||
|
$id = $key;
|
||||||
|
}
|
||||||
|
if (is_array($r) && !empty($r)) {
|
||||||
|
$stack = array_merge($stack, self::_squash($r, $id));
|
||||||
|
} else {
|
||||||
|
$stack[] = array('id' => $id, 'value' => $r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue