Add helper function for checking if an object is an array-like object.

Added support for traversable objects in `BaseHtml` and `ArrayHelper`
This commit is contained in:
Sam Mousa
2016-02-24 11:59:01 +00:00
committed by SilverFire - Dmitry Naumenko
parent 80e9331fe0
commit 16a6af5fa8
5 changed files with 58 additions and 8 deletions

View File

@ -7,10 +7,11 @@ Yii Framework 2 Change Log
- Bug #9851: Fixed partial commit / rollback in nested transactions (sammousa)
- Bug #10946: Fixed parameters binding to the SQL query in `yii\db\mysqlSchema::findConstraints()` (silverfire)
- Enh #5469: Add mimetype validation by mask in FileValidator (kirsenn, samdark, silverfire)
- Enh #10487: `yii\helpers\BaseArrayHelper::index()` got a third parameter `$groupBy` to group the input array by the key in one or more dimensions (quantum13, silverfire, samdark)
- Enh #10451: Check of existence of `$_SERVER` in `\yii\web\Request` before using it (quantum13)
- Enh #10610: Added `BaseUrl::$urlManager` to be able to set URL manager used for creating URLs (samdark)
- Enh #10764: `yii\helpers\Html::tag()` and `::beginTag()` return content without any HTML when the `$tag` attribute is `false` or `null` (pana1990)
- Enh #10487: `yii\helpers\BaseArrayHelper::index()` got a third parameter `$groupBy` to group the input array by the key in one or more dimensions (quantum13, silverfire, samdark)
- Enh #10941: Added `yii\helpers\ArrayHelper::isTraversable`, added support for traversable selections for dropdownList, radioList and checkboxList in `yii\helpers\Html`.
- Chg: HTMLPurifier dependency updated to `~4.6` (samdark)
2.0.7 February 14, 2016

View File

@ -680,7 +680,7 @@ class BaseArrayHelper
* Check whether an array or [[\Traversable]] contains an element.
*
* This method does the same as the PHP function [in_array()](http://php.net/manual/en/function.in-array.php)
* but it does not only work for arrays but also objects that implement the [[\Traversable]] interface.
* but additionally works for objects that implement the [[\Traversable]] interface.
* @param mixed $needle The value to look for.
* @param array|\Traversable $haystack The set of values to search.
* @param boolean $strict Whether to enable strict (`===`) comparison.
@ -706,6 +706,21 @@ class BaseArrayHelper
return false;
}
/**
* Checks whether a variable is an array or [[\Traversable]].
*
* This method does the same as the PHP function [is_array()](http://php.net/manual/en/function.is-array.php)
* but additionally works objects that implement the [[\Traversable]] interface.
* @param mixed $var The variable being evaluated.
* @return boolean whether $var is array-like
* @see http://php.net/manual/en/function.is_array.php
* @since 2.0.8
*/
public static function isTraversable($var)
{
return is_array($var) || $var instanceof \Traversable;
}
/**
* Checks whether an array or [[\Traversable]] is a subset of another array or [[\Traversable]].
*

View File

@ -906,8 +906,8 @@ class BaseHtml
$index = 0;
foreach ($items as $value => $label) {
$checked = $selection !== null &&
(!is_array($selection) && !strcmp($value, $selection)
|| is_array($selection) && in_array($value, $selection));
(!ArrayHelper::isTraversable($selection) && !strcmp($value, $selection)
|| ArrayHelper::isTraversable($selection) && ArrayHelper::isIn($value, $selection));
if ($formatter !== null) {
$lines[] = call_user_func($formatter, $index, $label, $name, $checked, $value);
} else {
@ -984,8 +984,8 @@ class BaseHtml
$index = 0;
foreach ($items as $value => $label) {
$checked = $selection !== null &&
(!is_array($selection) && !strcmp($value, $selection)
|| is_array($selection) && in_array($value, $selection));
(!ArrayHelper::isTraversable($selection) && !strcmp($value, $selection)
|| ArrayHelper::isTraversable($selection) && ArrayHelper::isIn($value, $selection));
if ($formatter !== null) {
$lines[] = call_user_func($formatter, $index, $label, $name, $checked, $value);
} else {
@ -1737,8 +1737,8 @@ class BaseHtml
$attrs = isset($options[$key]) ? $options[$key] : [];
$attrs['value'] = (string) $key;
$attrs['selected'] = $selection !== null &&
(!is_array($selection) && !strcmp($key, $selection)
|| is_array($selection) && in_array($key, $selection));
(!ArrayHelper::isTraversable($selection) && !strcmp($key, $selection)
|| ArrayHelper::isTraversable($selection) && ArrayHelper::isIn($key, $selection));
$text = $encode ? static::encode($value) : $value;
if ($encodeSpaces) {
$text = str_replace(' ', ' ', $text);

View File

@ -664,5 +664,15 @@ class ArrayHelperTest extends TestCase
}
public function testIsArray()
{
$this->assertTrue(ArrayHelper::isTraversable(['a']));
$this->assertTrue(ArrayHelper::isTraversable(new \ArrayObject(['1'])));
$this->assertFalse(ArrayHelper::isTraversable(new \stdClass()));
$this->assertFalse(ArrayHelper::isTraversable("A,B,C"));
$this->assertFalse(ArrayHelper::isTraversable(12));
$this->assertFalse(false);
}
}

View File

@ -354,6 +354,14 @@ EOD;
</select>
EOD;
$this->assertEqualsWithoutLE($expected, Html::listBox('test', '', [], ['unselect' => '0']));
$expected = <<<EOD
<select name="test" size="4">
<option value="value1" selected>text1</option>
<option value="value2" selected>text2</option>
</select>
EOD;
$this->assertEqualsWithoutLE($expected, Html::listBox('test', new \ArrayObject(['value1', 'value2']), $this->getDataItems()));
}
public function testCheckboxList()
@ -402,6 +410,15 @@ EOD;
},
'tag' => false
]));
$this->assertEqualsWithoutLE($expected, Html::checkboxList('test', new \ArrayObject(['value2']), $this->getDataItems(), [
'item' => function ($index, $label, $name, $checked, $value) {
return $index . Html::label($label . ' ' . Html::checkbox($name, $checked, ['value' => $value]));
},
'tag' => false
]));
}
public function testRadioList()
@ -449,6 +466,13 @@ EOD;
},
'tag' => false
]));
$this->assertEqualsWithoutLE($expected, Html::radioList('test', new \ArrayObject(['value2']), $this->getDataItems(), [
'item' => function ($index, $label, $name, $checked, $value) {
return $index . Html::label($label . ' ' . Html::radio($name, $checked, ['value' => $value]));
},
'tag' => false
]));
}
public function testUl()