En el capítulo 2 explicamos rápidamente el concepto de Bundle en Symfony:

“Conceptualmente se puede decir que son similares a los plugins que encontramos otras aplicaciones. La diferencia es que en Symfony todo es un bundle, incluída la aplicación que vamos a desarrollar en este tutorial”.

Este capítulo tiene como objetivo que aprendas a instalar, configurar e integrar un bundle de terceros en una aplicación Symfony. Como decía anteriormente, nuestra aplicación my_blog al competo también es un bundle y, además, podemos crear nuestros propios bundles para funcionalidades concretas, por ejemplo, SopinetUploadFilesBundle , con la posibilidad de desacoplarlo y reutilizar dicho código en todos nuestros proyectos.

Estructura de un bundle

Symfony es muy flexible, eso ya lo sabemos. Así que es de suponer que hay varias formas de organizar los directorios y ficheros de un bundle pero, por convención y buenas prácticas, ésta debería ser la estructura a seguir:

  • Controller/: contiene los controladores.
  • DependencyInjection/: elementos relacionados con el contenedor de inyección de dependencias.
  • Resources/config/: configuración del bundle, incluyendo el routing .
  • Resources/views/: contiene las vistas.
  • Resources/public/: contiene recursos del bundle tales como imágenes, CSS, javaScript.
  • Tests/: contiene los test unitarios y funcionales del bundle.

El CLI de Symfony tiene un comando destinado a la creación de un nuevo bundle , que automáticamente genera el árbol de directorios y ficheros que acabamos de ver:

php app/console generate:bundle --namespace=A/TestBundle

Antes de seguir, Composer

En el capítulo 1 creamos nuestro proyecto Symfony utilizando Symfony installer . Este instalador es muy útil porque ahorra tiempo en la creación de un nuevo proyecto, pero para poder gestionar las versiones de nuestra aplicación, actulizarla e instalar librerías de terceros lo mejor es utilizar Composer , un moderno gestor de paquetes para aplicaciones PHP.

Instalando un bundle de terceros

Para nuestra aplicación de ejemplo vamos a utilizar EasyAdminBundle en su última versión estable 1.7.1. cuyo creador es Javier Eguiluz , creador del sitio web symfony.es , el mayor referente de la comunidad Symfony en España.

Antes de comenzar a instalar un bundle es importante comprobar sus distintas versiones, la compatibilidad con nuestra aplicación y librerías que estemos utilizando y, en base a esto, utilizar una versión estable siempre que se pueda. Esto se puede hacer revisando el archivo composer.json del propio bundle, en la sección require .

EasyAdminBundle es una magnífica solución para implementar un panel de administración que nos permita gestionar toda la información referente a nuestras entidades.

Los pasos a seguir más comunes a la hora de instalar y configurar un bundle de terceros son:

  • Descargar el bundle . (Recomendado hacerlo con Composer ).
  • Activarlo en /app/AppKernel.php
  • Configuración en /app/config/config.yml
  • Enrutamiento en /app/config/routing.yml

Para instalar y configurar EasyAdminBundle tan sólo hay que seguir los pasos indicados en la documentación del bundle .

A través de Composer, añadir el repositorio a nuestro proyecto.

$ composer require javiereguiluz/easyadmin-bundle

Activar el bundle en app/AppKernel.php

<?php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new JavierEguiluz\Bundle\EasyAdminBundle\EasyAdminBundle(),
        );
    }

    // ...
}

Cargar las rutas del bundle añadiendo la configuración en app/config/routing.yml

easy_admin_bundle:
   resource: "@EasyAdminBundle/Controller/"
   type:     annotation
   prefix:   /admin

Ejecutar el siguiente commando para crear los enlaces simbólicos de los archivos públicos en el directorio web/

php app/console assets:install --symlink

Ya está establecida la configuración básica del bundle para su uso. Si accedemos a la ruta cuyo prefijo es /admin veremos que se ha generado un panel de administración tremendamente útil para gestionar las operaciones básicas de nuestras entidades, lo que se conoce como CRUD: Create, Read, Update, Delete .

enter image description here

Como ves, el tiempo invertido en instalar y configurar este bundle no ha llevado más de 3 minutos, y aporta una funcionalidad que de haber tenido que implementar nosotros nos llevaría días de trabajo.

Sobrescribiendo un bundle

Al utilizar un bundle es muy probable que necesitemos sobrescribir algnuas de sus partes para adaptarlas a nuestro proyecto. Dada la arquitectura y estructura de directorios de Symfony este trabajo puede hacerse de forma sencilla.

Principalmente las funcionalidades que uno suele querer personalizar son las referentes a los controladores y las vistas. Para ello hay varias formas de hacerlo:

Registrar un bundle como “padre” del tuyo.

Básicamente se trata de extender del bundle que queremos sobrescribir. Supongamos que tenemos instalado un bundle cuyo nombre es SopinetUploadFilesBundle y queremos sobrescribirlo con nuestro propio bundle , llamado FilesManagerBundle . Esta sería la forma de hacerlo:

<?php

// src/FilesManagerBundle/FilesManagerBundle.php
namespace FilesManagerBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class FilesManagerBundle extends Bundle
{
    public function getParent()
    {
        return 'SopinetUploadFilesBundle';
    }
}

Con el método getParent() se devuelve el namespace del bundle que queremos sobrescribir. Ahora podemos sobrescribir varias partes del bundle simplemente creando archivos con el mismo nombre y manteniendo la estructura de directorios original.

Sobrescribir sólo un controlador

Si sólo queremos customizar un controlador concreto lo único que hay que hacer es importarlo en nuestro propio controlador y hacer que éste herede de él.


<?php

// src/UserBundle/Controller/RegistrationController.php
namespace UserBundle\Controller;

use FOS\UserBundle\Controller\RegistrationController as BaseController;

class RegistrationController extends BaseController
{
    public function registerAction()
    {
        $response = parent::registerAction();

        // ... do custom stuff
        return $response;
    }
}

Ejemplo obtenido del CookBook de Symfony

Sobrescribir controladores de esta forma sólo funciona si el bundle sigue el estándar de buenas prácticas para la organización del código. Ej: FOSUserBundle:Registration:register .

Sobrescribir Resources : vistas, enrutamiento, etc.

La mayoría de archivos localizados en este directorio pueden sobrescirbirse simplemente creando un archivo en la misma localización que el bundle “padre”.

Ej: para sobrescribir la vista layout.html.twig de FOSUserBundle , creamos una propia en app/Resources/FOSUserBundle/views/layout.html.twig . Esto es gracias a que Symfony interpreta antes lo que hay que en app/ que en el resto de directorios.

Algunos de los archivos de la carpeta Resources no se pueden sobrescribir de la misma forma, como los archivos de traducciones o validación de metadatos. Para obtener más información acerca de ello puedes consultar la documentación oficial .