Dans Drupal 8 on trouve une nouvelle notion qui découle des nouvelles versions de Php et par conséquent du framework de Symfony : les services.
Dans cet article on va découvrir comment créer un service dans Drupal 8.
1. Qu'est ce qu'un service?
Voici quelques généralités sur les services :
Un service est un objet instancié par le Service Container (le conteneur de service qui gère les services), dans une logique de réutilisation, comme pour réutiliser un calcul par exemple ou pour créer une connexion à la base de données.
Le service est créé une seule fois au moment où l'on fait appel à lui, quand on crée l'objet et qu'on le retourne. Cela améliore donc les performances de l'application et évite de charger tous les services au lancement de l'application.
Un service peut dépendre d'autres services.
Ils permettent de créer toute la logique de l'application et ainsi de garder des controllers qui soient propres avec peu de code à l'intérieur.
Les services constituent la partie centrale du principe de l'injection de dépendances.
On retrouve les définitions de services de Drupal 8 dans le répertoire /core et dans le fichier core.services.yml, c'est assez instructif d'y jeter un oeil.
Les services améliorent la structuration de l'application et permettent de simplifier l'élaboration de tests unitaires car la logique métier est bien séparée des dépendances de Drupal.
1. Comment créer un service dans Drupal 8?
Pour créer un service dans Drupal 8, on va prendre l'exemple d'un service créé dans un module hello_world pour être original! :D
Une fois les bases du module achevées, on va créer un fichier HelloWorldSalutation.php dans le répertoire /src de notre module.
Je fais une service très simple, avec une méthode getSalutation
qui affiche "Hello World".
<?php
namespace Drupal\hello_world;
use Drupal\Core\StringTranslation\StringTranslationTrait;
/**
* HelloWorldSalutation
*/
class HelloWorldSalutation {
use StringTranslationTrait;
/*
* Return salutation
*/
public function getSalutation() {
return $this->t('Hello World');
}
}
Deuxième étape, il faut maintenant déclarer notre service. On va ajouter le fichier hello_world.services.yml à la racine de notre module.
services:
hello_world.salutation:
class: Drupal\hello_world\HelloWorldSalutation
2. Comment se servir d'un service dans D8?
On a ensuite 2 façons pour se servir du service :
A. en statique, utilisé dans le fichier .module par exemple ou dans les classes non exposées au Service Container :
$service = \Drupal::service('hello_world.salutation');
$service->getSalutation();
B. injecter le service dans un controller :
<?php
namespace Drupal\hello_world\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
class HelloController extends ControllerBase {
/**
* @var \Drupal\hello_world\HelloWorldSalutation
*/
protected $salutation;
/**
* HelloController constructor
*
* @param \Drupal\hello_world\HelloWorldSalutation $salutation
*/
public function __construct(HelloWorldSalutation $salutation) {
$this->salutation = $salutation;
}
/**
* {#inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('hello_world.salutation')
);
}
}
3. Gérer les dépendances d'un service à un autre service
Pour illustrer le propos, on va se servir par exemple de la configuration de Drupal dans notre premier service HelloWorldSalutation
services:
hello_world.salutation:
class: Drupal\hello_world\HelloWorldSalutation
arguments: ['@config.factory']
Dans le code de notre service (la classe HelloWorldSalutation) on ajoute une propriété et un constructeur :
/**
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* HelloWorldSalutation constructor
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
*/
public function __construct(ConfigFactoryInterface $config_factory) {
$this->configFactory = $config_factory;
}
et également un use plus haut dans la classe :
use Drupal\Core\Config\ConfigFactoryInterface;
Le résultat est qu'on a maintenant accès à la Config Factory à l'intérieur de notre service.