Los fixtures son extensiones de archivos que se requieren para llenar con datos de prueba una tabla con la arquitectura de datos que se da por las entidades de symfony… Regularme y en otros frameworks se genera SQL con el fin de rellenar los datos, pero no es tan fácil compartirlos con otros desarrolladores y no queda registro entero sobre el código del sistema.

Instalación del bundle DoctrineFixturesBundle

Los pasos de instalación se tomaron de internet. En primer lugar actualizamos el fichero de dependencias deps con las referencias a los repositorios donde se encuentra el código que vamos a añadir al proyecto. Añade a este fichero las siguientes líneas:

...

[doctrine-fixtures]
     git=http://github.com/doctrine/data-fixtures.git

[DoctrineFixturesBundle]
     git=http://github.com/symfony/DoctrineFixturesBundle.git
     target=/bundles/Symfony/Bundle/DoctrineFixturesBundle

¿Qué líneas referencian a dicho núcleo?

Ahora vamos a bajar el código cuyas referencias acabamos de añadir. Esto se hace con la herramienta bin/vendors:

Si hubieramos partido de una distribución estándard de Symfony2 sin vendors utilizariamos la herramienta de la siguiente forma:

./bin/vendors update

Pero como nuestra distribución ya venía con los vendors instalados, debemos volver a instalarlos para que se sincronicen con los respectivos repositorios remotos:

./bin/vendors install --reinstall


Esta operación borra las librerías del directorio vendors, y vuelve a colocarlas descargándolas de los repositorios y sincronizándolas con ellos.

Una vez finalizada la operación puedes comprobar que la librería doctrine-fixtures ha sido instalada en el directorio vendor/doctrine-fixtures, y el bundleDoctrineFixturesBundle se ha instalado en el directorio vendor/bundles/Doctrine/Bundle/FixturesBundle.

Ahora tenemos que registrar manualmente el bundleDoctrineFixturesBundle en el fichero AppKernel.php:

<?php

public function registerBundles()
{
    $bundles = array(
        // ...
        new Symfony\Bundle\DoctrineFixturesBundle\DoctrineFixturesBundle(),
        // ...
    );
    // ...
}

Y registrar el espacio de nombres de las clases del bundle en el fichero autoload.php:

<?php
...
$loader->registerNamespaces(array(
    // ...
    'Doctrine\\Common\\DataFixtures' => __DIR__.'/../vendor/doctrine-fixtures/lib',
    'Doctrine\\Common' => __DIR__.'/../vendor/doctrine-common/lib',
    // ...
));

Asegurate de que registras estos nombres de espacio antes de 'Doctrine\\Common.

Y ya podemos añadir nuestros fixtures.

Creación de los fixtures

Los fixtures son clases PHP que definen los datos de prueba que deseamos incorporar automáticamente a la base de datos. Deben ubicarse en el directorio Fixtures/ORM de algún bundle.

Comenzamos por añadir algunos usuarios de prueba. Creamos la clase LoadGrupoData en el fichero.

 

Debido a que no se tienen las entidades conformadas, se decidió dejar esta clase de ejemplo. La idea es realizar las preguntas y mejorar este archivo en cuanto se tenga un modelo consolidado.

src/Jazzyweb/AulasMentor/NotasFrontendBundle/Fixtures/ORM/LoadGrupoData.php.

<?php

 namespace Jazzyweb\AulasMentor\NotasFrontendBundle\Fixtures\ORM;

 use Doctrine\Common\Persistence\ObjectManager;
 use Doctrine\Common\DataFixtures\AbstractFixture;
 use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
 use Jazzyweb\AulasMentor\NotasFrontendBundle\Entity\Grupo;

 class LoadGrupoData extends AbstractFixture implements OrderedFixtureInterface
 {
     public function load(ObjectManager $manager)
     {
         // Preguntas
         $pregunta1 = new Pregunta();
         $pregunta1->setPregunta('¿Qué es blanco?');
         $pregunta1->setRespuesta1('Perro');
         $pregunta1->setRespuesta2('Huevo');
         $pregunta1->setRespuesta3('Gallina');
         $pregunta1->setRespuesta4('Pelota de Golf');
         $this->addReference('seleccion-multiple-multiple-respuesta', $pregunta1);
         $manager->persist($pregunta1);


         $pregunta2 = new Pregunta();
         $pregunta2->setPregunta('¿Qué es blanco y gallina lo pone?');
         $pregunta2->setRespuesta1('Perro');
         $pregunta2->setRespuesta2('Huevo');
         $pregunta2->setRespuesta3('Gallina');
         $pregunta2->setRespuesta4('Pelota de Golf');
         $this->addReference('seleccion-multiple-unica-respuesta', $pregunta2);
         $manager->persist($pregunta2);


         $pregunta3 = new Pregunta();
         $pregunta3->setPregunta('¿Los perros van al cielo?');
         $pregunta3->setRespuesta1('Falso');
         $pregunta3->setRespuesta2('Verdadero');
         $this->addReference('falso-verdadero', $pregunta3);
         $manager->persist($pregunta3);


         $pregunta4 = new Pregunta();
         $pregunta4->setPregunta('Empareje los estereotipos');
         $pregunta4->setRespuesta11('Metacho');
         $pregunta4->setRespuesta12('Mechudo');
         $pregunta4->setRespuesta21('Tolimense');
         $pregunta4->setRespuesta22('Flojo');
         $pregunta4->setRespuesta31('Boyacense');
         $pregunta4->setRespuesta32('Gay');
         $pregunta4->setRespuesta4('Miembro GLUD');
         $pregunta4->setRespuesta4('El puto AMO');
         $this->addReference('matching', $pregunta4);
         $manager->persist($pregunta4);


         $pregunta5 = new Pregunta();
         $pregunta5->setPregunta('¿Cuánto da 5 por 8?');
         $pregunta5->setRespuesta1('40');
         $this->addReference('numerica', $pregunta5);
         $manager->persist($pregunta5);

         $pregunta6 = new Pregunta();
         $pregunta6->setPregunta('¿Cuál es el mejor editor para symfony?');
         $pregunta6->setRespuesta1('atom');
         $this->addReference('texto', $pregunta6);
         $manager->persist($pregunta6);

         $manager->flush();
     }

     public function getOrder()
     {
         return 1;
     }
 }

Los fixtures son clases que extienden de Doctrine\Common\DataFixtures\AbstractFixture e implementan la interfaz Doctrine\Common\DataFixtures\OrderedFixtureInterface. Deben implementar una función load(), donde se crean los objetos que se desean persisitir en la base de datos. La manera de hacer esto es como ya hemos estudiado en la unidad 7: se crea el objeto, se definen sus atributos y se inyecta en el servicio de persistencia mediante el método persist(). Finalmente, para hacer la escritura en la base de datos se usa el método flush().

La novedad en el código anterior es el uso del método addReference() de la clase LoadGrupoData. Dicho método crea una referencia al objeto indicado en su segundo argumento con el nombre indicado en el primer argumento. Esta referencia podrá ser utilizada en otras clases fixtures para realizar asociaciones entre objetos. Por ejemplo, podemos crear una clase LoadUsuarioData y en ella podemos crear y persistir objetos Usuario‘s asociados a los grupos que hemos creados en LoadGrupoData a través de sus referencias.

Por último, cuando existen asociaciones entre objetos, el orden de creación de los mismos puede ser importante. Por ejemplo, para añadir una Nota a un Usuario, hay que crear primero la Nota, después el Usuario y por último podemos añadir la Nota al Usuario. Por ello la ejecución de las clases fixtures no siempre puede llevarse a cabo en cualquier orden. El método getOrder() de las mismas, indica al framework en qué orden debe ejecutarlas.

Una vez que tenemos alguna clase fixture ya podemos ejecutar el comando que cargará la base de datos con los datos especificados en ellas:

php app/console doctrine:fixtures:load --fixtures=src/Jazzyweb/AulasMentor/NotasFrontendBundle/Fixtures

Comprueba que se hayan cargado los grupos en la base de datos.

 

Esperamos que haya sido de ayuda, y recuerden, los procesos han de ser iterativos e incrementales.

Grupo GNU/Linux UD