Symfony2 - Jobeet - Jour 03 - Le Modèle de Données

1 1 1 1 1 1 1 1 1 1 Rating 3.33 (3 Votes)
Submit to DeliciousSubmit to DiggSubmit to FacebookSubmit to Google PlusSubmit to StumbleuponSubmit to TechnoratiSubmit to TwitterSubmit to LinkedIn

Si vous avez envie d'ouvrir votre éditeur de texte et de faire un peu de PHP, vous serez heureux de savoir qu'aujourd'hui nous allons faire quelques développements. Nous allons définir le modèle de données de Jobeet, utiliser un ORM pour interagir avec la base de données et construire le premier module de l'application. Mais comme Symfony fait beaucoup de travail pour nous, nous aurons un module web pleinement opérationnel sans trop écrire de code PHP.

Le modèle relationnel

Les stories du précédent chapitre décrivent les objets principaux de notre projet : les offres, les partenaires et les catégories. Voici le schéma des entités correspondant :

03-relational model

En plus des colonnes décrites dans les histoires, nous avons également ajouté les colonnes "created_at" et "updated_at". Nous allons configurer Symfony pour définir leur valeur automatiquement quand un objet est enregistré ou mis à jour.

La base de données

Pour stocker les emplois, les sociétés affiliées et les catégories dans la base de données, Symfony 2.5 utilise l'ORM Doctrine. Pour définir les paramètres de connexion de base de données, vous devez éditer le fichier "app/config/parameters.yml" (pour ce tutoriel, nous allons utiliser MySQL) :

  • 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: jobeet
    database_user: root
    database_password: root
    mailer_transport: smtp
    mailer_host: 127.0.0.1
    mailer_user: null
    mailer_password: null
    locale: fr
    secret: V5LyMQ3e9Ln9qgfHvyW3cdj988D946ED
    debug_toolbar: true
    debug_redirects: false
    use_assetic_controller: true

Maintenant que Doctrine connaît votre base de données, vous pouvez créer la base de données :

php app/console doctrine:database:create

Le schéma

Pour que Doctrine connaisse nos objets, nous allons créer des fichiers "métadonnées" qui décrivent la façon dont nos objets seront stockés dans la BDD :

  • src/Erlem/JobeetBundle/Resources/config/doctrine/Affiliate.orm.yml
Erlem\JobeetBundle\Entity\Affiliate:
    type: entity
    table: affiliate
    id:
        id:
            type: integer
            generator: { strategy: AUTO }
    fields:
        url:
            type: string
            length: 255
        email:
            type: string
            length: 255
            unique: true
        token:
            type: string
            length: 255
        is_active:
            type: boolean
            nullable: true
        created_at:
            type: datetime
    manyToMany:
        categories:
            targetEntity: Category
            inversedBy: affiliates
            joinTable:
                name: category_affiliate
                joinColumns:
                    affiliate_id:
                        referencedColumnName: id
                inverseJoinColumns:
                    category_id:
                        referencedColumnName: id
    lifecycleCallbacks:
        prePersist: [ setCreatedAtValue ]

L'ORM

Maintenant Doctrine peut générer les classes qui définissent nos objets pour nous avec la commande :

php app/console doctrine:generate:entities ErlemJobeetBundle

Le retour de la commande :

Generating entities for bundle "ErlemJobeetBundle"
  > backing up Category.php to Category.php~
  > generating Erlem\JobeetBundle\Entity\Category
  > backing up Job.php to Job.php~
  > generating Erlem\JobeetBundle\Entity\Job
  > backing up Affiliate.php to Affiliate.php~
  > generating Erlem\JobeetBundle\Entity\Affiliate

Si vous regardez dans le répertoire Entity de ErlemJobeetBundle, vous trouverez les classes nouvellement créées, là-dedans: Affiliate.php, Category.php et Job.php. Ouvrez Job.php et définissez les valeurs created_at et updated_at comme ci-dessous :

  • src/Erlem/JobeetBundle/Entity/Job.php
// ...
public function setCreatedAtValue()
{
  if(!$this->getCreatedAt())
  {
    $this->created_at = new \DateTime();
  }
}
// ...
public function setUpdatedAtValue()
{
  $this->updated_at = new \DateTime();
}

 Faites de même pour la valeur created_at de la classe Affiliate :

  • src/Erlem/JobeetBundle/Entity/Affiliate.php
// ...
public function setCreatedAtValue()
{
  $this->created_at = new \DateTime();
}

Cela rendra Doctrine capable de définir les valeurs created_at et updated_at lors de l'enregistrement ou de la mise à jour des objets. Ce comportement a été défini dans les fichiers Job.orm.yml et Affiliate.orm.yml énumérés ci-dessus.

Nous allons également demander à Doctrine de créer nos tables de BDD (ou les mettre à jour afin de prendre en compte notre configuration) avec la commande:

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

Le retour de la commande :

Updating database schema...
Database schema updated successfully! "7" queries were executed

Cette tâche ne doit être vraiment utilisée qu'au cours du développement. Pour une méthode plus stable de mise à jour systématique de votre BDD de production, lisez les migrations Doctrine.

Les données initiales

Les tables ont été créées dans la BDD, mais elles ne contiennent pas de données. Pour toute application web, il existe trois types de données: les données initiales (ce qui est nécessaire pour que l'application fonctionne, dans notre cas, nous avons quelques catégories initiales et un utilisateur admin), les données test (nécessaires pour tester l'application) et les données utilisateur (créées par les utilisateurs au fil du temps).

Pour remplir la BDD avec des données initiales, nous allons utiliser DoctrineFixturesBundlePour installer ce paquet, suivez les étapes suivantes :

1. Ajouter ce qui suit à votre fichier composer.json, dans la section require :

  • composer.json
// ...
    "require": {
        // ...
        "doctrine/doctrine-fixtures-bundle": "dev-master",
        "doctrine/data-fixtures": "dev-master"
    },
 
// ...

2. Mettez à jour les vendors :

composer update

3. Enregistrer le bundle DoctrineFixturesBundle dans app/AppKernel.php :

  • app/AppKernel.php
// ...
 
public function registerBundles()
{
    $bundles = array(
        // ...
        new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle()
    );
 
    // ...
}

Maintenant que tout est en place, nous allons créer de nouvelles classes pour charger les données dans un nouveau dossier dans notre paquet : src/Erlem/JobeetBundle/DataFixtures/ORM.

Une fois vos fixtures écrites, vous pouvez les charger via la ligne de commande suivante :

php app/console doctrine:fixtures:load

Retour de la commande :

Careful, database will be purged. Do you want to continue Y/N ?Y
  > purging database
  > loading [1] Erlem\JobeetBundle\DataFixtures\ORM\LoadCategoryData
  > loading [2] Erlem\JobeetBundle\DataFixtures\ORM\LoadJobData

Vous pouvez maintenant vérifier votre BDD, vous devriez voir les données chargées dans les tables.

Le fichier de fixtures des offres fait référence à deux images. Vous pouvez les télécharger (sensio-labs.gif, extreme-sensio.gif) et les mettre dans le répertoire web/uploads/jobs/.

Voir dans le navigateur

Si vous exécutez la commande ci-dessous, elle va créer un nouveau contrôleur src/Erlem/JobeetBundle/Controllers/JobController.php des actions pour l'inscription, la création, l'édition et la suppression d'emplois (et leurs modèles correspondants, la forme et les routes) :

php app/console doctrine:generate:crud --entity=ErlemJobeetBundle:Job --route-prefix=erlem_job --with-write --format=yml

Cela va créer un nouveau contrôleur src/Erlem/JobeetBundle/Controllers/JobController.php avec des actions pour lister, créer, modifier et supprimer des offres (et leurs modèles, routes et formulaires correspondants). Pour le voir dans le navigateur, nous devons importer les nouvelles routes qui ont été créées dans src/Erlem/JobeetBundle/Resources/config/routing/job.yml dans notre le fichier de routage principal de notre paquet :

  • src/Erlem/JobeetBundle/Resources/config/routing.yml
ErlemJobeetBundle_job:
    resource: "@ErlemJobeetBundle/Resources/config/routing/job.yml"
    prefix:   /job

Nous aurons aussi besoin d'ajouter une méthode __toString() à notre classe Category pour être utilisée par le menu déroulant Catégorie du formulaire de modification d'offre :

// ...
public function __toString()
{
  return $this->getName();
}

Videz le cache :

php app/console cache:clear --env=dev
php app/console cache:clear --env=prod
chmod 777 -R app/cache/

Vous pouvez maintenant tester le contrôleur Job dans un navigateur: http://jobeet.local/job/ ou dans l'environnement de développement, http://jobeet.local/app_dev.php/job/

03-list

03-show

Vous pouvez désormais créer et éditer des emplois. Essayez de laisser un champ vide requis, ou essayez d'entrer des données non valides. C'est vrai, symfony a créé des règles de validation de base par introspection du schéma de base de données.

C'est tout. Aujourd'hui, nous avons à peine écrit du code PHP, mais nous avons un module de travail Web pour le modèle de Job, prêt à être modifié et personnalisé. Demain, vous allez vous familiariser avec le contrôleur et la vue.

Code source

Le code source est sur GitHub. Vous pouvez le télécharger en exécutant les commandes ci-dessous (prérequis Symfony2 - Jobeet - Jour 01 - Démarrage du projet) :

su
cd /var/www/
git clone https://github.com/erlem/jobeet.git
cd jobeet/
git checkout tags/v0.3.0

composer update

php app/console doctrine:database:create
php app/console doctrine:schema:update --force
php app/console doctrine:fixtures:load

chmod 777 -R ../jobeet/

php app/console cache:clear --env=dev
php app/console cache:clear --env=prod
chmod 777 -R app/cache/

Vous pouvez maintenant tester le contrôleur Job dans un navigateur: http://jobeet.local/job/ ou dans l'environnement de développement, http://jobeet.local/app_dev.php/job/.


Symfony2 - Jour 02 - Le projet
[Sommaire] Symfony2 - Jour 04 - Le Contrôleur et la Vue >


Pour ce tutoriel, je me suis inspiré du tutoriel Symfony2 Jobeet du site IntelligentBee

Submit to DeliciousSubmit to DiggSubmit to FacebookSubmit to Google PlusSubmit to StumbleuponSubmit to TechnoratiSubmit to TwitterSubmit to LinkedIn