Doctrine2-Tips : Différence entre versions

De DiouxX's Wiki
Aller à : navigation, rechercher
(Many To Many)
(Base de donnée)
 
(Une révision intermédiaire par le même utilisateur non affichée)
Ligne 149 : Ligne 149 :
  
 
== Base de donnée ==
 
== Base de donnée ==
 +
 +
===Configurer la base de donnée===
 +
La base de donnée se configure dans le fichier {{ File | app/config/parameters.yml }}
 +
<br>
 +
<syntaxhighlight lang=yaml>
 +
parameters:
 +
    database_host: 127.0.0.1
 +
    database_port: null
 +
    database_name: symfonydb
 +
    database_user: symfony_user
 +
    database_password: symfony
 +
    mailer_transport: smtp
 +
    mailer_host: 127.0.0.1
 +
    mailer_user: null
 +
    mailer_password: null
 +
</syntaxhighlight>
  
 
===Créer la base de donnée ===
 
===Créer la base de donnée ===
Ligne 290 : Ligne 306 :
 
</syntaxhighlight>
 
</syntaxhighlight>
 
<br>
 
<br>
J'ai mis Advert comme propriétaire de la relation. C'est un choix que vous pouvez faire comme bon vous semble ici. Mais récupérer les catégories d'une annonce se fera assez souvent, alors que récupérer les annonces d'une catégorie moins. Et puis, pour récupérer les annonces d'une catégorie, on aura surement besoin de personnaliser la requête, donc on le fera de toute façon depuis le CategoryRepository, on en reparlera.
+
J'ai mis Advert comme propriétaire de la relation. C'est un choix que vous pouvez faire comme bon vous semble ici. Mais récupérer les catégories d'une annonce se fera assez souvent, alors que récupérer les annonces d'une catégorie moins. Et puis, pour récupérer les annonces d'une catégorie, on aura sûrement besoin de personnaliser la requête, donc on le fera de toute façon depuis le CategoryRepository, on en reparlera.
 +
<br>
 +
 
 +
== Fixtures ==
 +
 
 +
=== Installation ===
 +
 
 +
* Pour installer le bundle fixtures, on passe via la commande composer :
 +
<br>
 +
{{ Console | composer require --dev doctrine/doctrine-fixtures-bundle }}
 +
<br>
 +
 
 +
* On ajoute la ligne dans le fichier {{ File | app/AppKernel.php}} pour activer le bundle
 +
<syntaxhighlight lang=php>
 +
// app/AppKernel.php
 +
// ...
 +
 
 +
class AppKernel extends Kernel
 +
{
 +
    public function registerBundles()
 +
    {
 +
        // ...
 +
        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
 +
            $bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle();
 +
        }
 +
 
 +
        return $bundles
 +
    }
 +
 
 +
    // ...
 +
}
 +
</syntaxhighlight>
 +
<br>
 +
=== Utilisation ===
 +
Tout d'abord, créons notre fichier de fixture pour l'entité Category. Les fixtures d'un bundle se trouvent dans le répertoire DataFixtures/ORM (ou ODM pour des documents). Voici à quoi ressemble notre fixture LoadCategory
 +
 
 +
<syntaxhighlight lang=php>
 +
<?php
 +
// src/OC/PlatformBundle/DataFixtures/ORM/LoadCategory.php
 +
 
 +
namespace OC\PlatformBundle\DataFixtures\ORM;
 +
 
 +
use Doctrine\Common\DataFixtures\FixtureInterface;
 +
use Doctrine\Common\Persistence\ObjectManager;
 +
use OC\PlatformBundle\Entity\Category;
 +
 
 +
class LoadCategory implements FixtureInterface
 +
{
 +
  // Dans l'argument de la méthode load, l'objet $manager est l'EntityManager
 +
  public function load(ObjectManager $manager)
 +
  {
 +
    // Liste des noms de catégorie à ajouter
 +
    $names = array(
 +
      'Développement web',
 +
      'Développement mobile',
 +
      'Graphisme',
 +
      'Intégration',
 +
      'Réseau'
 +
    );
 +
 
 +
    foreach ($names as $name) {
 +
      // On crée la catégorie
 +
      $category = new Category();
 +
      $category->setName($name);
 +
 
 +
      // On la persiste
 +
      $manager->persist($category);
 +
    }
 +
 
 +
    // On déclenche l'enregistrement de toutes les catégories
 +
    $manager->flush();
 +
  }
 +
}
 +
</syntaxhighlight>
 +
 
 +
On éxécute la commande suivante :
 +
<pre>
 +
php app/console doctrine:fixtures:load
 +
Careful, database will be purged. Do you want to continue y/N ?y
 +
  > purging database
 +
  > loading OC\PlatformBundle\DataFixtures\ORM\LoadCategory
 +
</pre>
 +
<br>
 +
{{ Note | Attention, comme vous avez pu le voir, l'exécution de la commande Doctrine pour insérer les fixtures vide totalement la base de données avant d'insérer les nouvelles données. Si vous voulez ajouter les fixtures en plus des données déjà présentes, il faut ajouter l'option --append à la commande précédente. Cependant, c'est rarement ce que vous voulez, car à la prochaine exécution des fixtures, vous allez insérer une nouvelle fois les mêmes catégories… }}
 +
<br>
  
 
[[Catégorie:Doctrine2]]
 
[[Catégorie:Doctrine2]]

Version actuelle datée du 16 décembre 2015 à 09:53

Aide-mémoire sur l'utilisation de Donctrine2 dans Symfony2

Entité

Générer une entitée


Konsole.png
[user@ordi ~]$ php app/console generate:doctrine:entity


      Welcome to the Doctrine2 entity generator



    This command helps you generate Doctrine2 entities.

    First, you need to give the entity name you want to generate.
    You must use the shortcut notation like AcmeBlogBundle:Post.

    The Entity shortcut name:_

Grâce à ce que le générateur vous dit, vous l'avez compris, il faut entrer le nom de l'entité sous le format NomBundle:NomEntité. Dans notre cas, on entre donc OCPlatformBundle:Advert.

    The Entity shortcut name: OCPlatformBundle:Advert

    Determine the format to use for the mapping information.

    Configuration format (yml, xml, php, or annotation) [annotation]:_

Comme je vous l'ai dit, nous allons utiliser les annotations, qui sont d'ailleurs le format par défaut. Appuyez juste sur la touche Entrée.

    Configuration format (yml, xml, php, or annotation) [annotation]:

    Instead of starting with a blank entity, you can add some fields now.
    Note that the primary key will be added automatically (named id).

    Available types: array, simple_array, json_array, object,
    boolean, integer, smallint, bigint, string, text, datetime, datetimetz,
    date, time, decimal, float, blob, guid.

    New field name (press <return> to stop adding fields):_

On commence à saisir le nom de nos champs. Lisez bien ce qui est inscrit avant : Doctrine2 va ajouter automatiquement l'id, de ce fait, pas besoin de le redéfinir ici. On entre donc notre date : date.

    New field name (press <return> to stop adding fields): date
    Field type [string]:_

C'est maintenant que l'on va dire à Doctrine à quel type correspond notre propriété date. La liste des types possibles vous est donné par Symfony juste au dessus. Nous voulons une date avec les informations de temps, tapez donc datetime.

Répétez les points 3 et 4 pour les propriétés title, author et content. title et author sont de type string de 255 caractères (pourquoi pas). Content est par contre de type text.

    New field name (press <return> to stop adding fields): date
    Field type [string]: datetime

    New field name (press <return> to stop adding fields): title
    Field type [string]: string
    Field length [255]: 255

    New field name (press <return> to stop adding fields): author
    Field type [string]: string
    Field length [255]: 255

    New field name (press <return> to stop adding fields): content
    Field type [string]: text

    New field name (press <return> to stop adding fields):_

Lorsque vous avez fini, appuyez sur la touche Entrée.

    New field name (press <return> to stop adding fields):

    Do you want to generate an empty repository class [no]?_

Oui, on va créer le repository associé, c'est très pratique, nous en reparlerons largement. Entrez donc yes.

Confirmez la génération, et voilà !

    Do you want to generate an empty repository class [no]? yes


      Summary before generation


    You are going to generate a "OCPlatformBundle:Advert" Doctrine2 entity
    using the "annotation" format.

    Do you confirm generation [yes]?


      Entity generation


    Generating the entity code: OK


      You can now start using the generated code!



    C:\wamp\www\Symfony>_

Allez tout de suite voir le résultat dans le fichier Entity/Advert.php. Symfony2 a tout généré, même les getters et les setters ! Vous êtes l'heureux propriétaire d'une simple classe… avec plein d'annotations !

Mettre à jour une entité


Konsole.png
[user@ordi ~]$ php app/console doctrine:generate:entities OCPlatformBundle:Advert


Enregistrer en BDD

  • Création de l'entité
$advert = new Advert();


  • Récupération de l'EntityManager
$em = $this->getDoctrine()->getManager();


  • On dit à Doctrine de « persister » l'entité. Cela veut dire qu'à partir de maintenant cette entité (qui n'est qu'un simple objet !) est gérée par Doctrine. Cela n'exécute pas encore de requête SQL, ni rien d'autre.
$em->persist($advert);


  • On dit à Doctrine d'exécuter effectivement les requêtes nécessaires pour sauvegarder les entités qu'on lui a dit de persister précédemment.
$em->flush();


  • Notre Advert étant maintenant enregistré en base de données grâce au flush(), Doctrine2 lui a attribué un id ! On peut donc utiliser $advert->getId() dans la génération de la route, et non un nombre fixe comme précédemment.


Base de donnée

Configurer la base de donnée

La base de donnée se configure dans le fichier app/config/parameters.yml

parameters:
    database_host: 127.0.0.1
    database_port: null
    database_name: symfonydb
    database_user: symfony_user
    database_password: symfony
    mailer_transport: smtp
    mailer_host: 127.0.0.1
    mailer_user: null
    mailer_password: null

Créer la base de donnée


Konsole.png
[user@ordi ~]$ php app/console doctrine:database:create


Création de la requête


Konsole.png
[user@ordi ~]$ php app/console doctrine:schema:update --dump-sql


Générer les tables


Konsole.png
[user@ordi ~]$ php app/console doctrine:schema:update --force


Mise à jour


Konsole.png
[user@ordi ~]$ php app/console doctrine:schema:update


Relations

One To One


Doctrinne2-onetoone.png


<?php
// src/OC/PlatformBundle/Entity/Advert.php

/**
 * @ORM\Entity
 */
class Advert
{
  /**
   * @ORM\OneToOne(targetEntity="OC\PlatformBundle\Entity\Image", cascade={"persist"})
   */
  private $image;

  // …
}


<?php
// src/OC/PlatformBundle/Entity/Image

/**
 * @ORM\Entity
 */
class Image
{
  // Nul besoin d'ajouter une propriété ici

  // …
}

Many To One


Doctrine2-manytoone.png


<?php
// src/OC/PlatformBundle/Entity/Application.php

/**
 * @ORM\Entity
 */
class Application
{
  /**
   * @ORM\ManyToOne(targetEntity="OC\PlatformBundle\Entity\Advert")
   * @ORM\JoinColumn(nullable=false)
   */
  private $advert;

  // …
}


<?php
// src/OC/PlatformBundle/Entity/Advert.php

/**
 * @ORM\Entity
 */
class Advert
{
  // Nul besoin de rajouter de propriété, ici

  // …
}

Many To Many


Doctrine2-manytomany.png


<?php
// src/OC/PlatformBundle/Entity/Advert.php

/**
 * @ORM\Entity
 */
class Advert
{
  /**
   * @ORM\ManyToMany(targetEntity="OC\PlatformBundle\Entity\Category", cascade={"persist"})
   */
  private $categories;

  // …
}


<?php
// src/OC/PlatformBundle/Entity/Category.php

/**
 * @ORM\Entity
 */
class Category
{
  // Nul besoin d'ajouter une propriété ici

  // …
}


J'ai mis Advert comme propriétaire de la relation. C'est un choix que vous pouvez faire comme bon vous semble ici. Mais récupérer les catégories d'une annonce se fera assez souvent, alors que récupérer les annonces d'une catégorie moins. Et puis, pour récupérer les annonces d'une catégorie, on aura sûrement besoin de personnaliser la requête, donc on le fera de toute façon depuis le CategoryRepository, on en reparlera.

Fixtures

Installation

  • Pour installer le bundle fixtures, on passe via la commande composer :


Konsole.png
[user@ordi ~]$ composer require --dev doctrine/doctrine-fixtures-bundle


  • On ajoute la ligne dans le fichier app/AppKernel.php pour activer le bundle
// app/AppKernel.php
// ...

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        // ...
        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
            $bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle();
        }

        return $bundles
    }

    // ...
}


Utilisation

Tout d'abord, créons notre fichier de fixture pour l'entité Category. Les fixtures d'un bundle se trouvent dans le répertoire DataFixtures/ORM (ou ODM pour des documents). Voici à quoi ressemble notre fixture LoadCategory

<?php
// src/OC/PlatformBundle/DataFixtures/ORM/LoadCategory.php

namespace OC\PlatformBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use OC\PlatformBundle\Entity\Category;

class LoadCategory implements FixtureInterface
{
  // Dans l'argument de la méthode load, l'objet $manager est l'EntityManager
  public function load(ObjectManager $manager)
  {
    // Liste des noms de catégorie à ajouter
    $names = array(
      'Développement web',
      'Développement mobile',
      'Graphisme',
      'Intégration',
      'Réseau'
    );

    foreach ($names as $name) {
      // On crée la catégorie
      $category = new Category();
      $category->setName($name);

      // On la persiste
      $manager->persist($category);
    }

    // On déclenche l'enregistrement de toutes les catégories
    $manager->flush();
  }
}

On éxécute la commande suivante :

php app/console doctrine:fixtures:load
Careful, database will be purged. Do you want to continue y/N ?y
  > purging database
  > loading OC\PlatformBundle\DataFixtures\ORM\LoadCategory


BlocNotes.png
À noter !
Attention, comme vous avez pu le voir, l'exécution de la commande Doctrine pour insérer les fixtures vide totalement la base de données avant d'insérer les nouvelles données. Si vous voulez ajouter les fixtures en plus des données déjà présentes, il faut ajouter l'option --append à la commande précédente. Cependant, c'est rarement ce que vous voulez, car à la prochaine exécution des fixtures, vous allez insérer une nouvelle fois les mêmes catégories…