Commit 9e66e08b by Qiang Xue

Fixes #802: Added support for retrieving sub-array element or child object…

Fixes #802: Added support for retrieving sub-array element or child object property through `ArrayHelper::getValue()`
parent 9fd94872
...@@ -26,6 +26,7 @@ Yii Framework 2 Change Log ...@@ -26,6 +26,7 @@ Yii Framework 2 Change Log
- Bug: Fixed the issue that query cache returns the same data for the same SQL but different query methods (qiangxue) - Bug: Fixed the issue that query cache returns the same data for the same SQL but different query methods (qiangxue)
- Enh #364: Improve Inflector::slug with `intl` transliteration. Improved transliteration char map. (tonydspaniard) - Enh #364: Improve Inflector::slug with `intl` transliteration. Improved transliteration char map. (tonydspaniard)
- Enh #797: Added support for validating multiple columns by `UniqueValidator` and `ExistValidator` (qiangxue) - Enh #797: Added support for validating multiple columns by `UniqueValidator` and `ExistValidator` (qiangxue)
- Enh #802: Added support for retrieving sub-array element or child object property through `ArrayHelper::getValue()` (qiangxue, cebe)
- Enh #1293: Replaced Console::showProgress() with a better approach. See Console::startProgress() for details (cebe) - Enh #1293: Replaced Console::showProgress() with a better approach. See Console::startProgress() for details (cebe)
- Enh #1406: DB Schema support for Oracle Database (p0larbeer, qiangxue) - Enh #1406: DB Schema support for Oracle Database (p0larbeer, qiangxue)
- Enh #1437: Added ListView::viewParams (qiangxue) - Enh #1437: Added ListView::viewParams (qiangxue)
......
...@@ -123,7 +123,14 @@ class BaseArrayHelper ...@@ -123,7 +123,14 @@ class BaseArrayHelper
/** /**
* Retrieves the value of an array element or object property with the given key or property name. * Retrieves the value of an array element or object property with the given key or property name.
* If the key does not exist in the array, the default value will be returned instead. * If the key does not exist in the array or object, the default value will be returned instead.
*
* The key may be specified in a dot format to retrieve the value of a sub-array or the property
* of an embedded object. In particular, if the key is `x.y.z`, then the returned value would
* be `$array['x']['y']['z']` or `$array->x->y->z` (if `$array` is an object). If `$array['x']`
* or `$array->x` is neither an array nor an object, the default value will be returned.
* Note that if the array already has an element `x.y.z`, then its value will be returned
* instead of going through the sub-arrays.
* *
* Below are some usage examples, * Below are some usage examples,
* *
...@@ -136,6 +143,8 @@ class BaseArrayHelper ...@@ -136,6 +143,8 @@ class BaseArrayHelper
* $fullName = \yii\helpers\ArrayHelper::getValue($user, function($user, $defaultValue) { * $fullName = \yii\helpers\ArrayHelper::getValue($user, function($user, $defaultValue) {
* return $user->firstName . ' ' . $user->lastName; * return $user->firstName . ' ' . $user->lastName;
* }); * });
* // using dot format to retrieve the property of embedded object
* $street = \yii\helpers\ArrayHelper::getValue($users, 'address.street');
* ~~~ * ~~~
* *
* @param array|object $array array or object to extract value from * @param array|object $array array or object to extract value from
...@@ -144,15 +153,29 @@ class BaseArrayHelper ...@@ -144,15 +153,29 @@ class BaseArrayHelper
* `function($array, $defaultValue)`. * `function($array, $defaultValue)`.
* @param mixed $default the default value to be returned if the specified key does not exist * @param mixed $default the default value to be returned if the specified key does not exist
* @return mixed the value of the element if found, default value otherwise * @return mixed the value of the element if found, default value otherwise
* @throws InvalidParamException if $array is neither an array nor an object.
*/ */
public static function getValue($array, $key, $default = null) public static function getValue($array, $key, $default = null)
{ {
if ($key instanceof \Closure) { if ($key instanceof \Closure) {
return $key($array, $default); return $key($array, $default);
}
if (is_array($array) && array_key_exists($key, $array)) {
return $array[$key];
}
if (($pos = strrpos($key, '.')) !== false) {
$array = static::getValue($array, substr($key, 0, $pos), $default);
$key = substr($key, $pos + 1);
}
if (is_object($array)) {
return $array->$key;
} elseif (is_array($array)) { } elseif (is_array($array)) {
return isset($array[$key]) || array_key_exists($key, $array) ? $array[$key] : $default; return array_key_exists($key, $array) ? $array[$key] : $default;
} else { } else {
return $array->$key; return $default;
} }
} }
......
...@@ -320,4 +320,62 @@ class ArrayHelperTest extends TestCase ...@@ -320,4 +320,62 @@ class ArrayHelperTest extends TestCase
$this->assertTrue(ArrayHelper::keyExists('B', $array, false)); $this->assertTrue(ArrayHelper::keyExists('B', $array, false));
$this->assertFalse(ArrayHelper::keyExists('c', $array, false)); $this->assertFalse(ArrayHelper::keyExists('c', $array, false));
} }
public function valueProvider()
{
return [
['name', 'test'],
['noname', null],
['noname', 'test', 'test'],
['post.id', 5],
['post.id', 5, 'test'],
['nopost.id', null],
['nopost.id', 'test', 'test'],
['post.author.name', 'cebe'],
['post.author.noname', null],
['post.author.noname', 'test', 'test'],
['post.author.profile.title', '1337'],
['admin.firstname', 'Qiang'],
['admin.firstname', 'Qiang', 'test'],
['admin.lastname', 'Xue'],
[
function ($array, $defaultValue) {
return $array['date'] . $defaultValue;
},
'31-12-2113test',
'test'
],
];
}
/**
* @dataProvider valueProvider
*
* @param $key
* @param $expected
* @param null $default
*/
public function testGetValue($key, $expected, $default = null)
{
$array = [
'name' => 'test',
'date' => '31-12-2113',
'post' => [
'id' => 5,
'author' => [
'name' => 'cebe',
'profile' => [
'title' => '1337',
],
],
],
'admin.firstname' => 'Qiang',
'admin.lastname' => 'Xue',
'admin' => [
'lastname' => 'cebe',
],
];
$this->assertEquals($expected, ArrayHelper::getValue($array, $key, $default));
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment