Ajouter les classes Query de Propel 1.6 au Service Container de Symfony 2

Propel 1.6 ne bénéficie pas de la même intégration dans Symfony 2 que Doctrine 2. Je vais vous montrer comment combler en partie cette différence en ajoutant les classes Query de Propel au Service Container de Symfony 2 afin de pouvoir les "injecter" par la suite. Je vous invite à lire la documentation sur l'injection de dépendance si vous n'êtes pas familier avec.

Imaginons que j'ai un blog dans un bundle BlogBundle qui contient un dossier Model dans lequel Propel a généré les classes correspondantes à la bdd.
Je commence par suivre les recommanations de la documentation sur l'Injection de Dépendance et je crée des variables pour le nom des classes dans le fichier BlogBundle/Resources/config/services.yml

parameters:
    ## Déclaration des Propel Query ##
    blog.model.article_query.class: MonProjet\BlogBundle\Model\ArticleQuery
    blog.model.commentaire_query.class: MonProjet\BlogBundle\Model\CommentaireQuery

Ensuite il suffit de définir un service pour chaque classe, toujours dans le fichier services.yml

services:
    ## Déclaration des Propel Query as Service ##
    blog.model.article_query:
        class:       %blog.model.article_query.class%
        constructor: create
    blog.model.commentaire_query:
        class:       %blog.model.commentaire_query.class%
        constructor: create

J'ai utilisé les variables définis plus haut. J'ai également défini le constructeur que je veux utiliser, de cette façon Symfony 2 appelle statiquement la méthode spécifiée.

Avant la définition des classes Query dans le service container, je devais écrire ce type de code:

$articles = MonProjet\BlogBundle\Model\ArticleQuery::create()
                          ->filterByAuthor('ulrich')
                          ->find();

Maintenant, je peux écrire:

$articles = $this->get('blog.model.article_query') //$this->get() fait référence au service container
                          ->filterByAuthor('ulrich')
                          ->find();

Ces deux écritures sont équivalentes. Bien que moins explicite, la deuxième à l'avantage de centraliser comment accéder à la classe ArticleQuery. Ce qui sera un gain de temps énorme lors d'une migration vers Propel 2 ou autre.

Autre point très intéréssant, je peux maintenant utiliser les classes Query avec l'injection de dépendance de Symfony 2. Je peux créer un moteur de recherche d'article. Je veux passer un objet ArticleQuery à mon constructeur ce qui donnerait le code suivant:

<?php
 
namespace MonProjet\BlogBundle\Lib;
 
use MonProjet\BlogBundle\Model\ArticleQuery;
 
class MoteurRecherche 
{
    public function __construct(ArticleQuery $articleQuery)
    {
         ....
     }
 
    ....
}

Pour obtenir une instance de cette classe via le Service Container, je dois ajouter à mon fichier services.yml.

parameters:
    blog.lib.moteur_recherche.class: MonProjet\BlogBundle\Lib\MoteurRecherche 

services:
    blog.lib.moteur_recherche:
        class:     %blog.lib.moteur_recherche.class%
        arguments: [ @blog.model.article_query ]

Ce qui me permet d'accéder à ma classe MoteurRecherche avec ce code:

//sans le service container
$mr = new MonProjet\BlogBundle\Lib\MoteurRecherche(MonProjet\BlogBundle\Model\ArticleQuery::create());
 
//avec le service container
$mr = $this->get('blog.lib.moteur_recherche');

 

Voilà, j'espère que cet article aura répondu à vos questions sur comment utiliser Propel dans Symfony 2 avec le Service Container.

Ajouter un commentaire