Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public function loadChoicesForValues(array $values, $value = null)
// "INDEX BY" clause to the Doctrine query in the loader,
// but I'm not sure whether that's doable in a generic fashion.
foreach ($unorderedObjects as $object) {
$objectsById[$this->idReader->getIdValue($object)] = $object;
$objectsById[(string) $this->idReader->getIdValue($object)] = $object;
}

foreach ($values as $i => $id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bridge\Doctrine\Tests\Fixtures;

use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;

/** @Entity */
class SingleStringCastableIdEntity
{
/**
* @Id
* @Column(type="string")
* @GeneratedValue(strategy="NONE")
*/
protected $id;

/** @Column(type="string", nullable=true) */
public $name;

public function __construct($id, $name)
{
$this->id = new StringCastableObjectIdentity($id);
$this->name = $name;
}

public function __toString()
{
return (string) $this->name;
}
}

class StringCastableObjectIdentity
{
protected $id;

public function __construct($id)
{
$this->id = $id;
}

public function __toString()
{
return (string) $this->id;
}
}
136 changes: 136 additions & 0 deletions src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdEntity;
use Symfony\Bridge\Doctrine\Tests\Fixtures\GroupableEntity;
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity;
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringCastableIdEntity;
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity;
use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
Expand All @@ -40,6 +41,7 @@ class EntityTypeTest extends TypeTestCase
const SINGLE_IDENT_NO_TO_STRING_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity';
const SINGLE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity';
const SINGLE_ASSOC_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleAssociationToIntIdEntity';
const SINGLE_STRING_CASTABLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringCastableIdEntity';
const COMPOSITE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity';
const COMPOSITE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdEntity';

Expand Down Expand Up @@ -67,6 +69,7 @@ protected function setUp()
$this->em->getClassMetadata(self::SINGLE_IDENT_NO_TO_STRING_CLASS),
$this->em->getClassMetadata(self::SINGLE_STRING_IDENT_CLASS),
$this->em->getClassMetadata(self::SINGLE_ASSOC_IDENT_CLASS),
$this->em->getClassMetadata(self::SINGLE_STRING_CASTABLE_IDENT_CLASS),
$this->em->getClassMetadata(self::COMPOSITE_IDENT_CLASS),
$this->em->getClassMetadata(self::COMPOSITE_STRING_IDENT_CLASS),
);
Expand Down Expand Up @@ -580,6 +583,139 @@ public function testSubmitMultipleExpandedWithNegativeIntegerId()
$this->assertFalse($field['2']->getData());
}

public function testSubmitSingleNonExpandedStringCastableIdentifier()
{
$entity1 = new SingleStringCastableIdEntity(1, 'Foo');
$entity2 = new SingleStringCastableIdEntity(2, 'Bar');

$this->persist(array($entity1, $entity2));

$field = $this->factory->createNamed('name', 'entity', null, array(
'multiple' => false,
'expanded' => false,
'em' => 'default',
'class' => self::SINGLE_STRING_CASTABLE_IDENT_CLASS,
'choice_label' => 'name',
));

$field->submit('2');

$this->assertTrue($field->isSynchronized());
$this->assertSame($entity2, $field->getData());
$this->assertSame('2', $field->getViewData());
}

public function testSubmitSingleStringCastableIdentifierExpanded()
{
$entity1 = new SingleStringCastableIdEntity(1, 'Foo');
$entity2 = new SingleStringCastableIdEntity(2, 'Bar');

$this->persist(array($entity1, $entity2));

$field = $this->factory->createNamed('name', 'entity', null, array(
'multiple' => false,
'expanded' => true,
'em' => 'default',
'class' => self::SINGLE_STRING_CASTABLE_IDENT_CLASS,
'choice_label' => 'name',
));

$field->submit('2');

$this->assertTrue($field->isSynchronized());
$this->assertSame($entity2, $field->getData());
$this->assertFalse($field['0']->getData());
$this->assertTrue($field['1']->getData());
$this->assertNull($field['0']->getViewData());
$this->assertSame('2', $field['1']->getViewData());
}

public function testSubmitMultipleNonExpandedStringCastableIdentifierForExistingData()
{
$entity1 = new SingleStringCastableIdEntity(1, 'Foo');
$entity2 = new SingleStringCastableIdEntity(2, 'Bar');
$entity3 = new SingleStringCastableIdEntity(3, 'Baz');

$this->persist(array($entity1, $entity2, $entity3));

$field = $this->factory->createNamed('name', 'entity', null, array(
'multiple' => true,
'expanded' => false,
'em' => 'default',
'class' => self::SINGLE_STRING_CASTABLE_IDENT_CLASS,
'choice_label' => 'name',
));

$existing = new ArrayCollection(array(0 => $entity2));

$field->setData($existing);
$field->submit(array('1', '3'));

// entry with index 0 ($entity2) was replaced
$expected = new ArrayCollection(array(0 => $entity1, 1 => $entity3));

$this->assertTrue($field->isSynchronized());
$this->assertEquals($expected, $field->getData());
// same object still, useful if it is a PersistentCollection
$this->assertSame($existing, $field->getData());
$this->assertSame(array('1', '3'), $field->getViewData());
}

public function testSubmitMultipleNonExpandedStringCastableIdentifier()
{
$entity1 = new SingleStringCastableIdEntity(1, 'Foo');
$entity2 = new SingleStringCastableIdEntity(2, 'Bar');
$entity3 = new SingleStringCastableIdEntity(3, 'Baz');

$this->persist(array($entity1, $entity2, $entity3));

$field = $this->factory->createNamed('name', 'entity', null, array(
'multiple' => true,
'expanded' => false,
'em' => 'default',
'class' => self::SINGLE_STRING_CASTABLE_IDENT_CLASS,
'choice_label' => 'name',
));

$field->submit(array('1', '3'));

$expected = new ArrayCollection(array($entity1, $entity3));

$this->assertTrue($field->isSynchronized());
$this->assertEquals($expected, $field->getData());
$this->assertSame(array('1', '3'), $field->getViewData());
}

public function testSubmitMultipleStringCastableIdentifierExpanded()
{
$entity1 = new SingleStringCastableIdEntity(1, 'Foo');
$entity2 = new SingleStringCastableIdEntity(2, 'Bar');
$entity3 = new SingleStringCastableIdEntity(3, 'Bar');

$this->persist(array($entity1, $entity2, $entity3));

$field = $this->factory->createNamed('name', 'entity', null, array(
'multiple' => true,
'expanded' => true,
'em' => 'default',
'class' => self::SINGLE_STRING_CASTABLE_IDENT_CLASS,
'choice_label' => 'name',
));

$field->submit(array('1', '3'));

$expected = new ArrayCollection(array($entity1, $entity3));

$this->assertTrue($field->isSynchronized());
$this->assertEquals($expected, $field->getData());
$this->assertTrue($field['0']->getData());
$this->assertFalse($field['1']->getData());
$this->assertTrue($field['2']->getData());
$this->assertSame('1', $field['0']->getViewData());
$this->assertNull($field['1']->getViewData());
$this->assertSame('3', $field['2']->getViewData());
}

public function testOverrideChoices()
{
$entity1 = new SingleIntIdEntity(1, 'Foo');
Expand Down