From 6855cffb1ddb9ef56291b36b45391897bd656ac8 Mon Sep 17 00:00:00 2001 From: Toni Uebernickel Date: Fri, 21 Dec 2012 12:16:37 +0100 Subject: [PATCH 1/2] add preferred_query option to ModelType This enables the ModelChoiceList to use 'preferred_choices' of the parent ChoiceType. --- .../Form/ChoiceList/ModelChoiceList.php | 50 ++++++++++++++----- .../Bridge/Propel1/Form/Type/ModelType.php | 27 +++++++++- .../Form/ChoiceList/ModelChoiceListTest.php | 23 +++++++++ 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php index 4176777b37..f5c14306aa 100644 --- a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php +++ b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php @@ -11,8 +11,10 @@ namespace Symfony\Bridge\Propel1\Form\ChoiceList; +use \ModelCriteria; use \BaseObject; use \Persistent; + use Symfony\Component\Form\Exception\FormException; use Symfony\Component\Form\Exception\StringCastException; use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList; @@ -21,6 +23,7 @@ use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList; * Widely inspirated by the EntityChoiceList. * * @author William Durand + * @author Toni Uebernickel */ class ModelChoiceList extends ObjectChoiceList { @@ -31,28 +34,44 @@ class ModelChoiceList extends ObjectChoiceList * * @var array */ - private $identifier = array(); + protected $identifier = array(); /** - * Query + * The query to retrieve the choices of this list. + * + * @var ModelCriteria */ - private $query = null; + protected $query; + + /** + * The query to retrieve the preferred choices for this list. + * + * @var ModelCriteria + */ + protected $preferredQuery; /** * Whether the model objects have already been loaded. * * @var Boolean */ - private $loaded = false; + protected $loaded = false; /** - * @param string $class - * @param string $labelPath - * @param array $choices - * @param \ModelCriteria $queryObject - * @param string $groupPath + * Constructor. + * + * @see Symfony\Bridge\Propel1\Form\Type\ModelType How to use the preferred choices. + * + * @param string $class The FQCN of the model class to be loaded. + * @param string $labelPath A property path pointing to the property used for the choice labels. + * @param array $choices An optional array to use, rather than fetching the models. + * @param ModelCriteria $queryObject The query to use retrieving model data from database. + * @param string $groupPath A property path pointing to the property used to group the choices. + * @param array|ModelCriteria $preferred The preferred items of this choice. + * Either an array if $choices is given, + * or a ModelCriteria to be merged with the $queryObject. */ - public function __construct($class, $labelPath = null, $choices = null, $queryObject = null, $groupPath = null) + public function __construct($class, $labelPath = null, $choices = null, $queryObject = null, $groupPath = null, $preferred = array()) { $this->class = $class; @@ -63,13 +82,18 @@ class ModelChoiceList extends ObjectChoiceList $this->query = $queryObject ?: $query; $this->loaded = is_array($choices) || $choices instanceof \Traversable; + if ($preferred instanceof ModelCriteria) { + $this->preferredQuery = $preferred->mergeWith($this->query); + } + if (!$this->loaded) { // Make sure the constraints of the parent constructor are // fulfilled $choices = array(); + $preferred = array(); } - parent::__construct($choices, $labelPath, array(), $groupPath); + parent::__construct($choices, $labelPath, $preferred, $groupPath); } /** @@ -316,11 +340,11 @@ class ModelChoiceList extends ObjectChoiceList private function load() { $models = (array) $this->query->find(); + $preferred = (array) $this->preferredQuery->find(); try { // The second parameter $labels is ignored by ObjectChoiceList - // The third parameter $preferredChoices is currently not supported - parent::initialize($models, array(), array()); + parent::initialize($models, array(), $preferred); } catch (StringCastException $e) { throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $e); } diff --git a/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php b/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php index 820153c68d..14297e1889 100644 --- a/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php +++ b/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php @@ -22,6 +22,29 @@ use Symfony\Component\OptionsResolver\OptionsResolverInterface; * ModelType class. * * @author William Durand + * @author Toni Uebernickel + * + * Example using the preferred_query option. + * + * + * public function buildForm(FormBuilderInterface $builder, array $options) + * { + * $builder + * ->add('product', 'model', array( + * 'class' => 'Model\Product', + * 'query' => ProductQuery::create() + * ->filterIsActive(true) + * ->useI18nQuery($options['locale']) + * ->orderByName() + * ->endUse() + * , + * 'preferred_query' => ProductQuery::create() + * ->filterByIsTopProduct(true) + * , + * )) + * ; + * } + * */ class ModelType extends AbstractType { @@ -40,7 +63,8 @@ class ModelType extends AbstractType $options['property'], $options['choices'], $options['query'], - $options['group_by'] + $options['group_by'], + $options['preferred_query'] ); }; @@ -55,6 +79,7 @@ class ModelType extends AbstractType 'choice_list' => $choiceList, 'group_by' => null, 'by_reference' => false, + 'preferred_query' => null, )); } diff --git a/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php b/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php index 68f690db95..6675eac727 100644 --- a/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php +++ b/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php @@ -70,6 +70,29 @@ class ModelChoiceListTest extends Propel1TestCase $this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices()); } + public function testFlattenedPreferredChoices() + { + $item1 = new Item(1, 'Foo'); + $item2 = new Item(2, 'Bar'); + + $choiceList = new ModelChoiceList( + self::ITEM_CLASS, + 'value', + array( + $item1, + $item2, + ), + null, + null, + array( + $item1 + ) + ); + + $this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices()); + $this->assertEquals(array(1 => new ChoiceView($item1, '1', 'Foo')), $choiceList->getPreferredViews()); + } + public function testNestedChoices() { $item1 = new Item(1, 'Foo'); From 05fca6d80ebc10f8286632d6715565065e0a7af3 Mon Sep 17 00:00:00 2001 From: Toni Uebernickel Date: Fri, 21 Dec 2012 13:48:37 +0100 Subject: [PATCH 2/2] use preferred_choices in favor of preferred_query --- .../Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php | 6 +++++- src/Symfony/Bridge/Propel1/Form/Type/ModelType.php | 7 +++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php index f5c14306aa..0a3eab0903 100644 --- a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php +++ b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php @@ -340,7 +340,11 @@ class ModelChoiceList extends ObjectChoiceList private function load() { $models = (array) $this->query->find(); - $preferred = (array) $this->preferredQuery->find(); + + $preferred = array(); + if ($this->preferredQuery instanceof ModelCriteria) { + $preferred = (array) $this->preferredQuery->find(); + } try { // The second parameter $labels is ignored by ObjectChoiceList diff --git a/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php b/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php index 14297e1889..faf5f25f1c 100644 --- a/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php +++ b/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php @@ -24,7 +24,7 @@ use Symfony\Component\OptionsResolver\OptionsResolverInterface; * @author William Durand * @author Toni Uebernickel * - * Example using the preferred_query option. + * Example using the preferred_choices option. * * * public function buildForm(FormBuilderInterface $builder, array $options) @@ -38,7 +38,7 @@ use Symfony\Component\OptionsResolver\OptionsResolverInterface; * ->orderByName() * ->endUse() * , - * 'preferred_query' => ProductQuery::create() + * 'preferred_choices' => ProductQuery::create() * ->filterByIsTopProduct(true) * , * )) @@ -64,7 +64,7 @@ class ModelType extends AbstractType $options['choices'], $options['query'], $options['group_by'], - $options['preferred_query'] + $options['preferred_choices'] ); }; @@ -79,7 +79,6 @@ class ModelType extends AbstractType 'choice_list' => $choiceList, 'group_by' => null, 'by_reference' => false, - 'preferred_query' => null, )); }