Setear un párametro en una consulta creada con el QueryBuilder

Hola a todos, tengo dos dudas, la primera es qué atributo utilizo para pasar del controlador a un form builder un id. Con ['by_reference'] lo paso pero no se si es lo adecuado.

La segunda pregunta es una vez recibo y guardo la id en una variable, como se la paso al setParamenters, e probado de varias maneras pero no reconoce $id_centro. Gracias

public function buildForm(FormBuilderInterface $builder, array $options)
{
   $id_centro = $options['by_reference'];
 
    $builder
        ->add('aula', TextType::class,array())
        ->add('curso', TextType::class,array())
        ->add('usuarios', EntityType::class, ['class' => 'UsuariosBundle:Usuario',
            'query_builder' => function (EntityRepository $er) {
                return $er->createQueryBuilder('u')
                    ->orderBy('u.nombre', 'ASC')
                    ->where ('u.centro = ?1')
                    ->setParamenters(1,$id_centro)
                ;
            },
        ])
    ;
}

Respuestas

#1

Amigo lo que se le pasa a query builder es una función anónima, ella no tiene acceso a la variable $id_centro. Quisas no sea lo mejor pero puedes meterle una pequeña cañona.

public function buildForm(FormBuilderInterface $builder, array $options)
 
{    
   global $id_centro;
   $id_centro = $options['by_reference'];
 
    $builder
        ->add('aula', TextType::class,array())
        ->add('curso', TextType::class,array())
        ->add('usuarios', EntityType::class, ['class' => 'UsuariosBundle:Usuario',
                 'query_builder' => function (EntityRepository $er){
    global $id_centro;
    return $er->createQueryBuilder('u')
        ->orderBy('u.nombre', 'ASC')
            ->where ('u.centro = ?1')
            ->setParamenters(1,$id_centro)
           ;
},
 
]);
#2

Es posible "pasar" o hacer accesibles variables dentro de una funcion anonima con la sintaxis use:

$nombre = 'Manuel';
$apellido = 'Aguirre';
$fecha = "10-10-2016";
 
$callback = function() use ($nombre, $apellido) {
   // las variables $nombre y $apellidos son accesibles
   // gracias a que se ha indicado su uso dentro de la función.
   // la variable $fecha no es accesible ya que no se agregó en el use
};

Saludos!

#3

Por qué en vez de pasar el $id_centro al formulario no lo obtienes de alguna manera(de la misma que lo obtienes en el controlador desde donde se lo pasas por referencia) inyectando algun servicio necesario para llegar a la entidad que lo contiene, ya sea el token storage si lo que quieres es filtrar por el centro del usuario logueado, el entity manager si es que necesitas una query mas específica para recuperarlo. Luego deberías declarar tu formulario como servicio, la ventaja es que podrías reutilizarlo en cualquier punto de tu aplicación solo como MyFormNameType::class sin preocuparte lo que necesitas para instanciarlo ni tan siquiera del famoso $id_centro.

Sería algo como esto(fíjate que yo no paso ningún $id_cuenta para mostrar las empresas de una cuenta determinada en este caso la del usuario logueado):

private $tokenStorage;
 
    function __construct(TokenStorageInterface $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
    }
 
    public function obtenerUsuario()
    {
        return $this->tokenStorage->getToken()->getUser();
    }
 
    public function obtenerCuenta()
    {
        return $this->obtenerUsuario()->getCuenta();
    }
 
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('nombre', TextType::class, array(
                'label' => 'Nombre'
            ))
            ->add('direccion', TextType::class, array(
                'label' => 'Dirección'
            ))
            ->add('empresa', EntityType::class, array(
                'choice_label' => 'nombre',
                'class' => 'MyBundle:Empresa',
                'label' => 'Empresa',
                'query_builder' => function (EntityRepository $er) {
                    return $er->createQueryBuilder('e')
                        ->where('e.cuenta = :cuenta')
                        ->setParameter('cuenta', $this->obtenerCuenta());
                }));
    }

La declaración del formulario como servicio sería:

app.type.sucursal:
        class: MyBundle\Form\Type\SucursalType
        arguments: ["@security.token_storage"]
        tags:
            - { name: form.type }

Saludos.

#4

Echale un vistazo a este post

#5

Gracias a todos probare a ver con algún método de los expuestos. Un saludo.