merged branch havvg/2.2 (PR #8240)

This PR was merged into the 2.2 branch.

Discussion
----------

[Propel1] fix many-to-many Propel1 ModelChoiceList

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| License       | MIT

replaces #8223

Commits
-------

25e3abd fix many-to-many Propel1 ModelChoiceList
This commit is contained in:
Fabien Potencier 2013-06-10 16:56:21 +02:00
commit f4788121eb
2 changed files with 40 additions and 3 deletions

View File

@ -256,14 +256,14 @@ class ModelChoiceList extends ObjectChoiceList
*/
public function getIndicesForChoices(array $models)
{
$indices = array();
if (!$this->loaded) {
// Optimize performance for single-field identifiers. We already
// know that the IDs are used as indices
// Attention: This optimization does not check choices for existence
if ($this->identifierAsIndex) {
$indices = array();
foreach ($models as $model) {
if ($model instanceof $this->class) {
// Make sure to convert to the right format
@ -277,7 +277,30 @@ class ModelChoiceList extends ObjectChoiceList
$this->load();
}
return parent::getIndicesForChoices($models);
/*
* Overwriting default implementation.
*
* The two objects may represent the same entry in the database,
* but if they originated from different queries, there are not the same object within the code.
*
* This happens when using m:n relations with either sides model as data_class of the form.
* The choicelist will retrieve the list of available related models with a different query, resulting in different objects.
*/
$choices = $this->fixChoices($models);
foreach ($this->getChoices() as $i => $choice) {
foreach ($choices as $j => $givenChoice) {
if ($this->getIdentifierValues($choice) === $this->getIdentifierValues($givenChoice)) {
$indices[] = $i;
unset($choices[$j]);
if (0 === count($choices)) {
break 2;
}
}
}
}
return $indices;
}
/**

View File

@ -185,4 +185,18 @@ class ModelChoiceListTest extends Propel1TestCase
$this->assertEquals(array(1, 2), $choiceList->getValuesForChoices(array($item1, $item2)));
$this->assertEquals(array(1, 2), $choiceList->getIndicesForChoices(array($item1, $item2)));
}
public function testDifferentEqualObjectsAreChoosen()
{
$item = new Item(1, 'Foo');
$choiceList = new ModelChoiceList(
self::ITEM_CLASS,
'value',
array($item)
);
$choosenItem = new Item(1, 'Foo');
$this->assertEquals(array(1), $choiceList->getIndicesForChoices(array($choosenItem)));
}
}