add preferred_query option to ModelType
This enables the ModelChoiceList to use 'preferred_choices' of the parent ChoiceType.
This commit is contained in:
parent
031a09dc00
commit
6855cffb1d
|
@ -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 <william.durand1@gmail.com>
|
||||
* @author Toni Uebernickel <tuebernickel@gmail.com>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,29 @@ use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
|||
* ModelType class.
|
||||
*
|
||||
* @author William Durand <william.durand1@gmail.com>
|
||||
* @author Toni Uebernickel <tuebernickel@gmail.com>
|
||||
*
|
||||
* Example using the preferred_query 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_query' => ProductQuery::create()
|
||||
* ->filterByIsTopProduct(true)
|
||||
* ,
|
||||
* ))
|
||||
* ;
|
||||
* }
|
||||
* </code>
|
||||
*/
|
||||
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,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
|
Reference in New Issue