Como en toda aplicación compleja, en Symfony es posible crear y usar funciones personalizadas. La cuestión clave, además de escribirlas bien, es ubicarlas en las carpetas apropiadas y llamarlas del modo correcto. Distinguiremos dos casos:
- Funciones a utilizar en un controlador.
- Funciones a utilizar en una plantilla TWIG.
Veamos estos casos a través de ejemplos.
Funciones a utilizar en un controlador
Desarrollaré este punto a partir de un ejemplo concreto. Tengo una «acción» en un controlador con el siguiente código:
$mi_numero= number_format($contrat['id'], 0, ',', '.'); $mi_fecha_firma=ConverterHelper::obtenermiFecha($contrat['fechaFirma']); $mi_fecha_inicio=ConverterHelper::obtenermiFecha($contrat['fechaInicio']); $mi_fecha_final=ConverterHelper::obtenermiFecha($contrat['fechaFinal']); $mi_nombres=$contrat['docentes']['nombres']; //funciona $mi_apellido=$contrat['docentes']['apellido']; //funciona $mi_dni=$contrat['docentes']['dni']; //funciona $mi_cuit=$contrat['docentes']['cuit']; $mi_direccion=$contrat['docentes']['direccion']; $mi_direccion= str_replace('Piso: Depto: Barrio:', 'Barrio:', $mi_direccion); //depuracion 1 $mi_direccion= str_replace('Depto: Barrio:', 'Barrio:', $mi_direccion); //depuracion 2 $mi_materia=$contrat['materias']['descripcion']; //funciona $mi_carrera = $contrat['materias']['carreras']['descripcion']; $mi_institucion = $contrat['materias']['carreras']['institucion']['nombre']; $mi_monto= number_format($contrat['monto'], 2, ',', '.'); $mi_monto_letras= ConverterHelper::numtoletras($contrat['monto']); $mi_monto_adicional= number_format($contrat['montoAdicional'], 2, ',', '.'); $mi_monto_adicional_letras= ConverterHelper::numtoletras($contrat['montoAdicional']); $mi_garantia = $contrat['garantiaMinAlumnos']; $mi_marca_imprimir= ($contrat['marcaImprimir']) ? 'Sí' : 'No' ;
En las líneas de código de arriba, tenemos varios ejemplos de llamado a funciones. Algunas como $mi_monto= number_format($contrat[‘monto’], 2, ‘,’, ‘.’); llaman a una función predefinida de PHP. Como muestra el ejemplo, necesito que un número $contrat[‘monto’], sea formateado con dos decimales, y el separador decimal sea la coma y el separador de miles el punto.
Luego tengo un ejemplo del llamado a una función personalizada: $mi_monto_letras= ConverterHelper::numtoletras($contrat[‘monto’]); Se trata del mismo monto anterior, que quiero expresar en letras, ya que la información que estoy procesando, será utilizada en un contrato comercial. A través de la expresión, llamo a una función que hace esta tarea, a la que le envío un número, y me devuelve el mismo número pero en letras. Es decir, si el número enviado a la función «numtoletras» es «1510» el texto devuelto por la función será: «un mil quinientos diez».
Observese la sintaxis: estoy llamando a una clase ConverterHelper y dentro de la clase, a una función llamada numtoletras a la que le paso el argumento $contrat[‘monto’]. Lo expresamos como ConverterHelper::numtoletras($contrat[‘monto’])
Para que esta función pueda operar hay que tomar varios recaudos. Paso a explicar:
Primero que nada, debemos definir en el archivo de controlador donde vayamos a usar la o las funciones, la ruta donde Symfony podrá encontrar esas funciones.En la imagen siguiente, tenemos las primeras líneas de código del archivo ContratosController.php
Podemos observar en el recuadro rojo de arriba, que hay dos funciones declaradas con su ruta, que son las que se utilizan en distintas partes del archivo de controlador, ContratosController.php
Yo he creado una carpeta especial para las funciones personalizadas a utilizar en los diferentes controladores, que he llamado Helper y está dentro de la carpeta Controller del bundle, BackendBundle, como se muestra en la imagen siguiente:
Vemos que dentro la carpeta Helper hay tres archivos PHP. Cada archivo puede conterner más de una función, pero por claridad conviene crear un archivo para cada función. En cada archivo PHP procedo a crear una clase y dentro de esa clase, pongo las funciones a utilizar. En el ejemplo que venimos desarrollando, tengo la clase ConverterHelper y dentro de la clase la función numtoletras
Podemos ver las primeras líneas de código del archivo ConverterHelper.php en la imagen siguiente:
Funciones a utilizar en una plantilla TWIG
Con las funciones personalizadas a utilizar dentro de archivos Twig, la filosofía es similar a las funciones utilizadas en los controladores: mantener separadas las funciones, respecto de las plantillas de Twig donde son llamadas. Solo cambia en algo la sintaxis. Recordemos que en los archivos Twig, no podemos incorporar en forma directa código PHP, de modo que si necesitamos usar código PHP, debemos llamar a una función externa a la plantilla, para ejecutar ese código.
Primero que nada, debemos decirle a Symfony donde estarán las funciones de Twig. Esto lo hacemos en el archivos services.yml que se encuentra en la carpeta app\config donde definimos los parámetros que se muestran en la figura siguiente:
Veamos el uso de las funciones, desarrollando dos ejemplos muy sencillos.
Empecemos por el primero. He creado una función en Twig para formatear los títulos de una manera determinada y siempre igual para todas las plantillas. El llamado a la función, que la he denominado poner_h1, se muestra en la imagen siguiente donde tengo una plantilla Twig:
A esta función, le paso el contenido del título, en este caso «Nuevo Docente». La función se ejecuta en un archivo denominado AppExtension.php que está ubicado en la carpeta AppBundle\Twig\AppExtension tal como lo definimos en el archivo services.yml
A continuación el contenido del archivo con las dos funciones de ejemplo que mostraré.
namespace AppBundle\Twig; class AppExtension extends \Twig_Extension { public function getFunctions() { return array( new \Twig_SimpleFunction('poner_h1', array($this, 'ponerh1')), new \Twig_SimpleFunction('obtener_fecha', array($this, 'obtenerFecha')), ); } public function ponerh1($mititulo) { $mititulo_formateado=' <table width="100%"> <tbody> <tr> <td align="center"> <h1>'.$mititulo.'</h1> </td> </tr> <tr></tr> </tbody> </table> '; return $mititulo_formateado; } public function obtenerFecha() { setlocale(LC_ALL, "es_ES"); $timestamp=time(); $format='l j F Y H:i'; $trans = array( 'Monday' => 'Lunes,', 'Tuesday' => 'Martes,', 'Wednesday' => 'Miércoles,', 'Thursday' => 'Jueves,', 'Friday' => 'Viernes,', 'Saturday' => 'Sábado,', 'Sunday' => 'Domingo,', 'January' => ' de Enero de ', 'February' => ' de Febrero de ', 'March' => ' de Marzo de ', 'April' => ' de Abril de ', 'May' => ' de Mayo de ', 'June' => ' de Junio de ', 'July' => ' de Julio de ', 'August' => ' de Agosto de ', 'September' => ' de Septiembre de ', 'October' => ' de Octubre de ', 'November' => ' de Noviembre de ', 'December' => ' de Diciembre de ', ); return strtr(date($format,$timestamp),$trans); } }
Observemos que dentro la clase AppExtension tenemo dos «zonas» bien diferenciadas. Por un lado la función public function getFunctions() donde tengo listado el conjunto de las funciones de Twig que voy a utilizar. En este primer ejemplo, vemos que la línea de código donde se declara esta función es:
new \Twig_SimpleFunction(‘poner_h1’, array($this, ‘ponerh1’)),
aquí queda definido un nuevo nombre interno, para ejecutar la función: ‘ponerh1’ Esta es la función propiamente dicha, que se localiza más abajo en este mismo archivo. Allí podemos ver que la función, toma el texto que le pasa la plantilla de Twig, y lo formatea tal como se ve en la función. Devolviendo el texto formateado a la plantilla de Twig. Como quiero que Twig ejecute este valor como código HTML, agrego el parámetro raw ala llamada desde Twig. Rcuérdese que la función completa tal como es llamada desde la plantilla de Twig era: {{ poner_h1 (‘Nuevo Docente’) | raw}}
El segundo ejemplo, es una función PHP que me permite poner una fecha detallada en una plantilla Twig, de manera que se muestre el nombre del día, el nombre del mes y el año, junto con la hora, todo eso en español, tal como se ve en la imagen de más abajo. Entonces debo convertir la función que hace esta tarea en PHP pero que muestra los nombres en inglés y pasar esos nombres al español. La función se llama obtener_fecha() y no lleva ningún parámetro, ya que la propia función, toma la fecha y hora actual del sistema y la formatea del modo que se muestra aquí:
El código que va en la plantilla Twig es:
<div align="center"> <h3>Fecha de impresión: {{ obtener_fecha() }}</h3> </div>
Y la función está en el archivo AppExtension.php
Y esto es todo. Creo como ejemplos básicos son claros y muestran como se usan y donde se escriben las distintas funciones personalizadas en Symfony 2.8.