Blog de Gonzalo

TUTORIAL EASYADMIN DE SYMFONY

Actualmente estoy usando el bundle easyadmin de symfony y la verdad es que es bastante sencillo, ya que con un fichero de configuración, en formato yaml, es suficiente. Aunque se pueden hacer administradores más complejos y progrmando en php y symfony. Y aunque hay bastante documentación, y ejemplos, en internet creo que con este tutorial easyadmin de symfony intentaré cubrir bastantes necesidades cuando se quiere hacer un admin algo más complejo. Por ejemplo usar varios controladores de symfony cuando el admin va a ser muy amplio y se quiere dividir la programaci?on popr entidades, por ejemplo. Yo lo estoy usando con symfony 5.
Una vez instalado el bundle voy a explicar las diferentes partes por separado:
Primero nos dispondremos a abrir el fichero routes.yaml y añadiremos lo siguiente:


easy_admin_bundle:
  resource: '@EasyAdminBundle/Controller/EasyAdminController.php'
  prefix: /admin
  type: annotation

Una vez hecho esto iremos a la carpeta controllers y crearemos un controller que se llame AdminController.php que tendrá el siguiente código:


namespace App\Controller;

use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Controller\EasyAdminController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class AdminController extends EasyAdminController
{
    protected $entityManager;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    /**
     * @Route("/", name="easyadmin")
     */
    public function indexAction(Request $request)
    {
        return parent::indexAction($request);
    }
}

Después de todo ésto. Se pueden usar funciones dentro de este contolador y easyadmin la buscarfá aquí. Pero si se van a usar varios controladores para el admin, como se explica en lo siguiente. Los controladores tendrán que extender de este controlador.
Luego abriremos el fichero easy_admin.yaml que se encuentra en config/packages. Donde se añadirá toda la configuración y es la parte más importante del easyadmin

easy_admin:
    site_name: 'My Admin'
    design:
        menu: [{ entity: 'Provider', label: 'Data Providers' },
               { entity: 'Product', label: 'Credit Cards' }]
    formats:
        date: 'd/m/Y'
    entities:
        Provider:
            class: App\Entity\Provider
            controller: App\Controller\Admin\AdminProviderController
            label: Data Providers
            list:
                sort: ['id', 'DESC']
                disabled_actions: ['delete']
                actions:                                                               
                    - { name: 'editProvider', type: 'route', label: 'Edit' }  
                fields:
                    - { property: 'name', label: 'Name' }
                    - { property: 'affiliation', label: 'Type' }
            form:
                fields:
                    - { property: 'name',type_options: { required: true } }
                    - { property: 'affiliation', label: 'Type', type: 'choice',type_options:{choices: { 'Affiliate': 'affiliate', 'Direct': 'direct' }}}
                    - { property: 'ws_url', type: 'text',type_options: { required: true } }
                    - { property: 'ws_url_stats', type: 'text',type_options: { required: true } }
                    - { property: 'data_type', type: 'text',type_options: { required: true } }
                    - { property: 'api_user', type: 'text'}
                    - { property: 'api_key', type: 'text',type_options: { required: true } }
                    - { property: 'slug', type: 'text'}
        Product:
            class: App\Entity\Product
            controller: App\Controller\Admin\AdminProductController
            label: Credit Cards
            disabled_actions: ['delete']
            form:
                fields:
                    - { property: 'name'}
                    - { property: 'provider', label: 'Data provider'}
                    - { property: 'link', label: 'Deep link', type: 'text',type_options: { required: true } }
                    - { property: 'final_url', type: 'text',type_options: { required: true } }
                    - { property: 'provider_reference', type: 'hidden',type_options: { data: '0' } }
                    - { property: 'visible', type: 'hidden',type_options: { data: '0' } }
            list:
                actions:
                    - { name: 'edit', label: '' }
                fields:
                    - { property: 'name', label: 'Name' }
                    - { property: 'Provider.name', label: 'Data provider' }
                    - { property: 'visible', label: 'Visible in Web', type: 'toggle' }


Explicación del código anterior:
  • design: Como el propio nombre indica es la sección de diseño. Está definido el menú lateral que entidades se van a usar en el admin y el nombre que se va a mostrar en el menú
  • entities: Por cada entity definida en el apartado anterior se puede configurar que campos apareceran en el listado principal, el formulario de creación y edición, se pueden definir juntos o por separado y el controller que se va a usar.
    • class: Ruta a la entity, pero la ruta por namespace no ruta física. Este campo es obligatorio
    • controller: Ruta al controlador, pero la ruta por namespace no ruta física. Este campo es opcional. Se suele usar por si se quiere hacer un override de alguna función como el listado, creación o edición. En el caso de provider no hace falta pero para product sí.
    • list: Se definen los que campos se van a mostrar en el listado. Los campos son los atributos de la entity. En el ejmplo anterior tenemos dos entities Provider y Product si os mostrase las dos entities veríais que tiene esos mismos atributos que son los campos de la tabla de la base de datos.
    • form: Se definen los que campos se van a añadir en el formulario de creación edición, aunque se puede definir por separado. Los campos son los atributos de la entity. En el código anterior tenemos dos entities Provider y Product si os mostrase las dos entities veríais que tiene esos mismos atributos que son los campos de la tabla de la base de datos. Si queremos definir un campo de tipo file en la sección de form se le puede indicar el nombre del archivo y la ruta. En este caso la ruta está definida en una variable de entorno, sino se especifica la ruta los archivos se subirán a public/uploads/files/ y el nombre del archivo está formado por timestamp y un randhomhash y guardando la imagen con su propia extensión:
      - { property: 'logo', type: 'file_upload', type_options: { upload_dir: '%env(PATH_UPLOAD_IMAGES_TMP)%', upload_filename: '[timestamp][randomhash].[extension]'}}
    • actions: Se refiere a las acciones que se pueden hacer por cada dato en el listado. Las disponibles son edit y delete
    • disabled actions: Se refiere a las acciones desabilitadas. Las disponibles son new, edit y delete. Como se puede ver en la entidad Product: se ha deshabilitado la acci?on delete, por ponerlo de ejemplo en list, en la subsección de action aparece que edit tiene la opción de edit con una cadena vacía y en la subsección de fields aparece que el campo visible tiene el tipo toggle ya que desde el listado se muestra un togle para poder marcar el producto como visible o no en la web y si se deshabilita la opción edit no funcionaría. Por eso está hecho así.

Como se puede ver en código anterior, cuando se definen los controladores del admin, la ruta del namespace indica que están dentro de la carpeta admin para tenerlos separados de los controladores del front. Lo más importante del fichero easy_admin.yaml está explicado de forma sencilla con lo descrito anteriormente pero ¿qué pasa si necesitamos que la acción editar haga algo más que editar? Pues podemos ver que en la parte de Provider se ha deshabilitado acción de editary luego se ha definido una sección de actión donde se le ha puesto una ruta y que el texto que se va a mostrar es 'Edit'. También se ha definido un controlador en la sección de controller eso quiere decir cuando se haga click en el enlace Edit de un proveedor y con las rutas de symfony irá al controlador buscando esa función para esa ruta.
Cuando necesitaemos que la acción de listado o creación tenga una funcionalidad específica se hace de forma diferente. Lo que hay que hacer es crear una función, en el controlador definido en la sección controller y llamarla de las siguientes formas:
  • Para el listado sería protected function listEntityAction(). Por ejemplo para la sección provider sería: protected function listProviderAction()
  • Para la creación sería protected function newEntityAction()(). Por ejemplo para la sección producto sería: protected function newProductAction()()

Si quieres puedes aprender como proteger el admin con contraseña.

Compartir en twitter