Ajouter un Service à Elgg

Le guide sur les services présente des informations générales sur l’utilisation des services Elgg.

Pour ajouter un nouvel objet service à Elgg :

  1. Annotez votre classe comme @access private.

  2. Ouvrez la classe Elgg\Di\ServiceProvider.

  3. Ajoutez une annotaiton @property-read pour votre service au tout début. Ceci permet aux EDIs et aux analyseurs de code statique de comprendre le type de la propriété.

  4. Pour le constructeur, ajoutez le code pour indiquer au fournisseur de service quoi retourner. Voyez la classe Elgg\Di\DiContainer pour plus d’information sur comment le conteneur DI (« Dependency Injection ») d’Elgg fonctionne.

A ce stade votre service sera disponible depuis l’objet fournisseur de service, mais ne sera pas encore accessible aux plugins.

Injectez vos dépendances

Concevez votre constructeur de classe de sorte qu’il demande les dépendances nécessaires plutôt que de les créer ou d’utiliser _elgg_services(). La méthode setFactory() du fournisseur de service fournit l’accès à l’instance du fournisseur de service dans la méthode de votre fabrique.

Voici un exemple de fabrique de service foo, qui injecte les services config et db dans le constructeur :

// in Elgg\Di\ServiceProvider::__construct()

$this->setFactory('foo', function (ServiceProvider $c) {
    return new Elgg\FooService($c->config, $c->db);
});

La liste complète des services internes peut être vue dans les déclarations @property-read au début de Elgg\Di\ServiceProvider.

Avertissement

Evitez de faire du travail dans le constructeur de votre service, en particulier si cela requiert des requêtes sur la base de données. Actuellement les tests PHPUnit tests ne peuvent pas les effectuer.

Faire qu’un service fasse partie de l’API publique

Si votre service est conçu pour être utilisé par des développeurs de plugins :

  1. Faites une interface Elgg\Services\<Name> qui ne contient que ces méthodes nécessaires dans l’API publique.

  2. Faites que la classe de votre service implémente cette interface.

  3. Pour les méthodes qui sont dans l’interface, déplacez la documentation dans l’interface. Vous pouvez simplement utiliser {@inheritdoc} dans les PHPDocs des méthodes de votre classe effective.

  4. Documentez votre service dans docs/guides/services.rst (ce fichier)

  5. Ouvrez le test PHPUnit Elgg\ApplicationTest et ajoutez la clef de votre service au tableau $names dans testServices().

  6. Ouvrez la classe Elgg\Application.

  7. Ajoutez une déclaration @property-read pour documenter votre service, mais utilisez votre interface pour le type, et pas le nom de la classe de votre service.

  8. Ajoutez la clef de votre service au tableau dans la propriété $public_services, par ex. 'foo' => true,

Désormais votre service sera disponible via l’accès à la propriété sur l’instance Elgg\Application :

// using the public foo service
$three = elgg()->foo->add(1, 2);

Note

Pour des exemples, voyez le service config, qui comprend l’interface Elgg\Services\Config et la classe d’implémentation effective Elgg\Config.

Cycle de vie d’un Service et Fabriques (« factories »)

Par défaut, les services enregistrés sur le fournisseur de service sont « partagés », ce qui signifie que le fournisseur de service va conserver l’instance créée pour le reste de la requête, et servir la même instance à tout ce qui demande la propriété.

Si vous avez besoin que les développeurs puissent construire des objets qui soient pré-coonnectés aux services Elgg, vous pouvez avoir besoin d’ajouter une méthode de fabrique publique à Elgg\Application. Voici un exemple qui retourne une nouvelle instance en utilisant les services d’Elgg :

public function createFoo($bar) {
    $logger = $this->services->logger;
    $db = $this->services->db;
    return new Elgg\Foo($bar, $logger, $db);
}