-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Form] added "choice_label_attr" option and deprecated "choice_attr" as multi-arrays or property path #16834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e5cc7cd
eb658f9
23df93d
0fe7097
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -187,6 +187,69 @@ Form | |
} | ||
``` | ||
|
||
* Usage of `choice_attr` option as an array of nested arrays has been removed | ||
and indexes will be considered as attributes in 4.0. Use a unique array for | ||
all choices or a `callable` instead. | ||
|
||
Before: | ||
|
||
```php | ||
// Single array for all choices using callable | ||
'choice_attr' => function () { | ||
return array('class' => 'choice-options'); | ||
}, | ||
|
||
// Different arrays per choices using array | ||
'choices' => array( | ||
'Yes' => true, | ||
'No' => false, | ||
'Maybe' => null, | ||
'choice_attr' => array( | ||
'Yes' => array('class' => 'option-green'), | ||
'No' => array('class' => 'option-red'), | ||
), | ||
``` | ||
|
||
After: | ||
|
||
```php | ||
// Single array for all choices using array | ||
'choice_attr' => array('class' => 'choice-options'), | ||
|
||
// Different arrays per choices using callable | ||
'choices' => array( | ||
'Yes' => true, | ||
'No' => false, | ||
'Maybe' => null, | ||
'choice_attr' => function ($choice, $index, $value) { | ||
if ('Yes' === $index) { | ||
return array('class' => 'option-green'); | ||
} | ||
if ('No' === $index) { | ||
return array('class' => 'option-red'); | ||
} | ||
|
||
return array(); | ||
}, | ||
``` | ||
|
||
* Using `choice_attr` option as a string or a `ProprertyPath` instance will | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here |
||
throw an exception. Use a `callable` instead. | ||
|
||
Before: | ||
|
||
```php | ||
'choice_attr' => 'htmlAttributes', | ||
``` | ||
|
||
After: | ||
|
||
```php | ||
'choice_attr' => function ($choice, $value, $index) { | ||
return $choice->getHtmlAttributes(); | ||
}, | ||
``` | ||
|
||
FrameworkBundle | ||
--------------- | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,7 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul | |
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null) | ||
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null, $labelAttr = null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
{ | ||
$preferredViews = array(); | ||
$otherViews = array(); | ||
|
@@ -76,6 +76,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null, | |
$keys, | ||
$index, | ||
$attr, | ||
$labelAttr, | ||
$preferredChoices, | ||
$preferredViews, | ||
$otherViews | ||
|
@@ -90,6 +91,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null, | |
$keys, | ||
$index, | ||
$attr, | ||
$labelAttr, | ||
$preferredChoices, | ||
$preferredViews, | ||
$otherViews | ||
|
@@ -113,7 +115,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null, | |
return new ChoiceListView($otherViews, $preferredViews); | ||
} | ||
|
||
private static function addChoiceView($choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews) | ||
private static function addChoiceView($choice, $value, $label, $keys, &$index, $attr, $labelAttr, $isPreferred, &$preferredViews, &$otherViews) | ||
{ | ||
// $value may be an integer or a string, since it's stored in the array | ||
// keys. We want to guarantee it's a string though. | ||
|
@@ -131,13 +133,32 @@ private static function addChoiceView($choice, $value, $label, $keys, &$index, $ | |
$label = false === $dynamicLabel ? false : (string) $dynamicLabel; | ||
} | ||
|
||
// BC | ||
if (is_array($attr)) { | ||
if (isset($attr[$key])) { | ||
@trigger_error('Passing an array of arrays to the "choice_attr" option with choice keys as keys is deprecated since version 3.3 and will no longer be supported in 4.0. Use a "\Closure" instead.', E_USER_DEPRECATED); | ||
$attr = $attr[$key]; | ||
} else { | ||
foreach ($attr as $a) { | ||
if (is_array($a)) { | ||
// Using the deprecated way of choice keys as keys allows to not define all choices. | ||
// When $attr[$key] is not set for this one but is for another we need to | ||
// prevent using an array as HTML attribute | ||
$attr = array(); | ||
|
||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
$view = new ChoiceView( | ||
$choice, | ||
$value, | ||
$label, | ||
// The attributes may be a callable or a mapping from choice indices | ||
// to nested arrays | ||
is_callable($attr) ? call_user_func($attr, $choice, $key, $value) : (isset($attr[$key]) ? $attr[$key] : array()) | ||
// The attributes may be a callable or an array | ||
is_callable($attr) ? call_user_func($attr, $choice, $key, $value) : (null !== $attr ? $attr : array()), | ||
is_callable($labelAttr) ? call_user_func($labelAttr, $choice, $key, $value) : (null !== $labelAttr ? $labelAttr : array()) | ||
); | ||
|
||
// $isPreferred may be null if no choices are preferred | ||
|
@@ -148,7 +169,7 @@ private static function addChoiceView($choice, $value, $label, $keys, &$index, $ | |
} | ||
} | ||
|
||
private static function addChoiceViewsGroupedBy($groupBy, $label, $choices, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews) | ||
private static function addChoiceViewsGroupedBy($groupBy, $label, $choices, $keys, &$index, $attr, $labelAttr, $isPreferred, &$preferredViews, &$otherViews) | ||
{ | ||
foreach ($groupBy as $key => $value) { | ||
if (null === $value) { | ||
|
@@ -167,6 +188,7 @@ private static function addChoiceViewsGroupedBy($groupBy, $label, $choices, $key | |
$keys, | ||
$index, | ||
$attr, | ||
$labelAttr, | ||
$isPreferred, | ||
$preferredViewsForGroup, | ||
$otherViewsForGroup | ||
|
@@ -191,14 +213,15 @@ private static function addChoiceViewsGroupedBy($groupBy, $label, $choices, $key | |
$keys, | ||
$index, | ||
$attr, | ||
$labelAttr, | ||
$isPreferred, | ||
$preferredViews, | ||
$otherViews | ||
); | ||
} | ||
} | ||
|
||
private static function addChoiceViewGroupedBy($groupBy, $choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews) | ||
private static function addChoiceViewGroupedBy($groupBy, $choice, $value, $label, $keys, &$index, $attr, $labelAttr, $isPreferred, &$preferredViews, &$otherViews) | ||
{ | ||
$groupLabel = call_user_func($groupBy, $choice, $keys[$value], $value); | ||
|
||
|
@@ -211,6 +234,7 @@ private static function addChoiceViewGroupedBy($groupBy, $choice, $value, $label | |
$keys, | ||
$index, | ||
$attr, | ||
$labelAttr, | ||
$isPreferred, | ||
$preferredViews, | ||
$otherViews | ||
|
@@ -235,6 +259,7 @@ private static function addChoiceViewGroupedBy($groupBy, $choice, $value, $label | |
$keys, | ||
$index, | ||
$attr, | ||
$labelAttr, | ||
$isPreferred, | ||
$preferredViews[$groupLabel]->choices, | ||
$otherViews[$groupLabel]->choices | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -148,10 +148,11 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul | |
* @param null|callable|string|PropertyPath $index The callable or path generating the view indices | ||
* @param null|callable|string|PropertyPath $groupBy The callable or path generating the group names | ||
* @param null|array|callable|string|PropertyPath $attr The callable or path generating the HTML attributes | ||
* @param null|array|callable $labelAttr The array or callable generating the label HTML attributes | ||
* | ||
* @return ChoiceListView The choice list view | ||
*/ | ||
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null) | ||
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null, $labelAttr = null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BC break here too There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes they all use the same interface. The BC break is only mentioned as 'Yes' in the description for now, is there anything more I need to do about it ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, the issue is that we cannot make such a BC break in a minor release. So we should find another solution that would be mergable for the 3.1 release (I don't have any idea yet). |
||
{ | ||
$accessor = $this->propertyAccessor; | ||
|
||
|
@@ -218,12 +219,13 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null, | |
@trigger_error('Passing callable strings is deprecated since version 3.1 and PropertyAccessDecorator will treat them as property paths in 4.0. You should use a "\Closure" instead.', E_USER_DEPRECATED); | ||
} | ||
|
||
// Deprecated since 3.3 and to be removed in 4.0 with the condition above | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if it is deprecated, it must trigger a deprecation notice. And why deprecating this feature ? It is not consistent with other properties. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because of what =I explained in the related issue, it's more consistent IMO to deprecate this behavior rather than supporting it for |
||
if ($attr instanceof PropertyPath) { | ||
$attr = function ($choice) use ($accessor, $attr) { | ||
return $accessor->getValue($choice, $attr); | ||
}; | ||
} | ||
|
||
return $this->decoratedFactory->createView($list, $preferredChoices, $label, $index, $groupBy, $attr); | ||
return $this->decoratedFactory->createView($list, $preferredChoices, $label, $index, $groupBy, $attr, $labelAttr); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, thanks!