Utilisation du CompilerPass

Le compilerPass est extrêmement utile pour faire appel aux variables de l’environnement courant, bien entendu, mais aussi pour les services tagués.

En effet, Symfony nous permet, lorsque le compilerPass s’exécute (après ceux de tous les autres bundles), d’appeler un service en particulier, ainsi que l’une de ses fonctions, et de l’exécuter en allant dynamiquement rechercher tous les services ayant un tag personnalisé. C’est parti!

Un service de paiement

Créons deux services de paiement: Be2bill et Paypal.

Bien évidemment, on imagine, lorsqu’on fait appel à getHtml, qu’il vont générer le formulaire adéquat et nous le renvoyer. La fonction getLabel est très importante, nous allons le voir d’ici peu.

Ces deux services de paiement étendent une classe abstraite:

Il y a une fonction très intéressante, isTypeMatch, qui permet, en fonction du label passé, de savoir s’il correspond à l’un ou l’autre des services de paiment.

Cette classe abstraite implémente une interface qui va rapidement nous servir:

Créons un container de services de paiement

Ce n’est pas tout, nous avons deux services de paiement, une classe abstraite et une interface. A présent, j’aimerais bien avoir un service qui, dynamiquement, récupère tous les services de paiement. Pour cela, je vais d’abord créer ce service de paiement « container »:

Très simple, il permet de récupérer tous les services de paiement, mais aussi d’en ajouter. Remarquez que le type du service de paiement est l’interface GenericPaymentServiceInterface.

Créons un manager de services de paiement

C’est quasiment la dernière étape. Ce manager de service aura comme dépendance le PaymentContainerService qui contiendra tous les services de paiement existants. Il pourra, selon le service de paiement demander, déterminer quel service de paiement il doit retourner.

Comme vous le voyez, on fait appel à un label de service de paiement. A ce moment là, le paiementContainerService qui contient tous les services de paiement (donc ici Be2Bill et Paypal) dans un array, est utilisé. On boucle dessus, et la fameuse fonction isTypeMatch de l’abstractPaymentService est appelée pour savoir s’il faut retourner une instance de Be2Bill ou une instance de Paypal.

Déclarons les services

A présent, pour que la magie opère, il est temps d’enregistrer nos services:

Nous avons déclaré nos deux services de paiement, avec un tag personnalisé: app_portal.payment_services, puis notre service PaymentContainerService qui contiendra les deux services de paiement, puis notre PaymentManagerService qui a comme dépendance le PaymentContainerService. Ouf!

Il ne reste plus qu’une étape, déclarer notre compilerPass, et le coder bien sûr!

Notre compilerPass personnalisé

C’est là que ça devient intéressant. Nous demandons à Symfony de récupérer notre service app_portal.payment_container_service. Puis, s’il le trouve, de récupérer tous les services portant le tag app_portal.payment_services (soit Be2Bill et Paypal).

Enfin, sur chacun de ces services tagués, nous appelons la méthode addPaymentService du service PaymentContainerService afin qu’il ait dans son array les deux services de paiement.

Pour finir, il faut enregistrer notre compilerPass directement dans AppPortalBundle.php:

 

Bon, la démonstration est quasi terminée, mais on va aller jusqu’au bout, ce sera plus amusant. Nous allons configurer nos services de paiement dans config_dev.yml et config_prod.yml (ici, seulement config_dev.yml pour la démonstration):

Bon, ce n’est pas tout ça, mais si vous allez sur n’importe quelle page de votre site, ça ne fonctionnera plus, car il vous faut déclarer ces paramètres dans votre fichier Configuration.php du répertoire DependencyInjection de votre bundle:

Et puis, nous allons faire en sorte que ces valeurs de configuration soient disponibles dans le container en les déclarant dans AppPortalExtension.php:

 

Création d’un controller de paiement

Imaginons que nous arrivons, via un contrôleur, directement sur une page avec le bon formulaire selon que l’on ait indiqué dans la configuration que le service de paiement par défaut est Be2Bill ou Paypal (bien évidemment, dans la réalité, vous arriveriez sur une page où la personne choisirait via une option le mode de paiement souhaité, puis validerait, et par une requête ajax, le bon formulaire serait récupéré, posté, et vous arriveriez sur la page de paiement du service de paiement sélectionné. Mais nous allons faire simple ici):

 

La vue du formulaire de paiement

Nous arrivons donc à une vue qui doit nous donner un formulaire:

Bien évidemment, il nous faut une fonction twig pour générer ce formulaire, puisqu’il est différent selon l’organisme de paiement. C’est parti pour créer cette fonction, en commençant par son service (déclaré ici dans un fichier twig.xml qui est déjà déclaré dans AppPortalExtension, voyez plus haut):

Puis par son code:

Nous récupérons donc dans le constructeur le mode de paiement par défaut et le paymentManagerService.

La fonction getPaymentForm récupère la bonne solution de paiement avec la fonction getPaymentClass, puis elle appelle son code html en lui passant l’url qui lui correspond et qu’elle a récupéré via le fichier config_dev.yml ou config_prod.yml.

Et c’est terminé! La boucle est donc bouclé.

Pour résumer:

  • Nous avons créé deux services de paiement, Be2Bill et Paypal, qui étendaient une classe abstraite qui possédait la fonction isTypeMatch
  • Nous avons créé un service container de solutions de paiement, dont l’array est rempli via le compilerPass qui fait appel à tous les services de paiement tagués
  • Nous avons créé un service de paiement manager qui a le service de paiement container injecté et qui récupère le bon service de paiement selon le label passé en paramètre
  • Nous avons créé une fonction twig qui va lire la configuration pour connaître le service de paiement par défaut, récupérer les informations associées, faire appel au service de paiement manager qui va récupérer le bon service de paiement (Be2Bill ou Paypal) et qui va retourner le formulaire adéquat.

Pour finir, une petite preuve en image que le service container de solutions de paiement a bien dans son array Be2Bill et Paypal, et qu’en changeant le service de paiement par défaut dans le fichier config_dev/prod.yml, on retourne bien le bon formulaire:

Changez le défault en Paypal et ce sera le service Paypal qui sera retourné:

 

Rédigé par

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *