Este bundle de Symfony permite crear un backend de administración para aplicaciones Symfony de una forma totalmente simple, de ahí su nombre easy 🙂
Entre las funcionalidadeses de EasyAdminBundle nos encontramos con las siguientes:
Operaciones CRUD para entidades de Doctrine.
Búsqueda full-text, paginación y ordenado de columnas.
Diseño Responsive.
Soporte para Symfony 2+.
Traducciones en 10 idiomas.
EasyAdmin es obra de Javier Eguiluz un desarrollador español que colabora en el desarrollo de Symfony desde Sensiolabs y pone su granito de arena con este bundle. Además de su colaboración en el framework, es el creador de la web de Symfony.es, ha publicado varios libros sobre desarrollo web y es ponente de varias charlas sobre Symfony.
¿Cómo customizo EasyAdmin?
Desde hace tiempo vengo usando otro bundle con el mismo propósito y también conocido en la comunidad de desarrolladores Symfony: SonataAdminBundle. Ya conocía las tripas de este bundle y he tenido que personalizarlo en repetidas ocasiones para varios proyectos, incluso convirtiéndolo en una herramienta de back-office para una operadora móvil virtual, siendo parte core de la gestión de sus pedidos.
Sin embargo, he comenzado a utilizar este proyecto y requería que en el listado se incluyeran unos filtros personalizados más allá del full-text. Buceando por la red he visto que el propio Javier había comentado que esta funcionalidad todavía no estaba implementada pero estaba en la lista de deseos/roadmap de próximas funcionalidades. ¡Por cierto, no es mala idea colaborar para hacer crecer este proyecto en la comunidad open-source!
Volviendo a mi problema, el bundle no proporciona esta funcionalidad, pero si que está pensado que la herramienta sea totalmente extensible. En este enlace, se detalla como podemos personalizar en función de nuestras necesidades los controladores por entidad, las plantillas que se renderizan en cada vista y los eventos que podemos escuchar.
Tras bucear por el código del vendor, he podido ver los métodos que necesitaba pisar del bundle y he conseguido el objetivo. Voy a detallar a continuación los cambios que deberíais utilizar para poder implementar los filtros personalizados.
Personalizando listAction()
Lo primero que debemos hacer es customizar la acción del listado. Para ello, se ha sobrescrito el listAction, y se ha incluido la creación del formulario EventAdminFiltersType, devolviéndolo a la vista.
protected function listAction()
{
$this->dispatch(EasyAdminEvents::PRE_LIST);
$fields = $this->entity['list']['fields'];
$paginator = $this->findAll($this->entity['class'], $this->request->query->get('page', 1), $this->entity['list']['max_results'], $this->request->query->get('sortField'), $this->request->query->get('sortDirection'), $this->entity['list']['dql_filter']);
$this->dispatch(EasyAdminEvents::POST_LIST, array('paginator' => $paginator));
$form = $this->createForm(EventAdminFiltersType::class);
$parameters = array(
'paginator' => $paginator,
'fields' => $fields,
'delete_form_template' => $this->createDeleteForm($this->entity['name'], '__id__')->createView(),
'search_form' => $form->createView()
);
return $this->executeDynamicMethod('render<EntityName>Template', array('list', $this->entity['templates']['list'], $parameters));
}
Personalizando la plantilla list.html.twig
Una vez tenemos el formulario creado en el controlador es momento de renderizarlo en la vista. Para ello, vamos a customizar nuestra plantilla incluyéndola en app/Resources/views/easy_admin/{NombreModelo}/list.html.twig. Viendo la plantilla padre vemos que el bloque que necesitamos customizar es dónde se pinta actualmente el formulario de búsqueda.
Para ello, pisamos el bloque search_form y pintamos nuestro formulario.
{% extends '@EasyAdmin/default/list.html.twig' %}{% block search_form %}{{ form_widget(search_form.category) }}{{ form_widget(search_form.area) }}{{ form_widget(search_form.specialty) }}<inputtype="hidden"name="action"value="search"><inputtype="hidden"name="entity"value="{{ _request_parameters.entity }}"><inputtype="hidden"name="sortField"value="{{ _entity_config.search.sort.field|default(_request_parameters.sortField) }}"><inputtype="hidden"name="sortDirection"value="{{ _entity_config.search.sort.direction|default(_request_parameters.sortDirection) }}"><inputtype="hidden"name="menuIndex"value="{{ _request_parameters.menuIndex }}"><inputtype="hidden"name="submenuIndex"value="{{ _request_parameters.submenuIndex }}"><divclass="input-group">{{ form_row(search_form.query) }}<inputclass="form-control"type="hidden"name="query"value="{{ app.request.get('query')|default('') }}"><spanclass="input-group-btn"><buttonclass="btn"type="submit"formtarget="{{ _action.target }}"><iclass="fa fa-search"></i><spanclass="hidden-xs hidden-sm">{{ _action.label|default('action.search')|trans(_trans_parameters) }}</span></button></span></div>{% endblock %}
Personalizando searchAction()
Después del paso anterior, ya tenemos el formulario renderizado en nuestra vista delist, pero necesitamos incluir la funcionalidad de busca. Cuando pulsas el botónde búsqueda, EasyAdmin lleva a un action quese llama searchAction donde se maneja la búsqueda full-text. En nuestro caso, vamos a modificar lalógica para recibir los filtros de nuestro formulario. Para ello, tras recibir los filtros seleccionados, se lo enviamos a un servicio quese encargue de devolvernos los elementos filtrados.
protected function searchAction()
{
$this->dispatch(EasyAdminEvents::PRE_SEARCH);
$filters = new AdminFilters();
$form = $this->createForm(EventAdminFiltersType::class, $filters);
$form->handleRequest($this->request);
$data = $form->getData();
$events = $this->advanceSearch->search($data);
$paginator = new Pagerfanta(new ArrayAdapter($events));
$paginator->setMaxPerPage($this->entity['list']['max_results']);
$fields = $this->entity['list']['fields'];
$this->dispatch(EasyAdminEvents::POST_SEARCH, array(
'fields' => $fields,
'paginator' => $paginator,
));
$parameters = array(
'paginator' => $paginator,
'fields' => $fields,
'delete_form_template' => $this->createDeleteForm($this->entity['name'], '__id__')->createView(),
'search_form' => $form->createView()
);
return $this->executeDynamicMethod('render<EntityName>Template', array('search', $this->entity['templates']['list'], $parameters));
}
Espero que te haya resultado útil este ejemplo de como personalizar EasyAdmin. La mayoría de bundles proponen y plantean un diseño de su pieza software con la posibilidad de extender la funcionalidad y adaptarla a tus necesidades.