Symfony 5.1 lista de opciones filtrando
Estoy usando Symfony 5.1 para filtrar una entidad en un tipo de formulario.
->add('ageGroup', EntityType::class, [
'class' => AgeGroup::class,
'choice_label' => 'name',
'choice_filter' => ChoiceList::filter(
$this,
function ($ageGroup) {
if ($ageGroup instanceof AgeGroup) {
return $ageGroup->getOrganization()->getId() == $this->security->getUser()->getOrganization()->getId();
}
return false;
}
)
])
->add('room', EntityType::class, [
'class' => Room::class,
'choice_label' => 'name',
'choice_filter' => ChoiceList::filter(
$this,
function ($room) {
if ($room instanceof Room) {
return $room->getBranch()->getOrganization()->getId() == $this->security->getUser()->getOrganization()->getId();
}
return false;
}
),
])
Tengo un problema interesante. Cualquier cosa ChoiceList::filter
es primero funcionará pero ningún otro filtro funcionará después.
Esto es cuando ->add('ageGroup')
fue colocado primero.
Esto es cuando ->add('room')
fue colocado primero.
La segunda lista de opciones no se llama. Para nada.
De hecho, ninguna otra ChoiceList::filter
se llama si agrego más de 1.
https://symfony.com/doc/current/reference/forms/types/choice.html no pone ninguna limitación sobre cuántos se puede llamar.
Claramente lo estoy haciendo
Ni siquiera puedo empezar a adivinar qué tiene de malo.
Pregunta hecha hace 3 años, 4 meses, 29 días - Por algorithmadeptc6cb
3 Respuestas:
-
El
ChoiceList::filter
método toma un tercer argumento llamado$vary
.De acuerdo con el PHP Doc comment:
/** * @param FormTypeInterface|FormTypeExtensionInterface $formType A form type or type extension configuring a cacheable choice list * @param mixed $option Any pseudo callable, array, string or bool to define a choice list option * @param mixed|null $vary Dynamic data used to compute a unique hash when caching the option */
La función de corte usada dentro de este método utiliza php incorporado
spl_object_hash()
sobre$formType
objeto, que dará el mismo id para ambos callbacks. Pase el nombre de campo (o cualquier otra cosa que sea única) como un tercer argumento:->add('ageGroup', EntityType::class, [ 'class' => AgeGroup::class, 'choice_label' => 'name', 'choice_filter' => ChoiceList::filter( $this, function ($ageGroup) { if ($ageGroup instanceof AgeGroup) { return $ageGroup->getOrganization()->getId() == $this->security->getUser()->getOrganization()->getId(); } return false; }, 'ageGroup' ) ]) ->add('room', EntityType::class, [ 'class' => Room::class, 'choice_label' => 'name', 'choice_filter' => ChoiceList::filter( $this, function ($room) { if ($room instanceof Room) { return $room->getBranch()->getOrganization()->getId() == $this->security->getUser()->getOrganization()->getId(); } return false; }, 'room' ), ])
Respondida el Dec 17, 2020 a las 19:25 - por codergeek24
Votos positivos: 0 | Votos negativos: 0 -
El problema que estás experimentando se debe a cómo se están aplicando los filtros en tus campos de formulario. En Symfony, cuando se utilizan filtros en campos de tipo EntityType, estos deben ser aplicados a nivel de consulta en el repositorio de la entidad, en lugar de utilizar ChoiceList::filter directamente en el campo.
Para filtrar las opciones de forma adecuada en Symfony 5.1, puedes hacer lo siguiente:
- Define un EntityType personalizado que extienda de EntityType y sobrescribe el método finishView:
php namespace App\Form\Type; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; class FilteredEntityType extends EntityType { protected function finishView(FormView $view, FormInterface $form, array $options) { parent::finishView($view, $form, $options); $filterFunction = $options['filter']; $view->vars['choices'] = array_filter($view->vars['choices'], function ($choice) use ($filterFunction) { return $filterFunction($choice->data); }); } }
- Luego, utiliza este nuevo tipo de campo en tus formularios:
php use App\Form\Type\FilteredEntityType; // En tu formulario
- >add('ageGroup', FilteredEntityType::class, [
- >add('room', FilteredEntityType::class, [
Al hacerlo de esta manera, aseguras que los filtros se aplicarán correctamente a nivel de consulta en el repositorio de la entidad cuando se renderice el campo en el formulario. Esto debería solucionar el problema que estás experimentando con los filtros en tus campos de formulario.
Respondida el Dec 18, 2020 a las 19:25 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El problema que estás experimentando con los filtros de ChoiceList en Symfony 5.1 probablemente se deba a que estás usando el mismo callable para filtrar múltiples campos de entidad.
Cuando utilizas
ChoiceList::filter
, estás creando un nuevo filtro para un campo de entidad específico. En tu caso, estás utilizando el mismo callable para filtrar tanto el campoageGroup
como el camporoom
. Esto significa que Symfony solo aplicará el último filtro que agregaste, que en este caso es el filtro para el camporoom
.Para resolver este problema, debes crear un callable único para cada campo de entidad que desees filtrar. Aquí tienes un ejemplo actualizado de tu código:
php
- >add('ageGroup', EntityType::class, [
- >add('room', EntityType::class, [
Al crear callables únicos para cada filtro, te aseguras de que cada campo de entidad se filtre correctamente. Esto debería resolver el problema de que no se llamen los filtros posteriores.
Respondida el Dec 18, 2020 a las 19:38 - por Gemini
Votos positivos: 0 | Votos negativos: 0