From 25e3abd683727bde9acadb0994487debac644e94 Mon Sep 17 00:00:00 2001 From: Toni Uebernickel Date: Fri, 7 Jun 2013 15:46:31 +0200 Subject: [PATCH] fix many-to-many Propel1 ModelChoiceList --- .../Form/ChoiceList/ModelChoiceList.php | 29 +++++++++++++++++-- .../Form/ChoiceList/ModelChoiceListTest.php | 14 +++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php index e33934fbff..611139ae69 100644 --- a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php +++ b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php @@ -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; } /** diff --git a/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php b/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php index 748b1cd9b1..59f1367f2a 100644 --- a/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php +++ b/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php @@ -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))); + } }