Symfony2: Como manejarse con una fecha que tenga el valor null

Punto de partida: Trabajo con Symfony 2.8 y he diseñado la base de datos y las tablas que la componen con el software MySQL Workbench. Luego, hice exportar el esquema y crear la base de datos.
En Symfony 2.8, procedí a importar la base de datos ya creada y a generar las entidades.

Manejo de una fecha con valor null en un formulario diseñado con Twig

Mi problema: Tengo una tabla llamada Contratos (ver estructura en la imagen siguiente) con un campo fecha del tipo DateTime llamado fechaArchivo que puede ser nulo (valor=null).

Mi problema era que al utilizar las plantillas new.html.twig o edit.html.twig, Tiwg me exigía completar el valor del campo y no permitía dejarlo en blanco ni colocar una fecha igual a:»0000-00-00″. La solución está en utilizar la condición ‘required’ => false

contratos
Estructura de la tabla Contratos

Aquí la solución detallada con todos los archivos involucrados:

En el archivo donde se define la entidad Contratos, llamado Contratos.php tenemos:

 /**
     * @var \DateTime
     *
     * @ORM\Column(name='fecha_archivo', type='date', nullable=true)
     */
    private $fechaArchivo;

      /**
     * Set fechaArchivo
     *
     * @param \DateTime $fechaArchivo
     * @return Contratos
     */
    public function setFechaArchivo( \DateTime $fechaArchivo=null)
    {

       $this->fechaArchivo = $fechaArchivo;

        return $this;
    }

    /**
     * Get fechaArchivo
     *
     * @return \DateTime
     */
    public function getFechaArchivo()
    {
        return $this->fechaArchivo;
    }

En mi caso, como procedí a importar una base de datos ya existente, Symfony y Doctrine, crearon también un archivo llamado: Contratos.orm.xml que se muestra completo a continuación:

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  <entity name="BackendBundle\Entity\Contratos" table="contratos"  repository-class="BackendBundle\Entity\ContratosRepository">
    <indexes>
      <index name="fk_Contratos_Docentes1_idx" columns="docentes_id"/>
      <index name="fk_Contratos_Materias1_idx" columns="materias_id"/>
    </indexes>
    <id name="id" type="integer" column="id">
      <generator strategy="AUTO"/>
    </id>
    <field name="fechaInicio" type="date" column="fecha_inicio" nullable="false"/>
    <field name="fechaFinal" type="date" column="fecha_final" nullable="false"/>
    <field name="fechaFirma" type="date" column="fecha_firma" nullable="false"/>
     <field name="fechaArchivo" type="date" column="fecha_archivo" nullable="true"/>
    <field name="marcaImprimir" type="boolean" column="marca_imprimir" nullable="true"/>
    <field name="monto" type="decimal" column="monto" precision="10" scale="2" nullable="false"/>
    <field name="montoAdicional" type="decimal" column="monto_adicional" precision="10" scale="2" nullable="true"/>
    <many-to-one field="materias" target-entity="Materias">
      <join-columns>
        <join-column name="materias_id" referenced-column-name="id"/>
      </join-columns>
    </many-to-one>
    <many-to-one field="docentes" target-entity="Docentes">
      <join-columns>
        <join-column name="docentes_id" referenced-column-name="id"/>
      </join-columns>
    </many-to-one>
  </entity>
</doctrine-mapping>

Obsérvese con atención la línea 14 del código anterior, donde se fija el atributo nullable=»true» para el campo fechaArchivo

En el archivo donde se definen los atributos de los formularios, tengo:

 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
             ->add('fechaInicio', 'date', array( 'attr' => array('style' => 'width: 80px'), 'widget' => 'single_text', 'format' => 'dd/MM/yyyy'))
            ->add('fechaFinal', 'date' ,  array( 'attr' => array('style' => 'width: 80px'), 'widget' => 'single_text', 'format' => 'dd/MM/yyyy'))
            ->add('fechaFirma', 'date',  array( 'attr' => array('style' => 'width: 80px'), 'widget' => 'single_text', 'format' => 'dd/MM/yyyy' ))
            ->add('fechaArchivo', 'date',  array('required' => false, 'attr' => array('style' => 'width: 80px'), 'widget' => 'single_text', 'format' => 'dd/MM/yyyy' ))
            ->add('materias')
            ->add('marcaImprimir')
            ->add('monto', 'money', array('currency'=>'ARS' ))
            ->add('montoAdicional', 'money', array('required' => false, 'currency'=>'ARS' ))
            ->add('docentes')
        ;
    }

Obsérvese que tengo cuatro campos fecha, donde tres son obligatorios y el campo fechaArchivo, puede ser null, entonces defino para ese campo la cualidad ‘required’ => false quedando la línea de código completa de la siguiente manera:

 ->add('fechaArchivo', 'date',  array('required' => false, 'attr' => array('style' => 'width: 80px'), 'widget' => 'single_text', 'format' => 'dd/MM/yyyy' ))

¡Y eso es todo! Tanto cuando creo un registro nuevo, como cuando edito uno ya existente, no necesito asignar ningún valor al campo fechaArchivo si no es necesario. Si observamos la tabla con phpMyAdmin, vemos que todos los registros que no tienen una fecha cargada en el campo fechaArchivo, poseen un valor igual a null que yo definí como valor por defecto.

Manejo de una fecha con valor null en una consulta con el uso de Doctrine y Symfony2

Mi problema: ¿Como utilizar una fecha con valor null en una consulta en Symfony2 con Doctrine?
Imaginemos que necesito conocer todos los registros de una tabla que tengan un valor null en un campo fecha. ¿Como es la sintaxis de la consulta?

Solución:En el código de abajo se puede ver la sintaxis correcta para que funcione una consulta, cuando queremos conocer los registros del campo fechaArchivo, que tengan un valor NULL.

public function findNull()
    {
        $em = $this->getEntityManager();

        $consulta = $em->createQuery('
            SELECT c, d, m
            FROM BackendBundle:Contratos c
            JOIN c.docentes d
            JOIN c.materias m
            WHERE c.fechaArchivo IS NULL

            ORDER BY d.apellido, d.nombres
        ');

        return $consulta->getArrayResult();
    }

¿Como mostrar una fecha con valor NULL en un listado de una plantilla de Twig?

Mi problema: Siguiendo con el ejemplo del campo fechaArchivo, si quiero mostrar en un plantilla de Twig el valor de este campo fecha, debo utilizar la siguiente sintaxis para evitar un mensaje de error:

 {% for contrato in contratos %}
                {% if contrato.fechaArchivo %}{{ contrato.fechaArchivo|date('d-m-Y') }}{% endif %}
        {% endfor %}

Esta sintaxis es la correcta para cualquier campo fecha, sea que pueda tener un valor NULL o no. Si el valor fuese NULL, simplemente Twig no mostrará ningún valor en el listado correspondiente.

Instalar Symfony 2.8 con Xampp y NetBeans 8.1 en Windows 7

Esta entrada fue escrita en su versión original, hace mucho tiempo. Hoy Symfony anda por su versión 5. Igualmente, Symfony 2.8 sigue siendo una versión muy buena  potente y eficiente que puede y conviene usarse con PHP 7.1 o superior. Además, para los lectores de habla hispana, tenemos disponible un excelente libro para conocer casi todo sobre este framework en su versión 2.8, mientras que no hay casi nada escrito sobre como aprender a programar con las versiones más nuevas Me refiero al libro de Javier Eguiluz, que se menciona más abajo. Hoy, 18 de julio de 2020, he actualizado algunos detalles, pero lo esencial sigue vigente. (Desde hace poco, en 2020, salió el libro de Fabien Potencier: «Symfony 5: La vía rápida», que tiene una versión en castellano y puede comprarse por 30 euros en formato PDF).

Configurar el servidor Apache Xampp

Antes que nada debemos tener instalado y corriendo algún servidor Apache.

En mi caso utilizo Xampp.  Puede descargar Xampp desde varios lugares en la Web. Asegúrese de que sea una versión que contenga al menos PHP 5.5, en mi caso utilizo la versión de Xampp 5.6.24 (no funciona en Windows XP). Atención: solo instalo Apache y MySQL.

Iniciamos Xampp y si todo está correcto, veremos que se abre una ventana como la siguiente, donde puede verse que los servicios Apache y MySQL (los que elegí instalar) están funcionando adecuadamente ya que sus nombres se encuentran en fondo verde.

xampp1

Para que Xampp funcione de la manera adecuada para nuestro proyecto, debemos cambiar la configuración de Apache, haciendo clic en el botón Config  del módulo de Apache y abriendo el archivo httpd.conf
xampp2

Vamos al final del archivo y agregamos las siguientes líneas:

Listen 127.0.0.1:8080

<VirtualHost 127.0.0.1:8080>
           ServerName localhost
           DocumentRoot «D:\Datos\proyectos\cursospieromaster2017\html«
               <Directory «D:\Datos\proyectos\cursospieromaster2017\html«>
                   AllowOverride All
                     Allow from All
                    Require all granted
            </Directory>

</VirtualHost>

En el código de arriba podemos ver que debemos decirle a Xampp donde está ubicado nuestro directorio de trabajo: También definimos la IP del localhost con el puerto «8080» (en mi caso para distinguirlo de otros proyectos con los que uso diferente puertos).

Además de este cambio en el archivo httpd.conf debemos cambiar el puerto en la configuración general de Xampp, para ello:
  • Abrimos el Panel de Control de Xampp
  • Hacemos clic en Config (ver en la figura siguiente, el botón que está en el extremo superior derecho del Panel, encerrado en una elipse en color rojo).
  • Hacemos clic en Service and Port Settings
  • Aparece una nueva ventana que se llama Service Settings
  • Para nuestro propósito, solo elegimos la solapa Apache y reemplazamos el valor por defecto de 80 a 8080
  • Gravamos los cambios, haciendo click en Save
  • Y de nuevo  Save para actualizar la Configuración general de Xampp
  • Detenemos y volvemos a arrancar Apache en el panel principal, para que corra con los nuevos cambios.
configuracion general de Xampp

Recuerda que tendremos que introducir el dominio en nuestro fichero hosts del sistema operativo:

C:\Windows\System32\drivers\etc\hosts

127.0.0.1:8080       localhost

Luego probamos que todo está funcionando bien, cargando la página en nuestro localhost:

xampp4

Descargando e instalando Symfony 2.8

Aclaración: La explicación que sigue supone que Usted quiere desarrollar un proyecto nuevo. No que está tratando de importar un proyecto ya existente y en desarrollo.

Hay varios sitios en la web donde se explica como instalar Symfony 2. Incluso el sitio oficial de Symfony, también lo detalla. Sin embargo la tarea se puede complicar si además queremos usar como interface de programación a la IDE (integrated development environment) NetBeans para desarrollar nuestro proyecto. Es que desde la versión 2.6 Symfony no ofrece más el paquete en formato comprimido. Si Usted como yo, prefiere trabajar con  NetBeans, hay un par tareas extras, muy sencillas, para lograrlo.

Siguiendo los pasos que se detallan en este link:
https://symfony.com/doc/2.8/setup.html instalamos Symfony 2.8 en nuestra PC con Windows 7. Vemos que el sitio oficial de Symfony, ofrece varias alternativas. En mi caso prefiero usar Composer.

Una vez descargada en instalada la versión de Symfony 2.8, y  alojada en una carpeta que podemos denominar «c:\mi_proyecto», el paso siguiente es recurrir a algún de los software de compresión como Winzip o WinRar para comprimir esta carpeta con todas sus subcarpetas. Con ayuda del explorador de Windows, nos posicionamos en la carpeta «C:\mi_proyecto» y veremos algo similar a lo siguiente:

paso3

En el explorador de Windows, hacemos clic con el botón derecho del mouse (en mi caso uso Winzip) elijo: «Añadir a mi_proyecto.zip», y queda generado el archivo: «mi_proyecto.zip» en el directorio raíz C:\.

Instalando Symfony 2.8 en NetBeans 8.1

Ahora ingresamos a NetBeans (yo utilizo la versión 8.1) y seleccionamos en el menú principal: «Archivo, Import Proyect.., From Zip…», seleccionamos el archivo comprimido, «mi_proyecto.zip», y le decimos a NetBeans, donde queremos alojar nuestro proyecto. En mi caso, en la carpeta: «C:\proyectos». Hacemos clic en el botón «Import».

paso9

NetBeans, se encargará de importar y configurar el proyecto en la carpeta de destino elegida. Una vez terminada la importación, elegimos: «Archivo, Close All Proyects…», y luego, «Archivo, Open Proyect…» y seleccionamos de la lista nuestro proyecto recién importado (ver imagen siguiente)
paso7

Luego, elegimos en NetBeans: «Archivo|Project properties..» y en «Sources» nos aseguramos que las dos carpetas: «Sources folder» y «Project folder» sean iguales. En mi caso: «C:\proyectos\mi_proyecto»

Recordemos decirle a NetBeans, donde buscar el archivo de PHP. Para ello, en el menú principal, elegimos, «Herramientas, Opciones,» luego la solapa «PHP», y escribimos la ruta.  En mi caso, como utilizo Xampp, el archivo se aloja en «C:\xampp\php\php.exe», y luego hacemos clic en el botón «Aceptar», como muestra la imagen siguiente:

paso8

Así el proyecto quedará instalado, configurado (en modo automático) y listo para ser manejado desde NetBeans.

Ahora solo queda empezar a programar con Symfony. Un libro estupendo para aprender Symfony 2.8, se titula «Desarrollo web ágil con Symfony2» y está escrito por Javier Eguiluz, una de las personas que más sabe de Symfony en el mundo (puedes leer una reseña del libro aquí). En este libro se desarrolla un ejemplo muy completo y realista de una tienda on-line totalmente programada con Symfony2.