Acceder al usuario logueado desde un form

Hola,

¿Como se puede acceder desde una clase FormType embebida al usuario logueado? Tengo una relación OneToMany entre la clase Padre y la clase Hijo. Cuando el usuario añade en la aplicación a un Padre le aparece la opción de "añadir hijos" para crear el registro de la familia a la vez.

He seguido la documentación oficial al respecto para embeber los formularios de hijos cuando creas al Padre y funciona a la perfección (https://symfony.com/doc/current/form/form_collections.html)

En el builder de la clase PadreType tengo lo siguiente:

->add('hijos', CollectionType::class, array(
                'entry_type'   => HijoType::class,
                'allow_add'    => true,
                'by_reference' => false,
            ));

El problema está en que el formulario HijoType uno de los campos es un desplegable que muestra varias opciones pero deben ser filtradas dependiendo del usuario logueado en la aplicación.

En HijoType trato de hacer esto:

->add('etapa', 'entity', array(
                'class' => 'AppBundle\Entity\Etapa',
                'property' => 'line',
                'query_builder' => function(EntityRepository $er) use ( $user ) {
                    return $er->createQueryBuilder('e')
                              ->where('e.organizacion = :organizacion')
                              ->setParameter('organizacion', $user->getOrganizacion());
                        }
         ))

Tratando de obtener el user así:

$user = $this->getConfigurationPool()->getContainer()->get('security.token_storage')->getToken()->getUser();

pero no puedo acceder al container.

¿Alguna idea? He leído en foros que se puede pasar el usuario como parámetro a la hora de crear el form en el controller, pero al necesitarlo en un formulario embebido no se si podría usar en HijoType un valor que solo se le pasa a PadreType.

Le echado un ojo a los filtros de doctrine pero igual es matar moscas a cañonazos.

Gracias por adelantado.

Respuestas

#1

Crea tu formulario como un servicio que tenga como parámetro el token_storage. Aquí puedes leer en la doc de symfony Personalmente me gusta más la opción 2 de la documentación pero ambas son válidas. Acá te dejo un ejemplo de como normalmente la pongo en práctica.

Ejemplo:

class ParametrosProbabilidadRiesgoType extends AbstractType
{
    private $tokenStorage;
 
    function __construct(TokenStorage $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
    }
 
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('nombre')
            ->add('valorInicial')
            ->add('valorIncremento')
            ->add('orden');
    }
 
    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'ConfiguracionBundle\Entity\ParametrosProbabilidadRiesgo'
        ));
    }
 
    public function obtenerUsuario()
    {
        return $this->tokenStorage->getToken()->getUser();
    }
 
}

y declaro el form as service de la siguiente forma en el services.yml o cualquier que sea el archivo donde tengas tus servicios:

proyecto.parametros_probabilidad_riesgo_form:
    class: ConfiguracionBundle\Form\Type\ParametrosProbabilidadRiesgoType
    arguments: ["@security.token_storage"]
    tags:
      - { name: form.type }

Espero que te sirva, Saludos.

#2

Cualquier inconveniente o error déjale por acá.

#3

Muchas gracias!! Funciona perfectamente.