Keep preferred_choices order

This commit is contained in:
Valentin 2019-04-12 16:00:33 +03:00
parent a36fbe3d38
commit 340a2fb3f8
2 changed files with 44 additions and 6 deletions

View File

@ -48,13 +48,16 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
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)
{ {
$preferredViews = []; $preferredViews = [];
$preferredViewsOrder = [];
$otherViews = []; $otherViews = [];
$choices = $list->getChoices(); $choices = $list->getChoices();
$keys = $list->getOriginalKeys(); $keys = $list->getOriginalKeys();
if (!\is_callable($preferredChoices) && !empty($preferredChoices)) { if (!\is_callable($preferredChoices) && !empty($preferredChoices)) {
$preferredChoices = function ($choice) use ($preferredChoices) { // make sure we have keys that reflect order
return \in_array($choice, $preferredChoices, true); $preferredChoices = array_values($preferredChoices);
$preferredChoices = static function ($choice) use ($preferredChoices) {
return array_search($choice, $preferredChoices, true);
}; };
} }
@ -80,6 +83,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$attr, $attr,
$preferredChoices, $preferredChoices,
$preferredViews, $preferredViews,
$preferredViewsOrder,
$otherViews $otherViews
); );
} }
@ -108,14 +112,21 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$attr, $attr,
$preferredChoices, $preferredChoices,
$preferredViews, $preferredViews,
$preferredViewsOrder,
$otherViews $otherViews
); );
} }
uksort($preferredViews, static function ($a, $b) use ($preferredViewsOrder): int {
return isset($preferredViewsOrder[$a], $preferredViewsOrder[$b])
? $preferredViewsOrder[$a] <=> $preferredViewsOrder[$b]
: 0;
});
return new ChoiceListView($otherViews, $preferredViews); 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, $isPreferred, &$preferredViews, &$preferredViewsOrder, &$otherViews)
{ {
// $value may be an integer or a string, since it's stored in the array // $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. // keys. We want to guarantee it's a string though.
@ -143,14 +154,15 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
); );
// $isPreferred may be null if no choices are preferred // $isPreferred may be null if no choices are preferred
if ($isPreferred && $isPreferred($choice, $key, $value)) { if ($isPreferred && false !== $preferredKey = $isPreferred($choice, $key, $value)) {
$preferredViews[$nextIndex] = $view; $preferredViews[$nextIndex] = $view;
$preferredViewsOrder[$nextIndex] = $preferredKey;
} else { } else {
$otherViews[$nextIndex] = $view; $otherViews[$nextIndex] = $view;
} }
} }
private static function addChoiceViewsFromStructuredValues($values, $label, $choices, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews) private static function addChoiceViewsFromStructuredValues($values, $label, $choices, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$preferredViewsOrder, &$otherViews)
{ {
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
if (null === $value) { if (null === $value) {
@ -171,6 +183,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$attr, $attr,
$isPreferred, $isPreferred,
$preferredViewsForGroup, $preferredViewsForGroup,
$preferredViewsOrder,
$otherViewsForGroup $otherViewsForGroup
); );
@ -195,12 +208,13 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$attr, $attr,
$isPreferred, $isPreferred,
$preferredViews, $preferredViews,
$preferredViewsOrder,
$otherViews $otherViews
); );
} }
} }
private static function addChoiceViewsGroupedByCallable($groupBy, $choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews) private static function addChoiceViewsGroupedByCallable($groupBy, $choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$preferredViewsOrder, &$otherViews)
{ {
$groupLabels = $groupBy($choice, $keys[$value], $value); $groupLabels = $groupBy($choice, $keys[$value], $value);
@ -215,6 +229,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$attr, $attr,
$isPreferred, $isPreferred,
$preferredViews, $preferredViews,
$preferredViewsOrder,
$otherViews $otherViews
); );
@ -240,6 +255,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$attr, $attr,
$isPreferred, $isPreferred,
$preferredViews[$groupLabel]->choices, $preferredViews[$groupLabel]->choices,
$preferredViewsOrder,
$otherViews[$groupLabel]->choices $otherViews[$groupLabel]->choices
); );
} }

View File

@ -234,6 +234,28 @@ class DefaultChoiceListFactoryTest extends TestCase
$this->assertFlatView($view); $this->assertFlatView($view);
} }
public function testCreateViewFlatPreferredChoicesSameOrder()
{
$view = $this->factory->createView(
$this->list,
[$this->obj2, $this->obj1, $this->obj4, $this->obj3]
);
$preferredLabels = array_map(static function (ChoiceView $view): string {
return $view->label;
}, $view->preferredChoices);
$this->assertSame(
[
1 => 'B',
0 => 'A',
3 => 'D',
2 => 'C',
],
$preferredLabels
);
}
public function testCreateViewFlatPreferredChoicesEmptyArray() public function testCreateViewFlatPreferredChoicesEmptyArray()
{ {
$view = $this->factory->createView( $view = $this->factory->createView(