Skip to content

Commit 9b9fa3d

Browse files
committed
Merge branch '2.8'
* 2.8: [Form] Deprecated setting "choices_as_values" to "false" [Form] Deprecated setting "choices_as_values" to "false" [Form] Deprecated ArrayKeyChoiceList [Form] Deprecated TimezoneType::getTimezones()
2 parents 0468f74 + 78ff9dc commit 9b9fa3d

16 files changed

+320
-52
lines changed

UPGRADE-3.0.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,12 @@ UPGRADE FROM 2.x to 3.0
319319

320320
* The `Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList` class has been removed in
321321
favor of `Symfony\Component\Form\ChoiceList\ArrayChoiceList`.
322+
323+
* The `TimezoneType::getTimezones()` method was removed. You should not use
324+
this method.
325+
326+
* The `Symfony\Component\Form\ChoiceList\ArrayKeyChoiceList` class has been removed in
327+
favor of `Symfony\Component\Form\ChoiceList\ArrayChoiceList`.
322328

323329
### FrameworkBundle
324330

src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ public function __construct($choices, callable $value = null)
6868
$choices = iterator_to_array($choices);
6969
}
7070

71+
if (null === $value && $this->castableToString($choices)) {
72+
$value = function ($choice) {
73+
return (string) $choice;
74+
};
75+
}
76+
7177
if (null !== $value) {
7278
// If a deterministic value generator was passed, use it later
7379
$this->valueCallback = $value;
@@ -201,4 +207,35 @@ protected function flatten(array $choices, $value, &$choicesByValues, &$keysByVa
201207
$structuredValues[$key] = $choiceValue;
202208
}
203209
}
210+
211+
/**
212+
* Checks whether the given choices can be cast to strings without
213+
* generating duplicates.
214+
*
215+
* @param array $choices The choices.
216+
* @param array|null $cache The cache for previously checked entries. Internal
217+
*
218+
* @return bool Returns true if the choices can be cast to strings and
219+
* false otherwise.
220+
*/
221+
private function castableToString(array $choices, array &$cache = array())
222+
{
223+
foreach ($choices as $choice) {
224+
if (is_array($choice)) {
225+
if (!$this->castableToString($choice, $cache)) {
226+
return false;
227+
}
228+
229+
continue;
230+
} elseif (!is_scalar($choice)) {
231+
return false;
232+
} elseif (isset($cache[(string) $choice])) {
233+
return false;
234+
}
235+
236+
$cache[(string) $choice] = true;
237+
}
238+
239+
return true;
240+
}
204241
}

src/Symfony/Component/Form/ChoiceList/ArrayKeyChoiceList.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Form\ChoiceList;
1313

14+
@trigger_error('The '.__NAMESPACE__.'\ArrayKeyChoiceList class is deprecated since version 2.8 and will be removed in 3.0. Use '.__NAMESPACE__.'\ArrayChoiceList instead.', E_USER_DEPRECATED);
15+
1416
use Symfony\Component\Form\Exception\InvalidArgumentException;
1517

1618
/**

src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,14 @@ public function configureOptions(OptionsResolver $resolver)
268268
return $choiceListFactory->createListFromChoices($choices, $options['choice_value']);
269269
};
270270

271+
$choicesAsValuesNormalizer = function (Options $options, $choicesAsValues) {
272+
if (true !== $choicesAsValues) {
273+
@trigger_error('The value "false" for the "choices_as_values" option is deprecated since version 2.8 and will not be supported anymore in 3.0. Set this option to "true" and flip the contents of the "choices" option instead.', E_USER_DEPRECATED);
274+
}
275+
276+
return $choicesAsValues;
277+
};
278+
271279
$placeholderNormalizer = function (Options $options, $placeholder) {
272280
if ($options['multiple']) {
273281
// never use an empty value for this case
@@ -323,6 +331,7 @@ public function configureOptions(OptionsResolver $resolver)
323331
$resolver->setNormalizer('choice_list', $choiceListNormalizer);
324332
$resolver->setNormalizer('placeholder', $placeholderNormalizer);
325333
$resolver->setNormalizer('choice_translation_domain', $choiceTranslationDomainNormalizer);
334+
$resolver->setNormalizer('choices_as_values', $choicesAsValuesNormalizer);
326335

327336
$resolver->setAllowedTypes('choice_list', array('null', 'Symfony\Component\Form\ChoiceList\ChoiceListInterface'));
328337
$resolver->setAllowedTypes('choices', array('null', 'array', '\Traversable'));

src/Symfony/Component/Form/Extension/Core/Type/CountryType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class CountryType extends AbstractType
2323
public function configureOptions(OptionsResolver $resolver)
2424
{
2525
$resolver->setDefaults(array(
26-
'choices' => Intl::getRegionBundle()->getCountryNames(),
26+
'choices' => array_flip(Intl::getRegionBundle()->getCountryNames()),
27+
'choices_as_values' => true,
2728
'choice_translation_domain' => false,
2829
));
2930
}

src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class CurrencyType extends AbstractType
2323
public function configureOptions(OptionsResolver $resolver)
2424
{
2525
$resolver->setDefaults(array(
26-
'choices' => Intl::getCurrencyBundle()->getCurrencyNames(),
26+
'choices' => array_flip(Intl::getCurrencyBundle()->getCurrencyNames()),
27+
'choices_as_values' => true,
2728
'choice_translation_domain' => false,
2829
));
2930
}

src/Symfony/Component/Form/Extension/Core/Type/DateType.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,15 @@ public function buildForm(FormBuilderInterface $builder, array $options)
9393
if ('choice' === $options['widget']) {
9494
// Only pass a subset of the options to children
9595
$yearOptions['choices'] = $this->formatTimestamps($formatter, '/y+/', $this->listYears($options['years']));
96+
$yearOptions['choices_as_values'] = true;
9697
$yearOptions['placeholder'] = $options['placeholder']['year'];
9798
$yearOptions['choice_translation_domain'] = $options['choice_translation_domain']['year'];
9899
$monthOptions['choices'] = $this->formatTimestamps($formatter, '/[M|L]+/', $this->listMonths($options['months']));
100+
$monthOptions['choices_as_values'] = true;
99101
$monthOptions['placeholder'] = $options['placeholder']['month'];
100102
$monthOptions['choice_translation_domain'] = $options['choice_translation_domain']['month'];
101103
$dayOptions['choices'] = $this->formatTimestamps($formatter, '/d+/', $this->listDays($options['days']));
104+
$dayOptions['choices_as_values'] = true;
102105
$dayOptions['placeholder'] = $options['placeholder']['day'];
103106
$dayOptions['choice_translation_domain'] = $options['choice_translation_domain']['day'];
104107
}
@@ -282,14 +285,15 @@ private function formatTimestamps(\IntlDateFormatter $formatter, $regex, array $
282285
{
283286
$pattern = $formatter->getPattern();
284287
$timezone = $formatter->getTimezoneId();
288+
$formattedTimestamps = array();
285289

286290
$formatter->setTimeZone('UTC');
287291

288292
if (preg_match($regex, $pattern, $matches)) {
289293
$formatter->setPattern($matches[0]);
290294

291-
foreach ($timestamps as $key => $timestamp) {
292-
$timestamps[$key] = $formatter->format($timestamp);
295+
foreach ($timestamps as $timestamp => $choice) {
296+
$formattedTimestamps[$formatter->format($timestamp)] = $choice;
293297
}
294298

295299
// I'd like to clone the formatter above, but then we get a
@@ -299,7 +303,7 @@ private function formatTimestamps(\IntlDateFormatter $formatter, $regex, array $
299303

300304
$formatter->setTimeZone($timezone);
301305

302-
return $timestamps;
306+
return $formattedTimestamps;
303307
}
304308

305309
private function listYears(array $years)
@@ -308,7 +312,7 @@ private function listYears(array $years)
308312

309313
foreach ($years as $year) {
310314
if (false !== $y = gmmktime(0, 0, 0, 6, 15, $year)) {
311-
$result[$year] = $y;
315+
$result[$y] = $year;
312316
}
313317
}
314318

@@ -320,7 +324,7 @@ private function listMonths(array $months)
320324
$result = array();
321325

322326
foreach ($months as $month) {
323-
$result[$month] = gmmktime(0, 0, 0, $month, 15);
327+
$result[gmmktime(0, 0, 0, $month, 15)] = $month;
324328
}
325329

326330
return $result;
@@ -331,7 +335,7 @@ private function listDays(array $days)
331335
$result = array();
332336

333337
foreach ($days as $day) {
334-
$result[$day] = gmmktime(0, 0, 0, 5, $day);
338+
$result[gmmktime(0, 0, 0, 5, $day)] = $day;
335339
}
336340

337341
return $result;

src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class LanguageType extends AbstractType
2323
public function configureOptions(OptionsResolver $resolver)
2424
{
2525
$resolver->setDefaults(array(
26-
'choices' => Intl::getLanguageBundle()->getLanguageNames(),
26+
'choices' => array_flip(Intl::getLanguageBundle()->getLanguageNames()),
27+
'choices_as_values' => true,
2728
'choice_translation_domain' => false,
2829
));
2930
}

src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class LocaleType extends AbstractType
2323
public function configureOptions(OptionsResolver $resolver)
2424
{
2525
$resolver->setDefaults(array(
26-
'choices' => Intl::getLocaleBundle()->getLocaleNames(),
26+
'choices' => array_flip(Intl::getLocaleBundle()->getLocaleNames()),
27+
'choices_as_values' => true,
2728
'choice_translation_domain' => false,
2829
));
2930
}

src/Symfony/Component/Form/Extension/Core/Type/TimeType.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,22 @@ public function buildForm(FormBuilderInterface $builder, array $options)
6363
$hours = $minutes = array();
6464

6565
foreach ($options['hours'] as $hour) {
66-
$hours[$hour] = str_pad($hour, 2, '0', STR_PAD_LEFT);
66+
$hours[str_pad($hour, 2, '0', STR_PAD_LEFT)] = $hour;
6767
}
6868

6969
// Only pass a subset of the options to children
7070
$hourOptions['choices'] = $hours;
71+
$hourOptions['choices_as_values'] = true;
7172
$hourOptions['placeholder'] = $options['placeholder']['hour'];
7273
$hourOptions['choice_translation_domain'] = $options['choice_translation_domain']['hour'];
7374

7475
if ($options['with_minutes']) {
7576
foreach ($options['minutes'] as $minute) {
76-
$minutes[$minute] = str_pad($minute, 2, '0', STR_PAD_LEFT);
77+
$minutes[str_pad($minute, 2, '0', STR_PAD_LEFT)] = $minute;
7778
}
7879

7980
$minuteOptions['choices'] = $minutes;
81+
$minuteOptions['choices_as_values'] = true;
8082
$minuteOptions['placeholder'] = $options['placeholder']['minute'];
8183
$minuteOptions['choice_translation_domain'] = $options['choice_translation_domain']['minute'];
8284
}
@@ -85,10 +87,11 @@ public function buildForm(FormBuilderInterface $builder, array $options)
8587
$seconds = array();
8688

8789
foreach ($options['seconds'] as $second) {
88-
$seconds[$second] = str_pad($second, 2, '0', STR_PAD_LEFT);
90+
$seconds[str_pad($second, 2, '0', STR_PAD_LEFT)] = $second;
8991
}
9092

9193
$secondOptions['choices'] = $seconds;
94+
$secondOptions['choices_as_values'] = true;
9295
$secondOptions['placeholder'] = $options['placeholder']['second'];
9396
$secondOptions['choice_translation_domain'] = $options['choice_translation_domain']['second'];
9497
}

0 commit comments

Comments
 (0)