Skip to content

Instantly share code, notes, and snippets.

@benr77
Last active November 2, 2017 16:51
Show Gist options
  • Save benr77/085fe0ccd2f72f10bb0ad331508e81df to your computer and use it in GitHub Desktop.
Save benr77/085fe0ccd2f72f10bb0ad331508e81df to your computer and use it in GitHub Desktop.
Symfony form extension to permit un-sorted "preferred_choices" option
<?php
declare(strict_types=1);
namespace AppBundle\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Add option to choice field type to keep preferred_choices in the specified order
*/
class ChoiceTypeExtension extends AbstractTypeExtension
{
/**
* @return string
*/
public function getExtendedType()
{
return ChoiceType::class;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefaults(['preferred_choices_unsorted' => false])
->setAllowedTypes('preferred_choices_unsorted', 'boolean');
}
/**
* @param FormView $view
* @param FormInterface $form
* @param array $options
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
parent::buildView($view, $form, $options);
$parentDefinesUnsorted = $form->getParent()->getConfig()->getOption('preferred_choices_unsorted');
// If preferred_choices are specified for this field, AND
// If 'preferred_choices_unsorted' is specified by this field,
// or by its parent (to support choices inside compound fields)
if ($options['preferred_choices'] && ($options['preferred_choices_unsorted'] || $parentDefinesUnsorted))
{
$newPreferredChoices = array();
foreach ($options['preferred_choices'] as $key)
{
$choice = $this->findChoiceView($view, $key);
if (!$choice)
{
continue;
}
$newPreferredChoices[$key] = $choice;
}
$view->vars['preferred_choices'] = $newPreferredChoices;
}
}
/**
* @param FormView $view
* @param $keyToFind
*
* @return null
*/
private function findChoiceView(FormView $view, $keyToFind)
{
foreach ($view->vars['preferred_choices'] as $choice)
{
if ($choice->value == $keyToFind)
{
return $choice;
}
}
return null;
}
}
AppBundle\Form\Extension\ChoiceTypeExtension:
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\ChoiceType }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment