Я предполагаю, что вы используете тип entity
в вашей форме. Они довольно тяжелые, так как сначала все объекты выбираются как объекты, а затем уменьшаются до некоторого id => label
.
Таким образом, вы могли бы написать свой собственный entityChoice
тип, который работает с id => label
-array (так что ничего не забирается в качестве объекта в Фрист месте) и добавить DataTransformer к этому типу:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use MyNamespace\EntityToIdTransformer;
class EntityChoiceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addModelTransformer(new EntityToIdTransformer($options['repository']));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'empty_value' => false,
'empty_data' => null,
));
$resolver->setRequired(array(
'repository'
));
}
public function getParent()
{
return 'choice';
}
public function getName()
{
return 'entityChoice';
}
}
И как DataTransformer:
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class EntityToIdTransformer implements DataTransformerInterface
{
private $entityRepository;
public function __construct(EntityRepository $entityRepository)
{
$this->entityRepository = $entityRepository;
}
/**
* @param object|array $entity
* @return int|int[]
*
* @throws TransformationFailedException
*/
public function transform($entity)
{
if ($entity === null) {
return null;
}
elseif (is_array($entity) || $entity instanceof \Doctrine\ORM\PersistentCollection) {
$ids = array();
foreach ($entity as $subEntity) {
$ids[] = $subEntity->getId();
}
return $ids;
}
elseif (is_object($entity)) {
return $entity->getId();
}
throw new TransformationFailedException((is_object($entity)? get_class($entity) : '').'('.gettype($entity).') is not a valid class for EntityToIdTransformer');
}
/**
* @param int|array $id
* @return object|object[]
*
* @throws TransformationFailedException
*/
public function reverseTransform($id)
{
if ($id === null) {
return null;
}
elseif (is_numeric($id)) {
$entity = $this->entityRepository->findOneBy(array('id' => $id));
if ($entity === null) {
throw new TransformationFailedException('A '.$this->entityRepository->getClassName().' with id #'.$id.' does not exist!');
}
return $entity;
}
elseif (is_array($id)) {
if (empty($id)) {
return array();
}
$entities = $this->entityRepository->findBy(array('id' => $id)); // its array('id' => array(...)), resulting in many entities!!
if (count($id) != count($entities)) {
throw new TransformationFailedException('Some '.$this->entityRepository->getClassName().' with ids #'.implode(', ', $id).' do not exist!');
}
return $entities;
}
throw new TransformationFailedException(gettype($id).' is not a valid type for EntityToIdTransformer');
}
}
И, наконец, зарегистрировать FormType как новый тип в service.yml
services:
myNamespace.form.type.entityChoice:
class: MyNamespace\EntityChoiceType
tags:
- { name: form.type, alias: entityChoice }
Вы можете использовать его в форме
$formBuilder->add('appliance', 'entityChoice', array(
'label' => 'My Label',
'repository' => $repository,
'choices' => $repository->getLabelsById(),
'multiple' => false,
'required' => false,
'empty_value' => '(none)',
))
с $repository
как экземпляр нужного хранилища и 'choices'
как массив с id => label
не использовать тип 'entity' но только' выбор 'с' id => label' и напишите [DataTransformers] (http://symfony.com/doc/current/cookbook/form/data_transformers.html). Затем вы работаете только с равными значениями и только в конце, когда что-то было выбрано, преобразуйте его в желаемый объект – SBH