Skip to content

Commit

Permalink
fix many-to-many Propel1 ModelChoiceList
Browse files Browse the repository at this point in the history
  • Loading branch information
havvg committed Jun 10, 2013
1 parent 1f26887 commit 25e3abd
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php
Expand Up @@ -256,14 +256,14 @@ public function getValuesForChoices(array $models)
*/
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
Expand All @@ -277,7 +277,30 @@ public function getIndicesForChoices(array $models)
$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;
}

/**
Expand Down
Expand Up @@ -185,4 +185,18 @@ public function testGetValuesForChoices()
$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)));
}
}

0 comments on commit 25e3abd

Please sign in to comment.