Browse Source

Fix #18210: Allow strict comparison for multi-select inputs

tags/2.0.37
Alex 4 years ago committed by GitHub
parent
commit
e49a52f3a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      framework/CHANGELOG.md
  2. 19
      framework/helpers/BaseHtml.php
  3. 34
      tests/framework/helpers/HtmlTest.php

1
framework/CHANGELOG.md

@ -9,6 +9,7 @@ Yii Framework 2 Change Log
- Bug #18170: Fix 2.0.36 regression in passing extra console command arguments to the action (darkdef)
- Bug #18182: `yii\db\Expression` was not supported as condition in `ActiveRecord::findOne()` and `ActiveRecord::findAll()` (rhertogh)
- Bug #18189: Fix "Invalid parameter number" in `yii\rbac\DbManager::removeItem()` (samdark)
- Enh #18210: Allow strict comparison for multi-select inputs (alex-code)
- Bug #18204: Fix 2.0.36 regression in inline validator and JS validation (samdark)
- Enh #18205: Add `.phpstorm.meta.php` file for better auto-completion in PhpStorm (vjik)
- Bug #18198: Fix saving tables with trigger by outputting inserted data from insert query with usage of temporary table (darkdef)

19
framework/helpers/BaseHtml.php

@ -819,6 +819,8 @@ class BaseHtml
* Defaults to false.
* - encode: bool, whether to encode option prompt and option value characters.
* Defaults to `true`. This option is available since 2.0.3.
* - strict: boolean, if `$selection` is an array and this value is true a strict comparison will be performed on `$items` keys. Defaults to false.
* This option is available since 2.0.37.
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
@ -877,6 +879,8 @@ class BaseHtml
* Defaults to false.
* - encode: bool, whether to encode option prompt and option value characters.
* Defaults to `true`. This option is available since 2.0.3.
* - strict: boolean, if `$selection` is an array and this value is true a strict comparison will be performed on `$items` keys. Defaults to false.
* This option is available since 2.0.37.
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
@ -931,6 +935,8 @@ class BaseHtml
* This option is available since version 2.0.16.
* - encode: boolean, whether to HTML-encode the checkbox labels. Defaults to true.
* This option is ignored if `item` option is set.
* - strict: boolean, if `$selection` is an array and this value is true a strict comparison will be performed on `$items` keys. Defaults to false.
* This option is available since 2.0.37.
* - separator: string, the HTML code that separates items.
* - itemOptions: array, the options for generating the checkbox tag using [[checkbox()]].
* - item: callable, a callback that can be used to customize the generation of the HTML code
@ -962,13 +968,14 @@ class BaseHtml
$encode = ArrayHelper::remove($options, 'encode', true);
$separator = ArrayHelper::remove($options, 'separator', "\n");
$tag = ArrayHelper::remove($options, 'tag', 'div');
$strict = ArrayHelper::remove($options, 'strict', false);
$lines = [];
$index = 0;
foreach ($items as $value => $label) {
$checked = $selection !== null &&
(!ArrayHelper::isTraversable($selection) && !strcmp($value, $selection)
|| ArrayHelper::isTraversable($selection) && ArrayHelper::isIn((string)$value, $selection));
|| ArrayHelper::isTraversable($selection) && ArrayHelper::isIn((string)$value, $selection, $strict));
if ($formatter !== null) {
$lines[] = call_user_func($formatter, $index, $label, $name, $checked, $value);
} else {
@ -1021,6 +1028,8 @@ class BaseHtml
* This option is available since version 2.0.16.
* - encode: boolean, whether to HTML-encode the checkbox labels. Defaults to true.
* This option is ignored if `item` option is set.
* - strict: boolean, if `$selection` is an array and this value is true a strict comparison will be performed on `$items` keys. Defaults to false.
* This option is available since 2.0.37.
* - separator: string, the HTML code that separates items.
* - itemOptions: array, the options for generating the radio button tag using [[radio()]].
* - item: callable, a callback that can be used to customize the generation of the HTML code
@ -1049,6 +1058,7 @@ class BaseHtml
$encode = ArrayHelper::remove($options, 'encode', true);
$separator = ArrayHelper::remove($options, 'separator', "\n");
$tag = ArrayHelper::remove($options, 'tag', 'div');
$strict = ArrayHelper::remove($options, 'strict', false);
$hidden = '';
if (isset($options['unselect'])) {
@ -1067,7 +1077,7 @@ class BaseHtml
foreach ($items as $value => $label) {
$checked = $selection !== null &&
(!ArrayHelper::isTraversable($selection) && !strcmp($value, $selection)
|| ArrayHelper::isTraversable($selection) && ArrayHelper::isIn((string)$value, $selection));
|| ArrayHelper::isTraversable($selection) && ArrayHelper::isIn((string)$value, $selection, $strict));
if ($formatter !== null) {
$lines[] = call_user_func($formatter, $index, $label, $name, $checked, $value);
} else {
@ -1860,6 +1870,7 @@ class BaseHtml
$lines = [];
$encodeSpaces = ArrayHelper::remove($tagOptions, 'encodeSpaces', false);
$encode = ArrayHelper::remove($tagOptions, 'encode', true);
$strict = ArrayHelper::remove($tagOptions, 'strict', false);
if (isset($tagOptions['prompt'])) {
$promptOptions = ['value' => ''];
if (is_string($tagOptions['prompt'])) {
@ -1887,7 +1898,7 @@ class BaseHtml
if (!isset($groupAttrs['label'])) {
$groupAttrs['label'] = $key;
}
$attrs = ['options' => $options, 'groups' => $groups, 'encodeSpaces' => $encodeSpaces, 'encode' => $encode];
$attrs = ['options' => $options, 'groups' => $groups, 'encodeSpaces' => $encodeSpaces, 'encode' => $encode, 'strict' => $strict];
$content = static::renderSelectOptions($selection, $value, $attrs);
$lines[] = static::tag('optgroup', "\n" . $content . "\n", $groupAttrs);
} else {
@ -1896,7 +1907,7 @@ class BaseHtml
if (!array_key_exists('selected', $attrs)) {
$attrs['selected'] = $selection !== null &&
(!ArrayHelper::isTraversable($selection) && !strcmp($key, $selection)
|| ArrayHelper::isTraversable($selection) && ArrayHelper::isIn((string)$key, $selection));
|| ArrayHelper::isTraversable($selection) && ArrayHelper::isIn((string)$key, $selection, $strict));
}
$text = $encode ? static::encode($value) : $value;
if ($encodeSpaces) {

34
tests/framework/helpers/HtmlTest.php

@ -768,6 +768,13 @@ EOD;
'label' => 'Test Label'
]
]));
$expected = <<<'EOD'
<div><label><input type="checkbox" name="test[]" value="1"> 1</label>
<label><input type="checkbox" name="test[]" value="1.1" checked> 1.1</label>
<label><input type="checkbox" name="test[]" value="1.10"> 1.10</label></div>
EOD;
$this->assertEqualsWithoutLE($expected, Html::checkboxList('test', ['1.1'], ['1' => '1', '1.1' => '1.1', '1.10' => '1.10'], ['strict' => true]));
}
public function testRadioListWithArrayExpression()
@ -909,6 +916,13 @@ EOD;
'label' => 'Test Label'
]
]));
$expected = <<<'EOD'
<div><label><input type="radio" name="test" value="1"> 1</label>
<label><input type="radio" name="test" value="1.1" checked> 1.1</label>
<label><input type="radio" name="test" value="1.10"> 1.10</label></div>
EOD;
$this->assertEqualsWithoutLE($expected, Html::radioList('test', ['1.1'], ['1' => '1', '1.1' => '1.1', '1.10' => '1.10'], ['strict' => true]));
}
public function testUl()
@ -1046,6 +1060,26 @@ EOD;
],
];
$this->assertEqualsWithoutLE($expected, Html::renderSelectOptions(['value1'], $data, $attributes));
$expected = <<<'EOD'
<option value="1">1</option>
<option value="1.1" selected>1.1</option>
<option value="1.10">1.10</option>
EOD;
$data = ['1' => '1', '1.1' => '1.1', '1.10' => '1.10'];
$attributes = ['strict' => true];
$this->assertEqualsWithoutLE($expected, Html::renderSelectOptions(['1.1'], $data, $attributes));
$expected = <<<'EOD'
<option value="1">1</option>
<option value="1.1">1.1</option>
<optgroup label="group">
<option value="1.10" selected>1.10</option>
</optgroup>
EOD;
$data = ['1' => '1', '1.1' => '1.1', 'group' => ['1.10' => '1.10']];
$attributes = ['strict' => true];
$this->assertEqualsWithoutLE($expected, Html::renderSelectOptions(['1.10'], $data, $attributes));
}
public function testRenderAttributes()

Loading…
Cancel
Save