mirror of
https://gitlab.easter-eggs.com/ee/ldapsaisie.git
synced 2024-11-01 00:03:18 +01:00
675 lines
31 KiB
XML
675 lines
31 KiB
XML
<?xml version="1.0" encoding="UTF-8" ?>
|
|
<chapter id="contrib">
|
|
|
|
<title>Contribution</title>
|
|
|
|
<para>Comme tout projet libre qui se respecte, les contributions à LdapSaisie sont les bienvenues. Ce chapitre explique
|
|
les possibilités de contribution.</para>
|
|
|
|
<sect1 id="contrib-LSaddons">
|
|
<title>LSaddons</title>
|
|
<para>Les &LSaddons; sont utilisés pour implémenter dans &LdapSaisie; des fonctionnalités spécifiques tel que :
|
|
<itemizedlist>
|
|
<listitem><simpara>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
|
|
<literal>generate_function</literal>) ;</simpara></listitem>
|
|
<listitem><simpara>des tâches communes et génériques (envoi de mails, connexion FTP/SSH…) ;</simpara></listitem>
|
|
<listitem><simpara>l'implémentation de <link linkend='config-LSobject-triggers'>déclencheurs</link> 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… ;</simpara></listitem>
|
|
<listitem><simpara>l'implémentation de <link linkend='contrib-LSaddon-views'>vues personnalisées</link> proposées
|
|
dans l'interface</simpara></listitem>
|
|
<listitem><simpara>l'implémentation d'action personnalisée sur les <link linkend='config-LSobject-customActions'>
|
|
objets</link> (synchronisation, archivage…) ou sur les <link linkend='config-LSobject-customSearchActions'>
|
|
résultats de recherches</link> (export, rapport personnalisé…) ;</simpara></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<sect2 id="contrib-LSaddons-structure">
|
|
<title>Structure d'écriture</title>
|
|
|
|
<para>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 :</para>
|
|
<variablelist>
|
|
|
|
<varlistentry>
|
|
<term>conf/LSaddons/config.LSaddons.[addon name].php</term>
|
|
<listitem><simpara>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.</simpara></listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>includes/addons/LSaddons.[addon name].php</term>
|
|
<listitem><simpara>Ce fichier contiendra le code à proprement dit de votre &LSaddon;.</simpara></listitem>
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
|
|
<programlisting linenumbering="unnumbered">
|
|
<citetitle>Structure du fichier includes/addons/LSaddons.[addon name].php</citetitle>
|
|
<![CDATA[<?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>
|
|
*
|
|
* @retval 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= array(
|
|
'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>
|
|
*
|
|
* @retval [type(s) of returned values (pipe separator)] Description of the return of this function
|
|
**/
|
|
function myaddon_first_function($arg1, $arg2) {
|
|
// Do some stuff
|
|
if (something) {
|
|
LSerror :: addErrorCode(
|
|
'MYADDON_01',
|
|
'something went wrong' // Error LSformat unique argument
|
|
);
|
|
return false;
|
|
}
|
|
|
|
if (something else) {
|
|
LSerror :: addErrorCode(
|
|
'MYADDON_02',
|
|
array( // Error LSformat arguments
|
|
'about' => 'second step',
|
|
'msg' => 'something went wrong'
|
|
)
|
|
);
|
|
return false;
|
|
}
|
|
|
|
if (still something else) {
|
|
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.
|
|
]]>
|
|
</programlisting>
|
|
|
|
<para>Par convention, la structure de ce fichier est toujours à peu près la même:
|
|
|
|
<itemizedlist>
|
|
<listitem><para>On déclare tout d'abord les messages d'erreurs qui seront potentiellement émis par notre &LSaddon; en commençant par
|
|
les messages d'erreurs liés au support de cet &LSaddon;. On utilise pour cela la méthode <literal>LSerror :: defineError()</literal> qui
|
|
attends en premier argument, l'identifiant du message d'erreur et en tant que second argument, le &LSformat; du message d'erreur. Par
|
|
convention, les identifiants des messages d'erreurs seront en majuscule et préfixés du nom du &LSaddon;.</para></listitem>
|
|
<listitem><para>On déclare ensuite une fonction <literal>LSaddon_[myaddon]_support</literal> 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 <literal>True</literal> si c'est le cas ou
|
|
<literal>False</literal> dans le cas contraire.</para>
|
|
<para>Cette fonction s'assura notamment :
|
|
<itemizedlist>
|
|
<listitem><simpara>que les librairies dont l'addon dépends sont bien chargées et fonctionnelles ;</simpara></listitem>
|
|
<listitem><simpara>que ses variables et constantes de configuration sont bien définies ;</simpara></listitem>
|
|
<listitem><simpara>de déclarer <link linkend='contrib-LSaddon-views'>les vues personnalisées</link> fournies par cet &LSaddon; ;</simpara></listitem>
|
|
<listitem><simpara>de déclarer <link linkend='contrib-LSaddon-CLI-commands'>les commandes <emphasis>CLI</emphasis> personnalisées</link> fournies par cet &LSaddon; ;</simpara></listitem>
|
|
</itemizedlist>
|
|
</para></listitem>
|
|
<listitem><para>On déclare ensuite les fonctions, classes et éléments fournis et manipulés par l'addon.</para></listitem>
|
|
<listitem><para>Si notre addon offre des <link linkend='contrib-LSaddon-CLI-commands'>commandes <emphasis>CLI</emphasis>
|
|
personnalisées</link>, 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 <literal>CLI</literal>. Pour cela,
|
|
nous utilisons communément la fonction <literal>php_sapi_name</literal> pour déterminer le contexte d'exécution et si celui-ci
|
|
vaut <literal>cli</literal>, nous stoppons l'exécution du reste du code du fichier via un <literal>return true</literal>.
|
|
<note><simpara>Il est important dans ce contexte de ne jamais retourner autre chose que <literal>True</literal> pour éviter tout message
|
|
d'erreur inutile dans les logs.</simpara></note>
|
|
</para></listitem>
|
|
<listitem><para>On déclare, pour finir, les fonctions implémentant les <link linkend='contrib-LSaddon-CLI-commands'>commandes
|
|
<emphasis>CLI</emphasis> personnalisées</link> et leur éventuelle fonction gérant l'autocomplétion des arguments qu'elles acceptent.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 id="contrib-LSaddon-views">
|
|
<title>Les vues personnalisées</title>
|
|
|
|
<para>Les &LSaddons; peuvent fournir des vues personnalisées qui seront accessibles à tout ou parties des utilisateurs de l'application.
|
|
Ce filtrage d'accès sera fait en utilisant les &LSprofiles; de l'utilisateur connecté sur la <link linkend="config-subDn">racine
|
|
courante de l'annuaire LDAP</link>.</para>
|
|
|
|
<para>Pour mettre en place une telle vue personnalisée, il est nécessaire de :
|
|
<itemizedlist>
|
|
<listitem><simpara>Déclarer cette vue dans la fonction <literal>LSaddon_[addon]_support</literal> de l'addon à l'aide de la méthode
|
|
<literal>LSsession :: registerLSaddonView</literal> ;</simpara></listitem>
|
|
<listitem><simpara>Déclarer la fonction implémentant cette vue. Cette fonction n'acceptera aucun paramètre et ne retournera rien.
|
|
Elle devra en outre s'occuper de définir son fichier template et charger les dépendances de ce dernier (fichiers <emphasis>CSS
|
|
& JS</emphasis>, variables...).</simpara></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>Pour implémenter une telle vue personnalisée, vous pouvez vous inspirer de l'exemple fourni ci-dessous ou encore des vues fournies
|
|
par les autres &LSaddons; (par exemple, l'addon <link linkend="config-LSaddon_exportSearchResultAsCSV">exportSearchResultAsCSV</link>).
|
|
</para>
|
|
|
|
|
|
<programlisting linenumbering="unnumbered">
|
|
<citetitle>Structure du fichier includes/addons/LSaddons.[addon name].php</citetitle>
|
|
<![CDATA[<?php
|
|
function LSaddon_myaddon_support() {
|
|
|
|
$retval=true;
|
|
|
|
// Some check
|
|
|
|
if ($retval) {
|
|
$retval = LSsession :: registerLSaddonView(
|
|
'myaddon', // addon name
|
|
'myaddon_view', // addon view ID
|
|
__('MyAddon view'), // addon view label
|
|
'myaddon_view', // callable (ex: function name) that implement addon view
|
|
array('user'), // array listing allowed LSprofiles
|
|
true // Show/hide this addon view in user menu
|
|
);
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
[...]
|
|
|
|
/**
|
|
* My addon view handler function
|
|
*
|
|
* Description of this view
|
|
*
|
|
* @author My Name <my.email@example.com>
|
|
*
|
|
* @retval void
|
|
**/
|
|
function myaddon_view() {
|
|
// Do some stuff and set some template variables
|
|
$list = array ([...]);
|
|
LStemplate :: assign('list', $list);
|
|
|
|
// Load some CSS & JS files need on this view
|
|
LStemplate :: addCssFile('LSaddon_myadon.css');
|
|
LStemplate :: addJSscript('LSaddon_myadon.js');
|
|
|
|
// Set template file of the view
|
|
LSsession :: setTemplate('LSaddon_myadon_view.tpl');
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</sect2>
|
|
|
|
<sect2 id="contrib-LSaddon-CLI-commands">
|
|
<title>Les commandes <emphasis>CLI</emphasis> personnalisées</title>
|
|
|
|
<para>Les &LSaddons; peuvent fournir des commandes <emphasis>CLI</emphasis> personnalisées qui seront accessibles via la commande
|
|
<literal>ldapsaisie</literal> fournie avec l'application. Cela peut, par exemple, vous permettre de rendre accessible en ligne de commandes
|
|
une procédure implémentée dans le code d'LdapSaisie et vous permettre de mettre en place une tâche planifiée exécutant cette procédure
|
|
régulièrement.</para>
|
|
|
|
<para>Pour mettre en place une telle commande <emphasis>CLI</emphasis> personnalisée, il est nécessaire de :
|
|
<itemizedlist>
|
|
<listitem><simpara>Déclarer cette vue dans la fonction <literal>LSaddon_[addon]_support</literal> de l'addon à l'aide de la méthode
|
|
<literal>LScli :: add_command</literal> ;</simpara></listitem>
|
|
<listitem><simpara>Déclarer la fonction implémentant cette commande <emphasis>CLI</emphasis> personnalisée. Cette fonction acceptera,
|
|
en tant qu'unique paramètre, un tableau des arguments reçus lors de l'exécution de la commande et retournera <literal>True</literal>
|
|
ou <literal>False</literal> en cas de succès/d'erreur d'exécution de la commande. Cette valeur de retour influencera le code retourné
|
|
par la commande : <literal>0</literal> en cas de succès, <literal>1</literal> en cas d'erreur.</simpara></listitem>
|
|
<listitem><para>Bien que cela ne soit pas obligatoire, il sera également possible de déclarer une fonction permettant l'autocomplétion
|
|
des arguments acceptés par la commande.</para>
|
|
<para>Cette méthode recevra en paramètre:
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>$command_args</term>
|
|
<listitem>
|
|
<simpara>Un tableau des arguments déjà reçus par la commande.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>$comp_word_num</term>
|
|
<listitem>
|
|
<simpara>Un entier indiquant le rang de l'argument que l'autocomplétion tente de compléter. Il peut s'agir du rang d'un
|
|
paramètre déjà fourni et présent dans le tableau <literal>$command_args</literal> ou bien d'un rang supérieur aux nombres
|
|
d'arguments déjà fournis à la commande et dans ce cas il s'agira d'autocompléter tous potentiels autre argument que pourrait
|
|
accepter cette commande.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>$comp_word</term>
|
|
<listitem>
|
|
<simpara>Une chaîne de caractères correspondant à ce qu'a déjà saisi l'utilisateur de l'argument que l'on tente
|
|
d'autocompléter. Cette chaîne de caractères peut être vide ou non, en fonction de s'il s'agit d'un nouvel argument à
|
|
autocompléter ou non.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>$opts</term>
|
|
<listitem>
|
|
<simpara>Un tableau des potentiels arguments globaux acceptés par <emphasis>LScli</emphasis> dans le contexte actuel (par
|
|
exemple, <literal>-d</literal> ou <literal>--debug</literal> pour l'activation du mode debug). La réponse de cette fonction
|
|
devra inclure ces potentiels arguments si le contexte d'autocomplétion si prête (nouvel argument par exemple).</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
</para>
|
|
<para>Pour finir, cette fonction devra retourner un tableau des potentielles valeurs que pourrait prendre l'argument autocomplété. Si
|
|
une unique proposition est faite à l'utilisateur, celle-ci sera automatiquement proposée à l'utilisateur et à défaut, la liste des
|
|
valeurs possibles lui seront affichées.</para>
|
|
<note><para>Pour vous aider dans l'écrire d'une telle méthode d'autocomplétion, des méthodes statiques sont fournies par la classe
|
|
<literal>LScli</literal> pour les autocomplétions les plus courantes:
|
|
|
|
<variablelist>
|
|
|
|
<varlistentry>
|
|
<term>LScli :: autocomplete_class_name()</term>
|
|
<listitem>
|
|
<simpara>Autocomplétion du nom d'une classe PHP.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>LScli :: autocomplete_addon_name()</term>
|
|
<listitem>
|
|
<simpara>Autocomplétion du nom d'un &LSaddon;.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>LScli :: autocomplete_int()</term>
|
|
<listitem>
|
|
<simpara>Autocomplétion d'un nombre entier.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>LScli :: autocomplete_LSobject_types()</term>
|
|
<listitem>
|
|
<simpara>Autocomplétion du nom d'un type d'&LSobject;.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>LScli :: autocomplete_LSobject_dn()</term>
|
|
<listitem>
|
|
<simpara>Autocomplétion du DN d'un type précis d'&LSobject; de l'annuaire.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
</para>
|
|
<para>Par ailleurs, la méthode <literal>LScli :: autocomplete_opts()</literal> vous facilitera la construction de la liste des valeurs
|
|
d'autocomplétion de l'argument courant en fonction de ce qui a déjà été saisi par l'utilisateur (paramètre
|
|
<literal>$comp_word</literal>). Cette méthode s'occupera en l'occurrence de filtrer parmi toutes les valeurs contextuelles possibles,
|
|
celles qui correspondent au préfixe fourni par l'utilisateur.</para></note>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>Pour implémenter une telle commande <emphasis>CLI</emphasis> personnalisée, vous pouvez vous inspirer de l'exemple fourni ci-dessous
|
|
ou encore des commandes <emphasis>CLI</emphasis> fournies par les autres &LSaddons; ou classes PHP de l'application.</para>
|
|
|
|
<programlisting linenumbering="unnumbered">
|
|
<citetitle>Structure du fichier includes/addons/LSaddons.[addon name].php</citetitle>
|
|
<![CDATA[<?php
|
|
function LSaddon_myaddon_support() {
|
|
|
|
$retval=true;
|
|
|
|
// Some check
|
|
|
|
if ($retval) {
|
|
if (php_sapi_name() == 'cli') {
|
|
LScli :: add_command(
|
|
'my_custom_cli_cmd', // The CLI command name (required)
|
|
'cli_my_custom_cli_cmd', // The CLI command handler (must be callable, required)
|
|
'My custom CLI command', // A short description of what this command does (required)
|
|
'[arg1] [arg2] [...]', // A short list of commands available arguments show in usage message
|
|
// (optional, default: false)
|
|
'This command permit to ...', // A long description of what this command does (optional, default:
|
|
// false)
|
|
true, // Permit to define if this command need connection to LDAP server
|
|
// (optional, default: true)
|
|
'cli_my_custom_cli_cmd_autocompleter', // Callable of the CLI command arguments autocompleter (optional,
|
|
// default: null)
|
|
true // Allow override if a command already exists with the same name
|
|
// (optional, default: null)
|
|
);
|
|
}
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
[...]
|
|
|
|
// Defined CLI commands functions only on CLI context
|
|
if (php_sapi_name() != 'cli')
|
|
return true; // Always return true to avoid some warning in log
|
|
|
|
/**
|
|
* My addon CLI command my_custom_cli_cmd handler function
|
|
*
|
|
* Description of this CLI command.
|
|
*
|
|
* @param[in] $command_args array Command arguments
|
|
* - Positional arguments :
|
|
* - LSobject
|
|
* - dn
|
|
* - Optional arguments :
|
|
* - -f|--force : Force mode
|
|
*
|
|
* @author My Name <my.email@example.com>
|
|
*
|
|
* @retval boolean True on success, false otherwise
|
|
**/
|
|
function cli_my_custom_cli_cmd($command_args) {
|
|
$objType = null;
|
|
$dn = null;
|
|
$force_mode = false;
|
|
foreach ($command_args as $arg) {
|
|
if ($arg == '-f' || $arg == '--force')
|
|
$force_mode = true;
|
|
elseif (is_null($objType)) {
|
|
$objType = $arg;
|
|
}
|
|
elseif (is_null($dn)) {
|
|
$dn = $arg;
|
|
}
|
|
else
|
|
LScli :: usage("Invalid $arg parameter.");
|
|
}
|
|
|
|
if (is_null($objType) || is_null($dn))
|
|
LScli :: usage('You must provide LSobject type and DN.');
|
|
|
|
if (!LSsession :: loadLSobject($objType))
|
|
return false;
|
|
|
|
$obj = new $objType();
|
|
if (!$obj->loadData($dn)) {
|
|
self :: log_fatal("Fail to load object $dn data from LDAP");
|
|
return false;
|
|
}
|
|
|
|
// Do some stuff on loaded object
|
|
[...]
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Args autocompleter for CLI my_custom_cli_cmd command
|
|
*
|
|
* @param[in] $command_args array List of already typed words of the command
|
|
* @param[in] $comp_word_num int The command word number to autocomplete
|
|
* @param[in] $comp_word string The command word to autocomplete
|
|
* @param[in] $opts array List of global available options
|
|
*
|
|
* @retval array List of available options for the word to autocomplete
|
|
**/
|
|
public static function cli_my_custom_cli_cmd_autocompleter($command_args, $comp_word_num, $comp_word, $opts) {
|
|
$opts = array_merge($opts, array ('-f', '--force'));
|
|
|
|
// Handle positional args
|
|
$objType = null;
|
|
$objType_arg_num = null;
|
|
$dn = null;
|
|
$dn_arg_num = null;
|
|
for ($i=0; $i < count($command_args); $i++) {
|
|
if (!in_array($command_args[$i], $opts)) {
|
|
// If object type not defined
|
|
if (is_null($objType)) {
|
|
// Defined it
|
|
$objType = $command_args[$i];
|
|
LScli :: unquote_word($objType);
|
|
$objType_arg_num = $i;
|
|
|
|
// Check object type exists
|
|
$objTypes = LScli :: autocomplete_LSobject_types($objType);
|
|
|
|
// Load it if exist and not trying to complete it
|
|
if (in_array($objType, $objTypes) && $i != $comp_word_num) {
|
|
LSsession :: loadLSobject($objType, false);
|
|
}
|
|
}
|
|
elseif (is_null($dn)) {
|
|
$dn = $command_args[$i];
|
|
LScli :: unquote_word($dn);
|
|
$dn_arg_num = $i;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If objType not already choiced (or currently autocomplete), add LSobject types to available options
|
|
if (!$objType || $objType_arg_num == $comp_word_num)
|
|
$opts = array_merge($opts, LScli :: autocomplete_LSobject_types($comp_word));
|
|
|
|
// If dn not alreay choiced (or currently autocomplete), try autocomplete it
|
|
elseif (!$dn || $dn_arg_num == $comp_word_num)
|
|
$opts = array_merge($opts, LScli :: autocomplete_LSobject_dn($objType, $comp_word));
|
|
|
|
return LScli :: autocomplete_opts($opts, $comp_word);
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</sect2>
|
|
|
|
</sect1>
|
|
|
|
<sect1 id="contrib-LSformElements">
|
|
<title>LSformElements</title>
|
|
|
|
<para>Les &LSformElements; sont les types de champs de formulaire supportés par l'application.</para>
|
|
<para>Pour chaque type implémenté, on devra trouver :
|
|
<itemizedlist>
|
|
<listitem><simpara>Une classe PHP dérivée de la classe <literal>LSattr_html</literal> et devant s'appeler
|
|
<literal>LSattr_html_[nom du type d'attribut HTML]</literal>. Dans celle-ci, il devra être défini à minima la variable de classe
|
|
<literal>LSformElement_type</literal> permettant de référencer le type d'&LSformElement; à utiliser ;</simpara>
|
|
</listitem>
|
|
<listitem><para>Une classe PHP dérivée de la classe <literal>LSformElement</literal> et devant s'appeler
|
|
<literal>LSformElement_[nom du type d'LSformElement]</literal>. Cette classe implémentera tout ce qui concerne l'affichage du champ
|
|
dans le formulaire et le traitement d'une valeur retournée par ce dernier. Cela concerne notamment les méthodes suivantes :
|
|
<variablelist>
|
|
|
|
<varlistentry>
|
|
<term>getDisplay()</term>
|
|
<listitem>
|
|
<simpara>Retourne les informations d'affichage du champ dans un formulaire sous la forme d'un tableau <emphasis>(implémentation
|
|
obligatoire, pas de méthode par défaut)</emphasis>. Il sera possible de s'appuyer sur la méthode <literal>getLabelInfos()</literal>
|
|
permettant de générer et récupérer tout ce qui concerne le label du champ du formulaire. Il faudra cependant à minima fournir
|
|
également la clé <literal>html</literal> dans le tableau retourné qui devra contenir le bout de code HTML correspondant au champ
|
|
du formulaire. Communément, ce code HTML est généré en appelant la méthode <literal>fetchTemplate()</literal>.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>fetchTemplate()</term>
|
|
<listitem>
|
|
<simpara>Retourne le code HTML du champ dans le formulaire. L'implémentation de cette méthode est facultative et par défaut, cette
|
|
méthode utilisera la variable de classe <literal>$template</literal> pour connaître le fichier de template à utiliser. Ce fichier
|
|
de template permettra la génération de la liste de tous les champs associés à chacune des valeurs de l'attribut. Individuellement,
|
|
le champ d'une des valeurs de l'attribut est généré à l'aide du fichier de template référencé dans la variable de class
|
|
<literal>$fieldTemplate</literal>.</simpara>
|
|
<note><simpara>La variable de classe <literal>$fieldTemplate</literal> est également utilisée par la méthode
|
|
<literal>LSformElement :: getEmptyField()</literal> qui sert à générer le code HTML d'un champ du formulaire pour une nouvelle
|
|
valeur de l'attribut. Cette méthode est notamment utilisée lorsque l'on clique sur le bouton permettant d'ajouter une valeur à
|
|
un champ du formulaire.</simpara></note>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>getPostData()</term>
|
|
<listitem>
|
|
<simpara>Récupère dans les données postées par le formulaire, celle concernant ce champ. Cette méthode devra potentiellement
|
|
traiter l'ensemble des valeurs de l'attribut envoyées par le formulaire et les définir dans le tableau passé en référence en tant
|
|
que premier argument, les valeurs de l'attribut. L'implémentation de cette méthode est facultative et par défaut, un tableau de
|
|
valeurs portant le nom de l'attribut LDAP correspondant sera récupérée comme valeur de l'attribut.</simpara>
|
|
<note><simpara>Pour plus d'informations sur le rôle et fonctionnement de cette méthode, référer à la méthode par défaut, définie
|
|
dans la classe PHP parente <literal>LSformElement</literal>.</simpara></note>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>setValueFromPostData()</term>
|
|
<listitem>
|
|
<simpara>Définit les valeurs de l'attribut à partir des données reçues du formulaire (et récupérées par la méthode
|
|
<literal>getPostData</literal>). L'implémentation de cette méthode est facultative et par défaut, aucune transformation ne sera
|
|
faites à cette étape sur les données récupérées depuis le formulaire. Implémenter cette méthode pourra cependant se révéler utile
|
|
en cas de champs de formulaire complexe (attribut composite par exemple).</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>autocomplete_attr_values()</term>
|
|
<listitem>
|
|
<simpara>Génère de la liste des valeurs possibles de l'attribut dans un contexte <emphasis>CLI</emphasis>.</simpara>
|
|
<note><simpara>Pour plus d'informations sur le rôle et fonctionnement de cette méthode, référer aux commentaires de la méthode par
|
|
défaut, définie dans la classe PHP parente <literal>LSformElement</literal>. Vous pouvez également vous inspirer des exemples
|
|
d'implémentations fournies avec les autres type d'&LSformElement;.</simpara></note>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
</para></listitem>
|
|
<listitem><simpara>Un (ou plusieurs) fichier template pour la génération du code HTML du champ du formulaire. Communément, le fichier
|
|
<literal>LSformElement.tpl</literal> est utilisé pour générer la structure de la liste des champs correspondant aux différentes valeurs
|
|
de l'attribut. Ce template utilise une variable <literal>$fieldTemplate</literal> pour définir quel fichier template devra être utilisé
|
|
pour générer le code HTML de chaque champ associés à une valeur. C'est ce second fichier de template qui est en général à fournir à
|
|
minima avec votre &LSformElement;.</simpara></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<note><simpara>Il peut être utile d'étendre un type d'&LSformElement; existant pour faciliter l'implémentation d'un nouveau type. Pour
|
|
cela, vous devez utiliser l'héritage de classe PHP en faisant dériver vos nouvelles classes des classes du &LSformElement; dont vous vous
|
|
inspirer, plutôt que les classes génériques. Vous pouvez prendre exemple sur le type d'&LSformElement; <literal>pre</literal> qui s'inspire
|
|
du type <literal>textarea</literal>, ou encore du type <literal>url</literal> dérivé du type <literal>text</literal>.</simpara></note>
|
|
</sect1>
|
|
|
|
<sect1 id="contrib-LSformRules">
|
|
<title>LSformRules</title>
|
|
|
|
<para>Les &LSformRules; sont les règles syntaxiques applicables aux champs des formulaires. Ces règles serviront à s'assurer que les
|
|
valeurs des champs récupérées des formulaires sont syntaxiquement correctes. Elles seront configurables via le paramètre
|
|
<literal>check_data</literal> des attributs des &LSobjects;.</para>
|
|
|
|
<para>Pour chaque type implémenté, on trouvera une classe PHP dérivée de la classe <literal>LSformRule</literal> et devant s'appeler
|
|
<literal>LSattr_rule_[nom du type]</literal>. Dans celle-ci, il devra être défini la méthode statique <literal>validate()</literal> qui
|
|
implémentera le contrôle syntaxique. Cette méthode prendra en paramètres :
|
|
<variablelist>
|
|
|
|
<varlistentry>
|
|
<term>$value</term>
|
|
<listitem>
|
|
<simpara>La valeur à tester.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>$options</term>
|
|
<listitem>
|
|
<simpara>Un tableau des options définies dans la configuration pour ce contrôle syntaxique.</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>$formElement</term>
|
|
<listitem>
|
|
<simpara>Une référence au champ du formulaire (objet &LSformElement;).</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
</para>
|
|
<para>Cette méthode devra retourner <literal>True</literal> ou <literal>False</literal> si la valeur testée est respectivement valide ou
|
|
invalide. Elle pourra également déclencher une exception <literal>LSformRuleException</literal> qui lui permettra de donner des messages
|
|
d'erreurs elle-même sur le(s) problème(s) detecté(s) durant l'analyse de la valeur passée. Le constructeur de ce type d'exception prend
|
|
en tant que premier paramètre un tableau de messages d'erreurs (ou un simple message d'erreur) qui seront retournés à l'utilisateur.</para>
|
|
|
|
<note><simpara>Par défaut, les valeurs de l'attribut sont testées une à une via la méthode <literal>validate()</literal>. Cependant, il est
|
|
possible d'implémenter une méthode de validation pour toutes les valeurs de l'attribut en une seule fois en affectant la valeur <literal>
|
|
false</literal> à la constante de classe <literal>validate_one_by_one</literal>. Dans ce cas, l'ensemble des valeurs de l'attribut seront
|
|
passées via le paramètre <literal>$value</literal> à la méthode <literal>validate()</literal> (sous la forme d'un tableau). Cela pourra par
|
|
exemple être utile pour implémenter une validation de la cohérence des valeurs les unes vis à vis des autres (unicité, nombre maximum de
|
|
valeurs, …).</simpara></note>
|
|
</sect1>
|
|
|
|
</chapter>
|