Browse Source

Fixes #802: Added support for retrieving sub-array element or child object property through `ArrayHelper::getValue()`

tags/2.0.0-beta
Qiang Xue 11 years ago
parent
commit
9e66e08bc7
  1. 1
      framework/CHANGELOG.md
  2. 29
      framework/yii/helpers/BaseArrayHelper.php
  3. 58
      tests/unit/framework/helpers/ArrayHelperTest.php

1
framework/CHANGELOG.md

@ -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)
- 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 #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 #1406: DB Schema support for Oracle Database (p0larbeer, qiangxue)
- Enh #1437: Added ListView::viewParams (qiangxue)

29
framework/yii/helpers/BaseArrayHelper.php

@ -123,7 +123,14 @@ class BaseArrayHelper
/**
* 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,
*
@ -136,6 +143,8 @@ class BaseArrayHelper
* $fullName = \yii\helpers\ArrayHelper::getValue($user, function($user, $defaultValue) {
* 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
@ -144,15 +153,29 @@ class BaseArrayHelper
* `function($array, $defaultValue)`.
* @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
* @throws InvalidParamException if $array is neither an array nor an object.
*/
public static function getValue($array, $key, $default = null)
{
if ($key instanceof \Closure) {
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)) {
return isset($array[$key]) || array_key_exists($key, $array) ? $array[$key] : $default;
return array_key_exists($key, $array) ? $array[$key] : $default;
} else {
return $array->$key;
return $default;
}
}

58
tests/unit/framework/helpers/ArrayHelperTest.php

@ -320,4 +320,62 @@ class ArrayHelperTest extends TestCase
$this->assertTrue(ArrayHelper::keyExists('B', $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));
}
}

Loading…
Cancel
Save