Skip to content

[Propel1] add preferred_choices option to ModelType #6454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 27, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 41 additions & 13 deletions src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -21,6 +23,7 @@
* Widely inspirated by the EntityChoiceList.
*
* @author William Durand <william.durand1@gmail.com>
* @author Toni Uebernickel <tuebernickel@gmail.com>
*/
class ModelChoiceList extends ObjectChoiceList
{
Expand All @@ -31,28 +34,44 @@ class ModelChoiceList extends ObjectChoiceList
*
* @var array
*/
private $identifier = array();
protected $identifier = array();

/**
* The query to retrieve the choices of this list.
*
* @var ModelCriteria
*/
protected $query;

/**
* Query
* The query to retrieve the preferred choices for this list.
*
* @var ModelCriteria
*/
private $query = null;
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;

Expand All @@ -63,13 +82,18 @@ public function __construct($class, $labelPath = null, $choices = null, $queryOb
$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);
}

/**
Expand Down Expand Up @@ -317,10 +341,14 @@ private function load()
{
$models = (array) $this->query->find();

$preferred = array();
if ($this->preferredQuery instanceof ModelCriteria) {
$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);
}
Expand Down
26 changes: 25 additions & 1 deletion src/Symfony/Bridge/Propel1/Form/Type/ModelType.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,29 @@
* ModelType class.
*
* @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
{
Expand All @@ -40,7 +63,8 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
$options['property'],
$options['choices'],
$options['query'],
$options['group_by']
$options['group_by'],
$options['preferred_choices']
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,29 @@ public function testFlattenedChoices()
$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');
Expand Down