Aller au contenu

Les addons (LSaddon)

Les LSaddons sont utilisés pour implémenter dans LdapSaisie des fonctionnalités spécifiques tel que :

  • le support d'une famille d'attributs spécifiques (POSIX, Samba, SUPANN…) par le biais de méthodes de génération de la valeur de ces attributs par exemple (paramètre generate_function) ;

  • des tâches communes et génériques (envoi de mails, connexion FTP/SSH…) ;

  • l'implémentation de déclencheurs spécifiques à votre environnement : création automatique du dossier client sur le serveur de fichiers de l'entreprise, création de la boite mail de l'utilisateur… ;

  • l'implémentation de vues personnalisées proposées dans l'interface

  • l'implémentation d'action personnalisée sur les objets (synchronisation, archivage…) ou sur les résultats de recherches (export, rapport personnalisé…) ;

Structure d'écriture

L'écriture d'un LSaddon doit respecter une structure suffisamment souple afin de ne pas être un frein à vos contributions, tout en permettant d'assurer la bonne intégration de votre contribution au projet. Le code que vous écrirez sera réparti dans deux fichiers :

  • conf/LSaddons/config.LSaddons.[addon name].php

Ce fichier contiendra la configuration de votre LSaddon. On y retrouvera la déclaration de constances et/ou variables de configuration permettant d'adapter votre LSaddon à une installation et à un environnement.

  • includes/addons/LSaddons.[addon name].php

Ce fichier contiendra le code à proprement dit de votre LSaddon.

Structure du fichier includes/addons/LSaddons.[addon name].php :

<?php
/*
 * Error messages
 */

// Support error messages
LSerror::defineError("MYADDON_SUPPORT_01", ___("MYADDON Support :  Unable to load %{dep}."));

LSerror::defineError(
  "MYADDON_SUPPORT_02",
  ___("MYADDON Support : The constant %{const} is not defined."),
);

// Other orror messages
LSerror::defineError("MYADDON_01", ___("An error : %{msg}."));

LSerror::defineError("MYADDON_02", ___("An other error about %{about} : %{msg}"));

LSerror::defineError("MYADDON_03", ___("Unknown error."));

/**
 * Verify support of my addon by LdapSaisie
 *
 * @author My Name <my.email@example.com>
 *
 * @return boolean true if my addon is totaly supported, false in other cases
 **/
function LSaddon_myaddon_support() {
  $retval = true;

  // Check/load dependencies
  if (!class_exists("mylib")) {
    if (!LSsession::includeFile(LS_LIB_DIR . "class.mylib.php")) {
      LSerror::addErrorCode("MYADDON_SUPPORT_01", "mylib");
      $retval = false;
    }
  }

  $MUST_DEFINE_CONST = ["LS_MYADDON_CONF_O1", "LS_MYADDON_CONF_O2"];

  foreach ($MUST_DEFINE_CONST as $const) {
    if (!defined($const) || constant($const) == "") {
      LSerror::addErrorCode("MYADDON_SUPPORT_02", $const);
      $retval = false;
    }
  }

  if ($retval) {
    // Register LSaddon view using LSsession :: registerLSaddonView()

    if (php_sapi_name() == "cli") {
      // Register LSaddon CLI command using LScli :: add_command()
    }
  }

  return $retval;
}

/**
 * My first function
 *
 * Description of this wonderfull function
 *
 * @author My Name <my.email@example.com>
 *
 * @return [type(s) of returned values (pipe separator)] Description of the return of this function
 **/
function myaddon_first_function($arg1, $arg2) {
  // Do some stuff
  if (true) {
    LSerror::addErrorCode(
      "MYADDON_01",
      "something went wrong", // Error LSformat unique argument
    );
    return false;
  }

  if (false) {
    LSerror::addErrorCode("MYADDON_02", [
      // Error LSformat arguments
      "about" => "second step",
      "msg" => "something went wrong",
    ]);
    return false;
  }

  if (true) {
    LSerror::addErrorCode("MYADDON_03"); // Error without argument
    return false;
  }
  return true;
}

// Defined custom CLI commands functions only on CLI context
if (php_sapi_name() != "cli") {
  return true;
}

// Always return true to avoid some warning in log

// Defined functions handling custom CLI commands and optionnaly // their arguments autocompleter functions. ?>

Par convention, la structure de ce fichier est toujours à peu près la même:

- On déclare tout d'abord les messages d'erreurs qui seront potentiellement émis par notre
[LSaddon](../../conf/index.md#configuration-des-lsaddons) en commençant par les messages d'erreurs liés au
support de cet [LSaddon](../../conf/index.md#configuration-des-lsaddons). On utilise pour cela la méthode
`LSerror :: defineError()` qui attends en premier argument, l'identifiant du message
d'erreur et en tant que second argument, le
[LSformat](../../conf/global/LSformat.md#format-parametrable) du message d'erreur. Par convention,
les identifiants des messages d'erreurs seront en majuscule et préfixés du nom du
[LSaddon](../../conf/index.md#configuration-des-lsaddons).

- On déclare ensuite une fonction `LSaddon_[myaddon]_support` qui sera exécutée lors du chargement
de l'addon et qui permettra de s'assurer du support de celui-ci. Cette fonction devra retourner
`True` si c'est le cas ou `False` dans le cas contraire.

Cette fonction s'assura notamment :
- que les librairies dont l'addon dépends sont bien chargées et fonctionnelles ;
- que ses variables et constantes de configuration sont bien définies ;
- de déclarer [les vues personnalisées](#les-vues-personnalisees) fournies par cet
  [LSaddon](../../conf/index.md#configuration-des-lsaddons) ;
- de déclarer [les commandes _CLI_ personnalisées](#les-commandes-cli-personnalisees) fournies par
  cet [LSaddon](../../conf/index.md#configuration-des-lsaddons) ;

- On déclare ensuite les fonctions, classes et éléments fournis et manipulés par l'addon.
- Si notre addon offre des [commandes _CLI_ personnalisées](#les-commandes-cli-personnalisees), les
fonctions les implémentant ne seront définies, dans un souci de performance, que dans un contexte
ou elles seraient potentiellement appelables, c'est à dire dans un contexte d'exécution `CLI`.
Pour cela, nous utilisons communément la fonction `php_sapi_name` pour déterminer le contexte
d'exécution et si celui-ci vaut `cli`, nous stoppons l'exécution du reste du code du fichier via
un `return true`.

/// note
Il est important dans ce contexte de ne jamais retourner autre chose que `True` pour éviter
tout message d'erreur inutile dans les logs.
///

- On déclare, pour finir, les fonctions implémentant les
[commandes _CLI_ personnalisées](#les-commandes-cli-personnalisees) et leur éventuelle fonction
gérant l'autocomplétion des arguments qu'elles acceptent.