Symfony 2.5: Entity type, prevents getting all records when submitting a form

I have a form that contains some classics fields and a drop-down list of user objects (processed using AngularJs, and not with the classic form view). When I submit the form, the entire object (and the User selected using the drop-down list) is sent to my controller using an Ajax request.

class MyRestController{

    public function MyRestAction(...){
        ...
        $myObject = new MyObject();

        $myForm = $this->createForm(new MyFormType(), $myObject);

        $myForm->handleRequest($request);

        ...
    }
}

class MyFormType extends AbstractType{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add(...),
            ->add(...),
            ->add(...),
            ->add('user', 'entity', array(
                'required' => true,
                'class' => 'User',
                'property' => 'id',
            ))
        ;
            ...
    }

}

Then I save the whole object and clear it. It works great. But the process is insanely slow ...

The problem arises from the handleRequest function when the getChoicesForValue (EntityChoiceList.php) function is called. In my case, the process executes the findAll () query in the user entity, retrieves all the records (thousands) from the database.

, , EntityChoiceList entityLoader:

if ($this->idAsValue && $this->entityLoader) {
    // do a findById()
} else {
    // do a findAll()
}

( , , EntityChoiceList.php). , $this->idAsValue true, $this->entityLoader null, , findAll().

, , -, ?

.

:

, handleRequest , , .

+4
1

, . , DataTransformer, User. , , .

:

:

class MyFormType extends AbstractType{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('user', 'entity', array(
                'required' => true,
                'class' => 'User',
                'property' => 'id',
            ))
        ;
    }

}

to:

class MyFormType extends AbstractType{

    private $manager;

    public function __construct(ObjectManager $manager)
    {
        $this->manager = $manager;
    }
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('user', 'text', array(
                'required' => true,
            ))
        ;
       // we use a specific ModelTransformer (UserTransformer) created by ourself (see below)
       $builder->get('user')->addModelTransformer(new UserTransformer($this->manager));
    }

}

UserTransformer, :

class UserTransformer implements DataTransformerInterface
{
    private $manager;

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

    public function transform($user)
    {
        if (null === $user) {
            return '';
        }

        return $user->getId();
    }

    public function reverseTransform($id)
    {
        if (!$id) {
            return null;
        }

        $user= $this->manager
            ->getRepository(User::class)
            ->find($id)
        ;

        if (null === $user) {
            throw new TransformationFailedException(sprintf(
                'There is no User with the id "%s" !',
                $id
            ));
        }
        return $user;
    }
}

, , EntityManager :

class MyRestController{

    public function MyRestAction(...){
        ...
        $myObject = new MyObject();

        $manager = $this->getDoctrine()->getManager();
        $myForm = $this->createForm(new MyFormType($manager), $myObject);

        $myForm->handleRequest($request);

        ...
    }
}

Symfony :  https://symfony.com/doc/2.7/form/data_transformers.html

, 10 !

0

Source: https://habr.com/ru/post/1694008/


All Articles