Chargement...

Doctrine les entités - ORM symfony


Les entités

Tout d'abord indiquez à Symfony la base utilisée dans le fichier app/config/parameters.yml

# This file is auto-generated during the composer install
parameters:
    database_driver: pdo_mysql
    database_host: 127.0.0.1
    database_port: null
    database_name: mabase
    database_user: root
    database_password: monmotdepasse
    mailer_transport: smtp
    mailer_host: 127.0.0.1
    mailer_user: null
    mailer_password: null
    locale: fr
    secret: ThisTokenIsNotSoSecretChangeIt

Si la base indiquée n'existe pas encore, vous pouvez la créer depuis Symfony:

php app/console doctrine:database:create

Voir les mise à jour à effectuer au niveau SQL

php app/console doctrine:schema:update --dump-sql

Cette commande est très intéressante, elle compare ce qui existe sur la base actuelle et renvoit les requetes SQL à executer pour avoir une cohérence entre le code et la base. Il s'agit juste d'une consultation aucune requête ne sera executée.

Il est possible que vous rencontriez l'erreur suivante:

  [Doctrine\DBAL\DBALException]                                                                    
  Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it. 

Pour fixer ce problème ajoutez le mapping_types enum suivant dans le fichier de config comme dans l'exemple suivant:

doctrine:
    dbal:
        driver: %database_driver%
         host: %database_host%
         port: %database_port%
         dbname: %database_name%
         user: %database_user%
         password: %database_password%
         charset: UTF8
         mapping_types:
             enum: string

Si après avoir fait le dump sql tout vous semble bon, vousp pouvez executer les requetes SQL nécessaire à la mise à jour avec cette commande:

app/console doctrine:schema:update --force

Créer une entité

Ce qui est magique avec Symfony c'est que l'on vous assiste pour presque tout. Nous avoons vu précédemment comment créer un bundle en ligne de commande il est possible de créer une entité dans la même logique avec la commande suivante:

php app/console generate:doctrine:entity

Une série de question vous sera posée:


The entity name must contain a : ("ENGELAwesomeBundleCustomer" given, expecting something like AcmeBlogBundle:Blog/Post) 
The Entity shortcut name: ENGELAwesomeBundle:Customer

Determine the format to use for the mapping information.

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): code
Field type [string]: 
Field length [255]: 

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

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

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

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

                             
Summary before generation
You are going to generate a "ENGELAwesomeBundle:Customer" Doctrine2 entity using the "annotation" format. Do you confirm generation [yes]? yes
Entity generation
Generating the entity code: OK
You can now start using the generated code!

Créer une entrée

Nous allons maintenant créer une entrée Customer , pour cela intégrez le code suivant dans une méthode de votre Controller:

use ENGEL\AwesomeBundle\Entity\Customer;
$customer = new Customer();
$customer->setFirstname('Olivier');
$customer->setLastname('ENGEL');
$customer->setCode('00001');

$em = $this->getDoctrine()->getManager();
$em->persist($customer);
$em->flush();

Il est possible que l'enregistrement soit refusé parce que vous n'avez pas indiqué à l'ORM que vous accepter des valeurs nulles pour certains champs. Pour cela modifier les annotation de votre entité comme ceci:

    /**
     * @var string
     *
     * @ORM\Column(name="code", type="string", length=255, nullable=true)
     */
    private $code;

Modifier une entrée

Vous pouvez modifier les valeurs d'une entité:

$customer = $this->getDoctrine()->getRepository('ENGELAwesomeBundle:Customer')->find($request['id_customer']);
$customer->setName('Olivier ENGEL');
$customer->save();

ManyToOne

Le ManyToOne permet de lier un item à un autre via une clé étrangère. Exemple, dans un ticket qui est composé de lignes, ce sont ces ligne (TicketItem) qui nécessiteront un ManyToMany

Dans l'entité TicketItem, il faut créer à la main:

   /**
     * @ORM\ManyToOne(targetEntity="ENGEL\AwesomeBundle\Entity\Ticket")
     * @ORM\JoinColumn(nullable=false)
     */
    private $Ticket;

Symfony créera la clé étrangère après avoir exécuter la commande suivante:

php app/console doctrine:schema:update --force

Une classe très "Utils"

Vous pouvez créer vos propres fonctions pour accéder plus facilement aux données:

class Utils
{

    // Retourne le résultat d'un select d'une query
    public static function select($that, $query, $binds = array())
    {
        $em = $that->getDoctrine()->getManager();
        $connection = $em->getConnection();
        $statement = $connection->prepare($query);
        foreach( $binds as $key => $value ):
            $statement->bindValue($key, $value);
        endforeach;
        $statement->execute();
        return $statement->fetchAll();
    }

    // Protège une donnée
    public static function quote($that, $string)
    {
        $em = $that->getDoctrine()->getManager();
        $connection = $em->getConnection();
        return $connection->quote($string, \PDO::PARAM_STR);
    }
}

Nous pouvons maintenant utiliser ces fonctions dans nos controleurs:

$term = "ENGEL";
$query = "
    SELECT 
        id, concat(firstname, ' ', lastname, ' ', code ) as text
    FROM 
        Customer as a 
    WHERE 
        firstname like :term OR
        lastname  like :term  
";
$binds = array( 'term' => $term ); 
$r = Utils::select($this, $query, $binds);

Et si vous avez besoin de sécuriser une données avec quote:

$term_secure = Utils::quote( $this, '%'.$_term.'%' );

Evidemment ce n'est qu'un exemple, pour ce type de besoin on utilisera plutôt un service Symfony




UNE QUESTION SUR L'ARTICLE?


CSSW Apprendre à créer son site web CSSW