Skip to content

Instantly share code, notes, and snippets.

@MacDada
Created March 30, 2016 20:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MacDada/33ab6b74ae681ff83854bd542fb209d3 to your computer and use it in GitHub Desktop.
Save MacDada/33ab6b74ae681ff83854bd542fb209d3 to your computer and use it in GitHub Desktop.
<?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);
}
}
<?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;
}
}
<?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