merged branch havvg/feature/propel1-modelchoice-preferred (PR #6454)

This PR was merged into the 2.1 branch.

Commits
-------

05fca6d use preferred_choices in favor of preferred_query
6855cff add preferred_query option to ModelType

Discussion
----------

[Propel1] add preferred_choices option to ModelType

This enables the ModelChoiceList to use 'preferred_choices' of the parent ChoiceType.

Ping @willdurand

---------------------------------------------------------------------------

by willdurand at 2012-12-22T09:39:39Z

👍
This commit is contained in:
Fabien Potencier 2012-12-27 16:10:36 +01:00
commit a0ea84bbc3
3 changed files with 89 additions and 14 deletions

View File

@ -11,8 +11,10 @@
namespace Symfony\Bridge\Propel1\Form\ChoiceList; namespace Symfony\Bridge\Propel1\Form\ChoiceList;
use \ModelCriteria;
use \BaseObject; use \BaseObject;
use \Persistent; use \Persistent;
use Symfony\Component\Form\Exception\FormException; use Symfony\Component\Form\Exception\FormException;
use Symfony\Component\Form\Exception\StringCastException; use Symfony\Component\Form\Exception\StringCastException;
use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList; 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. * Widely inspirated by the EntityChoiceList.
* *
* @author William Durand <william.durand1@gmail.com> * @author William Durand <william.durand1@gmail.com>
* @author Toni Uebernickel <tuebernickel@gmail.com>
*/ */
class ModelChoiceList extends ObjectChoiceList class ModelChoiceList extends ObjectChoiceList
{ {
@ -31,28 +34,44 @@ class ModelChoiceList extends ObjectChoiceList
* *
* @var array * @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. * Whether the model objects have already been loaded.
* *
* @var Boolean * @var Boolean
*/ */
private $loaded = false; protected $loaded = false;
/** /**
* @param string $class * Constructor.
* @param string $labelPath *
* @param array $choices * @see Symfony\Bridge\Propel1\Form\Type\ModelType How to use the preferred choices.
* @param \ModelCriteria $queryObject *
* @param string $groupPath * @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; $this->class = $class;
@ -63,13 +82,18 @@ class ModelChoiceList extends ObjectChoiceList
$this->query = $queryObject ?: $query; $this->query = $queryObject ?: $query;
$this->loaded = is_array($choices) || $choices instanceof \Traversable; $this->loaded = is_array($choices) || $choices instanceof \Traversable;
if ($preferred instanceof ModelCriteria) {
$this->preferredQuery = $preferred->mergeWith($this->query);
}
if (!$this->loaded) { if (!$this->loaded) {
// Make sure the constraints of the parent constructor are // Make sure the constraints of the parent constructor are
// fulfilled // fulfilled
$choices = array(); $choices = array();
$preferred = array();
} }
parent::__construct($choices, $labelPath, array(), $groupPath); parent::__construct($choices, $labelPath, $preferred, $groupPath);
} }
/** /**
@ -317,10 +341,14 @@ class ModelChoiceList extends ObjectChoiceList
{ {
$models = (array) $this->query->find(); $models = (array) $this->query->find();
$preferred = array();
if ($this->preferredQuery instanceof ModelCriteria) {
$preferred = (array) $this->preferredQuery->find();
}
try { try {
// The second parameter $labels is ignored by ObjectChoiceList // The second parameter $labels is ignored by ObjectChoiceList
// The third parameter $preferredChoices is currently not supported parent::initialize($models, array(), $preferred);
parent::initialize($models, array(), array());
} catch (StringCastException $e) { } catch (StringCastException $e) {
throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $e); throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $e);
} }

View File

@ -22,6 +22,29 @@ use Symfony\Component\OptionsResolver\OptionsResolverInterface;
* ModelType class. * ModelType class.
* *
* @author William Durand <william.durand1@gmail.com> * @author William Durand <william.durand1@gmail.com>
* @author Toni Uebernickel <tuebernickel@gmail.com>
*
* Example using the preferred_choices option.
*
* <code>
* 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_choices' => ProductQuery::create()
* ->filterByIsTopProduct(true)
* ,
* ))
* ;
* }
* </code>
*/ */
class ModelType extends AbstractType class ModelType extends AbstractType
{ {
@ -40,7 +63,8 @@ class ModelType extends AbstractType
$options['property'], $options['property'],
$options['choices'], $options['choices'],
$options['query'], $options['query'],
$options['group_by'] $options['group_by'],
$options['preferred_choices']
); );
}; };

View File

@ -70,6 +70,29 @@ class ModelChoiceListTest extends Propel1TestCase
$this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices()); $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() public function testNestedChoices()
{ {
$item1 = new Item(1, 'Foo'); $item1 = new Item(1, 'Foo');