Created
March 30, 2016 20:15
-
-
Save MacDada/33ab6b74ae681ff83854bd542fb209d3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AppBundle\Form\DataTransformer; | |
use AppBundle\Entity\Entity; | |
use AppBundle\Entity\EntityRepository; | |
use Symfony\Component\Form\DataTransformerInterface; | |
use Symfony\Component\Form\Exception\TransformationFailedException; | |
class EntitiesToIdsDataTransformer implements DataTransformerInterface | |
{ | |
/** | |
* @var EntityRepository | |
*/ | |
private $entityRepository; | |
public function __construct(EntityRepository $entity) | |
{ | |
$this->entityRepository = $entity; | |
} | |
/** | |
* @param array|\Traversable|null $value | |
* @return array|string | |
* @throws TransformationFailedException | |
*/ | |
public function transform($value) | |
{ | |
if (null === $value) { | |
// as the DataTransformerInterface suggests | |
return ''; | |
} | |
if (!is_array($value) && !$value instanceof \Traversable) { | |
throw new TransformationFailedException(sprintf( | |
'Array or Traversable expected, %s given', | |
gettype($value) | |
)); | |
} | |
$ids = []; | |
foreach ($value as $entity) { | |
if (!$entity instanceof Entity) { | |
throw new TransformationFailedException(sprintf( | |
'%s expected, %s given', | |
Entity::class, | |
gettype($entity) | |
)); | |
} | |
$ids[] = $entity->getId(); | |
} | |
return $ids; | |
} | |
/** | |
* @param array|null $value | |
* @return \AppBundle\Entity\Entity[]|null | |
* @throws TransformationFailedException | |
*/ | |
public function reverseTransform($value) | |
{ | |
if (empty($value)) { | |
// as the DataTransformerInterface suggests | |
return null; | |
} | |
if (!is_array($value)) { | |
throw new TransformationFailedException(sprintf( | |
'Array expected, %s given', | |
gettype($value) | |
)); | |
} | |
return $this->entityRepository->findByIds($value); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AppBundle\Tests\Form\DataTransformer; | |
use AppBundle\Entity\Entity; | |
use AppBundle\Entity\EntityRepository; | |
use AppBundle\Form\DataTransformer\EntitiesToIdsDataTransformer; | |
use Doctrine\Common\Collections\ArrayCollection; | |
class EntitiesToIdsDataTransformerTest extends \PHPUnit_Framework_TestCase | |
{ | |
/** | |
* @var EntitiesToIdsDataTransformer | |
*/ | |
private $transformer; | |
/** | |
* @var EntityRepository|\PHPUnit_Framework_MockObject_MockObject | |
*/ | |
private $entityRepository; | |
/** | |
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException | |
* @expectedExceptionMessage Array or Traversable expected | |
*/ | |
public function testTransformExpectsArrayOrTraversable() | |
{ | |
$this->transformer->transform('not an array nor traversable'); | |
} | |
public function testTransformReturnsEmptyStringOnNull() | |
{ | |
$this->assertSame('', $this->transformer->transform(null)); | |
} | |
public function testTransformEmptyList() | |
{ | |
$this->assertEquals([], $this->transformer->transform([])); | |
$this->assertEquals([], $this->transformer->transform(new ArrayCollection())); | |
} | |
/** | |
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException | |
* @expectedExceptionMessage Entity expected | |
*/ | |
public function testTransformRequiresEntities() | |
{ | |
$this->transformer->transform([ | |
$this->mockEntity(1), | |
$this->mockEntity(2), | |
'not an Entity', | |
$this->mockEntity(3), | |
]); | |
} | |
public function testTransformEntitiesReturnsTheirIds() | |
{ | |
$entities = [ | |
$this->mockEntity(4), | |
$this->mockEntity(5), | |
$this->mockEntity(6), | |
$this->mockEntity(7), | |
]; | |
$this->assertEquals([4, 5, 6, 7], $this->transformer->transform($entities)); | |
$this->assertEquals([4, 5, 6, 7], $this->transformer->transform(new ArrayCollection($entities))); | |
} | |
public function testReverseTransformReturnsNullOnEmptyValue() | |
{ | |
$this->assertNull($this->transformer->reverseTransform(null)); | |
$this->assertNull($this->transformer->reverseTransform('')); | |
$this->assertNull($this->transformer->reverseTransform(0)); | |
} | |
public function testReverseTransformReturnsEntitiesFromIds() | |
{ | |
$ids = [2, 3, 4, 5]; | |
$entities = [ | |
$this->mockEntity(2), | |
$this->mockEntity(3), | |
$this->mockEntity(4), | |
$this->mockEntity(5), | |
]; | |
$this->entityRepository | |
->expects($this->once()) | |
->method('findByIds') | |
->with($ids) | |
->willReturn($entities); | |
$this->assertEquals($entities, $this->transformer->reverseTransform($ids)); | |
} | |
/** | |
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException | |
* @expectedExceptionMessage Array expected | |
*/ | |
public function testReverseTransformExpectsArray() | |
{ | |
$this->transformer->reverseTransform('not an array'); | |
} | |
protected function setUp() | |
{ | |
$this->entityRepository = $this->getMockBuilder(EntityRepository::class) | |
->disableOriginalConstructor() | |
->getMock(); | |
$this->transformer = new EntitiesToIdsDataTransformer($this->entityRepository); | |
} | |
private function mockEntity($id) | |
{ | |
$entity = $this->getMockBuilder(Entity::class) | |
->disableOriginalConstructor() | |
->getMock(); | |
$entity | |
->method('getId') | |
->willReturn($id); | |
return $entity; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AppBundle\Form; | |
use AppBundle\Entity\EntityRepository; | |
use AppBundle\Form\DataTransformer\EntitiesToIdsDataTransformer; | |
use DTL\Symfony\Form\DataTransformer\ArrayToDelimitedStringTransformer; | |
use Symfony\Component\Form\AbstractType; | |
use Symfony\Component\Form\CallbackTransformer; | |
use Symfony\Component\Form\FormBuilderInterface; | |
class EntityIdsDelimitedByCommaType extends AbstractType | |
{ | |
private $entityRepository; | |
public function __construct(EntityRepository $entityRepository) | |
{ | |
$this->entityRepository = $entityRepository; | |
} | |
public function buildForm(FormBuilderInterface $builder, array $options) | |
{ | |
$builder->add('entity_ids_delimited_by_comma', 'text', ['required' => false]); | |
$builder->get('entity_ids_delimited_by_comma') | |
// user can type ids delimited by commas | |
// https://packagist.org/packages/dantleech/symfony-form-array-to-delimited-string-transformer | |
->addModelTransformer(new ArrayToDelimitedStringTransformer(',', 0, 0)) | |
// just ignore that user typed the same id twice | |
->addModelTransformer(new CallbackTransformer('array_unique', 'array_unique')) | |
// after all, we want the entity objects | |
->addModelTransformer(new EntitiesToIdsDataTransformer($this->entityRepository)); | |
} | |
public function getName() | |
{ | |
return 'entity_ids_delimited_by_comma'; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment