Skip to content

Instantly share code, notes, and snippets.

@lunetics
Created December 28, 2015 20:43
Show Gist options
  • Save lunetics/645b34bf0a77349871fb to your computer and use it in GitHub Desktop.
Save lunetics/645b34bf0a77349871fb to your computer and use it in GitHub Desktop.
<?php
namespace AppBundle\Form\Type
use AppBundle\Form\DataTransformer\ContactPersonLanguageModelTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AcmeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
/** the actual collection used as choicetype now! **/
->add(
'languages',
ChoiceType::class,
[
'choices' => array_flip(Intl::getLanguageBundle()->getLanguageNames()),
'preferred_choices' => ['de','en','el','fr','nl','dk','no','uk','cs','es','it','pt','pl','tr','ru','ja','zh'],
'choices_as_values' => true,
'placeholder' => 'please select a language',
'attr' => [
'style' => 'width: 100%;'
],
'multiple' => true,
'expanded' => false
]
);
;
$builder->get('languages')
->addModelTransformer(new CollectionEntityPropertyToArrayModelTransformer('language'));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => 'AppBundle\Entity\AcmeEntity',
'cascade_validation' => false,
'attr' => ['novalidate' => 'novalidate']
]
);
}
}
<?php
namespace AppBundle\Form\DataTransformer;
use Doctrine\Common\Collections\Criteria;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
class CollectionEntityPropertyToArrayModelTransformer implements DataTransformerInterface
{
/**
* Name of the property of the entity
*
* @var string
*/
protected $propertyName;
/**
*
* @param string $propertyName
*/
public function __construct($propertyName)
{
$this->propertyName = $propertyName;
}
/**
* @var \Doctrine\ORM\PersistentCollection
*/
private $persistentCollection;
/**
* Transforms an collection into an array with the currently propertyvalues
*
* @param \Doctrine\ORM\PersistentCollection|null $collection
*
* @return array
*/
public function transform($collection)
{
$accessor = PropertyAccess::createPropertyAccessor();
$array = [];
$this->persistentCollection = $collection;
/** @var \ArrayIterator $iterator */
$iterator = $collection->getIterator();
while ($iterator->valid()) {
$array[] = $accessor->getValue($iterator->current(), $this->propertyName);
$iterator->next();
}
return $array;
}
/**
* Transforms an array to an collection
*
* @param array $array
*
* @return \Doctrine\ORM\PersistentCollection
*/
public function reverseTransform($array)
{
$accessor = PropertyAccess::createPropertyAccessor();
$owner = $this->persistentCollection->getOwner();
$targetEntity = $this->persistentCollection->getMapping()['targetEntity'];
$mappedBy = $this->persistentCollection->getMapping()['mappedBy'];
foreach ($array as $value) {
$exists = Criteria::create()
->where(Criteria::expr()->eq($this->propertyName, $value));
if ($this->persistentCollection->matching($exists)->count() <= 0) {
$entity = new $targetEntity();
/** Set owner */
$accessor->setValue($entity, $mappedBy, $owner);
/* Set property value */
$accessor->setValue($entity, $this->propertyName, $value);
$this->persistentCollection->add($entity);
}
}
foreach ($this->persistentCollection as $entity) {
if (!in_array($accessor->getValue($entity, $this->propertyName), $array)) {
$this->persistentCollection->removeElement($entity);
}
}
return $this->persistentCollection;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment