symfony

Generar urls usando routes.yml y annotations

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

    Uno de los aspectos fundamentales dentro de cualquier proyecto web, está formado por la manera en que podremos generar o manipular las diferentes urls, que permiten entre otras cosas, el acceso a todas las secciones de la web, indexación del contenido en los buscadores o interactuar con los resultados de nuestra base de datos y/o formularios, mediante el envio de parámetros.

     Ya que hemos aprendido a utilizar el paquete (Bundle) Make, para generar un controlador, con su respectiva página, en el artículo anterior Symfony, Arquitectura y primeros pasos; hoy vamos a explorar las diferentes opciones disponibles en Symfony para generar estas urls.

     En Symfony 5 contamos con dos maneras para crear nuestras propias urls, mediante el uso del archivo routes.yml, que nos viene por defecto, al descargar el esqueleto del proyecto, y que está ubicado a nivel de nuestra carpeta raiz, dentro de la carpeta config, o mediante el paquete (Bundle) Annotation, que tendríamos que descargar utilzando el gestor de paquetes Composer, pero que ya nos viene descargado y listo si optamos por utilizar Lando como hemos echo en este caso.

   Cómo generar urls usando el archivo routes.yml

     El archivo routes.yml tiene como contenido, un modelo base, para que podamos copiar y modificar sus líneas, adaptádolas a nuestras necesidades. Si abrimos el archivos routes.yml, veremos una estructura como la siguiente:

#index:
#    path: /
#    controller: App\Controller\DefaultController::index

     Para que este archivo comience a funcionar, bastaría con descomentar todas sus líneas borrando las almohadillas (#) y asegurándonos de que existiera el controlador llamado DefaultController, con su respectivo método, función o acción, como le llaman en Symfony, con el nombre index.

     Explicación de la estructura

     #index: Se refiere al nombre interno que utiliza Symfony, para identificar esta url. Dicho nombre puede ser aleatorio, por lo que su contenido en realidad no impediría acceder a la respectiva página, siempe que rellenemos correctamente las líneas siguientes.

     # path: /: Esta sí que tiene un impacto directo, ya que es donde se define la ruta, a la cual podremos acceder desde el navegador, si queremos encontrar la página dentro de nuestro proyecto. En esta caso en particular, la barra hace referencia a la página principal de nuestro proyecto de Symfony, que sería la página por defecto que vimos al terminar la instalación y arrancar nuestro proyecto.

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

     # controller: App\Controller\DefaultController::index: En esta última línea es donde especificamos la ruta, para acceder hasta el controlador que conecta con nuestra página y a su vez, al método o acción dentro de él. Es muy importante poner atencion en la nomenclatura respectanto las mayúsculas en cada caso y los dos puntos, que permitirán ejecutar el método o acción relacionado.

   Ejercicio de comprobación

     Queremos asegurarnos de que hemos comprendido el funcionamiento del archivo routes.yml, por esta razón, vamos a realizar una prueba en la cual utilizaremos el MainController.php para convertir la página que generamos en el anterior capítulo, en la nueva página principal de nuestro proyecto.

     Para ello, abriremos nuestro controlador y comentaremos las líneas siguientes:

/*
/**
 * @Route("/main", name="app_main")
 */

     Estas líneas son las encargadas de generar la url para nuestro MainController, gracias al paquete (Bundle) Annotation, que explicaremos en breve, por ahora, lo único que necesitaremos es añadir la barra con el asterisco ( /* ) al principio de las líneas, para convertirlo en un comentario de php en lugar de una anotación.

     A continuación, abriremos el archivo routes.yml, borraremos todas las almohadillas y luego actualizaremos el nombre del controlador a MainController, en lugar de DefaultController, para que podamos utilizar nuestro controlador como ruta hacia nuestra página. El archivo routes.yml debería quedar de la siguiente manera:

index:
    path: /
    controller: App\Controller\MainController::index

     Una vez realizados los cambios, nos aseguraremos de guardarlos y si refrescamos el navegador, deberíamos ver que ahora la página principal de nuestro proyecto es la que habíamos generado.

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

  Cómo generar urls usando annotations

     Ahora que ya hemos comprobado cómo podemos configurar las urls, utilizando el archivo routes.yml, vamos a conocer la manera recomendada por Symfony, ya que permite mantener unidas en un mismo espacio, las principales configuraciones del controlador, junto a la gestión de sus url, gracias a su bundle Annotations o anotaciones.

     A primera vista, podemos darnos cuenta de que el aspecto de las anotaciones nos recuerda a los comentarios en php, pero en realidad es una estructura innovadora que nos permitirá incluir varias informaciones y/o parámetros sin la necesidad de buscar en otro lugar fuera del controlador, facilintando la investigacion y comprobación de errores.

     Antes de continuar, nos aseguraremos de restaurar el archivo routes.yml a su aspecto anterior, con las almohadillas y luego quitaremos el asterisco y la barra que habíamos añadido a nuestro MainController.php, quedando de la siguiente manera:

class MainController extends AbstractController
{
    /**
     * @Route("/main", name="app_main")
     */

     Si prestamos atención, y comparamos con el contenido de archivo routes.yml, encontraremos varias similitudes, que nos permitirán entender mejor el uso de anotaciones.

     En lo primero que deberíamos fijarnos al trabajar con las anotaciones es que sus líneas comienzan con una barra y dos asteriscos ( /** ) a diferencia de los comentarios de php y que terminan igual que estos, con un solo asterisco y una barra ( */ ). El resto de líneas que aparezca dentro de este principio y final de la estructura, será lo que conoceremos como anotaciones.

     En este ejemplo en concreto, para definir nuestra ruta, Symfony utiliza la siguiente declaración @Route( ) y dentro de los paréntesis, se añaden algunos elementos, dependiendo del propósito de dicha ruta.

     La primera parte, donde vemos las comillas dobles y el nombre main "/main", estamos definiendo el equivalente al path:, en el anterior archivo routes.yml, es decir, la url que pondremos en el navegador, para acceder a nuestra página.

     A continuación, en el apartado de name="app_main", como habrás imaginado, es el nombre de nuestra ruta, es decir, el equivalente a la primera línea dentro del archivo routes.yml, ese nombre interno que utiliza Symfony para identificar a la ruta, pero que no repercute directamente en que nuestra página se muester cuando escribimos su url en el navegador.

   Ejercicio de comprobación

     Como estamos comenzando con Symfony y para aprender a utilizarla correctamente, es recomendable que comprobemos cada nueva fase, para asegurarnos de que entendemos lo que estamos leyendo, vamos a realizar una rápida comprobarción, sobre el impacto que tendría en nuestra controlador, si modificamos el nombre en la declaración de la ruta.

/**
 * @Route("/main", name="otronombre")
 */

     Una vez hayamos realizado y guardado el cambio, accederemos nuevamente a la url correspondiente a nuestro controlador, que como puedes comprobar en este caso será /main y podrás ver en tu pantalla, que la página sigue mostrándose sin ningún cambio, a pesar de que has cambiado su nombre (NO SU RUTA).

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Felicidades!!! ya puedes presumir de que haz aprendido y entiendes cómo funciona la generación de urls en Symfony. Ahora, ¿te atreves a experimentar creando una nueva página, utilizando las anotaciones sin la necesidad de salir del archivo MainController.php?

Arquitectura y primeros pasos

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

     Ahora que ya hemos arrancado Symfony en nuestro entorno local, porque vemos la página de inicio que nos da la bienvenida, existen algunos detalles que debes conocer, antes de comenzar a trabajar en tu proyecto, evitando así la pérdida del tiempo en averiguar la procedencia de los errores que te vayas encontrando.

   Qué es Symfony y cómo funciona

     Symfony es uno de los proyectos PHP más exitosos. Es a la vez un framework sólido de pila completa y un conjunto popular de componentes reutilizables.

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

     En otras palabras, Symfony es un Framework o estructura de archivos, cuyo propósito fundamental, es ofrecer una forma de ordenar nuestro código, para agilizar las tareas de desarrollo. Con este fin, propone distribuir el proyecto en tres partes fundamentales, ModeloVista y Controlador o MVC.

     Modelo: está formado por las partes del código encargadas de gestionar las definciones, implementación e interacción de las bases de datos en el proyecto.

     Vista: está compuesta por todo lo relacionado con la apariencia o presentación de nuestos contenidos.

     Controlador: se encarga de las conexiones entre las partes incluidas en el Modelo y las Vistas.

 

   Dependencias o Plugins para Symfony

     A partir de la versión Symfony 4, podremos descargar, instalar y actualizar diferentes librerías o "Paquetes", que nos servirán para ampliar o modificar diversas funcionalidades, dentro de nuestros proyectos.

     Estos paquetes están alojados en un repositorio global, llamado Flex. Al principio, podíamos acceder al servidor desde la url flex.symfony.com, pero actualmente ha sido modificado y ahora está alojado directamente en Github. Desde su página oficial, podemos ver la siguiente aclaración si visitamos esta url.

     "Si tienes un proyecto que usa Symfony 4+ full-stack framework, es muy probable que esté usando Symfony Flex. Symfony Flex configura automáticamente los paquetes cuando los instala o actualiza a través de recetas oficiales  o aportadas. La forma en que servimos las recetas está cambiando y debes actualizar el paquete symfony/flex para aprovechar este cambio".

     Para saber más acerca del sistema de repositorio de Symfony Flex Haz clic aquí

 

   Ejecutando código dentro de Symfony

     Existen varias formas de comenzar un proyecto con Symfony, podremos descargar un esqueleto o estructura sin las principales funcionalidades activadas, en el cual tendremos que ir añadiendo todos los paquetes que nos ayudarán, por ejemplo, con la generación de controladores, rutas y entidades; o si lo preferimos, podríamos descargar algunas de estas funcionalidades, ahorrándonos tiempo en el comienzo de nuestro desarrollo.

     Por defecto, si quisiéramos poner en funcionamiento alguno de los paqutes de Symfony, deberíamos escribir en nuestra pantalla algo como la siguiente línea:

php bin/console make:controller

     Lando nos ofrece la oportunidad de descargar ese esqueleto, incluyedo las principales funcionalidades de Symfony; por ejemplo el paquete Make, que nos permitierá generar controladores, entidades, contenidos, etc., entre otras opciones.

     Para saber las posibilidades disponibles, así como los paquetes que nos ha descargado lando, escribiremos en cosola el siguiente comando:

lando console

Esto nos mostrará en pantalla, todos los paquetes, comando y funcionalidades disponibles en cada momento.

 

Una vez descargardos los "Paquetes", podremos ejecutarlos o llamarlos, desde la consola agregando el código. (lando + console + PAQUETE: OPCIÓN). Ej.:

lando console make:controller

     Al ejecutar el código anterior, estamos pidiéndole a Symfony, que nos genere la estructura que compone un controlador, que será el encargado de gestionar nuestra primera página, con su respectiva plantilla y de esta manera, tendremos un punto de partida, antes de continuar con el resto de tareas.

     Una vez ejecudado el código para generar nuestro controlador, se nos presentarán un conjunto de preguntas que iremos contestando, para que se añadan características o funcionalidades específicas, relacionadas con dicho controlador.

     Cuando hayamos terminado por completo el proceso de generación del controlador, podremos explorar su contenido y acceder a la url generada con éste.

 

   Explorando nuestro primer controlador (Controller)

     Si abrimos el archivo generado, que está dentro de la carpeta MIPROYECTO/src/controller, econtraremos la nueva clase generada con el nombre que hemos descrito en el paso anterior: MainController

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony
<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class MainController extends AbstractController
{
    /**
     * @Route("/main", name="app_main")
     */
    public function index(): Response
    {
        return $this->render('main/index.html.twig', [
            'controller_name' => 'MainController',
        ]);
    }
}

Explicación

     En la primera parte encontramos el namespace, que será la ubicación donde están alojados los archivos relacionados con nuestro controlador.

namespace App\Controller;

     Si continuamos un poco hacia abajo, veremos tres líneas que comienzan con la palabra "use", esto le indica a Symonfy, otras clases o recursos que vamos a necesitar, para lograr que todo funcione correctamente. 

     Es muy importante, prestar atención en esta ubicación, ya que de lo contrario, no obtendremos el resultado esperado.

     En este caso, necesitaremos tres clases :

  • clase AbstractContoller, para heredar las funcionalidades necesarias para que nuestro controlador funcione.
  • clase Response, para obtener la respuesta que esperamos al poner en marcha este controlador, que en nuestro caso, mostará en pantalla una página con el contenido por defecto que nos da Symfony, a través de una plantilla llamada index.html.twig, ubicada en la carpeta templates/main, de la cual hablaremos más adelante.
  • clase Route, que nos permitirirá mediante la url "/main", acceder a través del navegador y ver el resultado esperado.

   Accediendo a nuestra primera página

     Como he mencionado anteriormente, por defecto, las urls de Symonfy se contruyen a través del archivo index.php, por lo que si quisiéramos ver nuesta primera página, deberíamos escribir simplemente, en nuestro caso, algo como lo siguiente:

http://symfony5-app.lndo.site/index.php/main

     Pero para nuestra sorpresa, lo que vemos en pantalla es un error, como este:

 

     Para corregirlo, simplemente tendremos que ejecutar el suguiente código, para borrar la causa de este error:

lando composer rem symfony/webpack-encore-bundle

     Si ahora refrescamos nuestro navegador, veremos nuestra página funcionando correctamente:

 

   Cómo evitar que aparezca index.php en nuestra url

      Aunque nuestra página se vea correctamente, lo ideal sería no tener que añadir dentro de su url, la parte que se refiere al index.php, por lo que a continuación, tendremos que añadir un archivo .htaccess para corregir esto.

     Abriremos la carpeta ubicada en la raiz de nuestro proyecto y crearemos un nuevo archivo .htaccess, a continuación pegaremos el siguiente código:

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Determine the RewriteBase automatically and set it as environment variable.
    RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
    RewriteRule ^(.*) - [E=BASE:%1]

    # If the requested filename exists, simply serve it.
    # We only want to let Apache serve files and not directories.
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule .? - [L]

    # Rewrite all other queries to the front controller.
    RewriteRule .? %{ENV:BASE}/index.php [L]
</IfModule>

Symfony 5 | Introducción

Symfony es uno de los Framework (Estructura) de desarrollo basado en PHP, ideal para crear todo tipo de proyectos, manteniendo una organización del código reduciendo el tiempo de todas las tareas relacionadas con la puesta en marcha o el mantenimiento de las aplicaciones.

En este curso, exploraremos cada uno de los pasos necesarios, para que puedas comenzar a utilizarlo y sacarle el máximo provecho, beneficiándote en todo momento de sus ventajas. 

Symfony, An exception has been thrown during the rendering of a template

An exception has been thrown during the rendering of a template
("Could not find the entrypoints file from Webpack: the file "./public/build/entrypoints.json" does not exist.")

Durante la instalación de un proyecto de Symfony, es posible que nos encontremos con este error cuando intentamos acceder a la plantilla correspondiente al Controller que generamos por defecto con el comando make:controller, para solucionar el fallo tendrás que eliminar el archivo ENCORE ubicado dentro de config/packages. Pero no manualmente, sino ejecutando el comando que está más abajo.

Testeado en la versión Symfony 5.4.6

Symfony Postgree | Datatype mismatch: 7 ERROR:  column "xxx" cannot be cast automatically to type boolean

Cuando trabajas con Symfony y Postgree, es posible que al intentar cambiar el tipo de valor para una tabla o para una columna, te encuentres con este error, que no te permitirá realizar la actualización al ejecutar el comando doctrine:migrations:migrate.

SQLSTATE[42804]: Datatype mismatch: 7 ERROR:  column "xxx" cannot be cast automatically to type boolean   HINT:  You might need to specify "USING xxx::boolean".

PHPStan and Doctrine: $id is never written, only read

Cuando trabajamos con PhpStand en Symfony, es posible que nos encontremos con una alerta que nos advierte sobre propiedades o campos como el $id, que nunca se han utilizado o leído, pero en realidad, en este caso, el $id, sólo se crea para la interacción entre Symfony y Doctrine, por lo que no hace falta Leerlo ni Usarlo más allá.

Así que para evitar esta alerta, que nos saltará siempre que ejecutemos la revisión con PhpStand, sigue los siguientes pasos:

Argument #1 ($validateTo) must be of type DateTimeInterface, string given

En Symfony, al trabajar con propiedades o campos del tipo fecha en nuestra entidades, es posible que nos encontremos con este error:

App\Entity\Entidad::setValidateTo(): 
Argument #1 ($validateTo) must be of type DateTimeInterface, string given, 
called in /app/src/Command/UpdateEntidadInfo.php on line 50 

     Esto significa que aunque en nuestra entidad hemos declarado correctamente el tipo de propiedad, al intentar leerla desde otro lugar, sea controlador o comando de consola, tendremos que volver a añadir su tipo.