mirror of
https://gitlab.easter-eggs.com/ee/ldapsaisie.git
synced 2024-12-23 08:53:47 +01:00
Improve doc about custom CLI commands
This commit is contained in:
parent
2e0338e678
commit
5e17a8ec81
1 changed files with 169 additions and 79 deletions
|
@ -1,5 +1,7 @@
|
|||
# Les commandes *CLI* personnalisées
|
||||
|
||||
## Introduction
|
||||
|
||||
Les [LSaddons](../../conf/index.md#configuration-des-lsaddons) peuvent fournir des commandes *CLI*
|
||||
personnalisées qui seront accessibles via la commande `ldapsaisie` fournie avec l'application. Cela
|
||||
peut, par exemple, vous permettre de rendre accessible en ligne de commandes une procédure
|
||||
|
@ -8,81 +10,152 @@ exécutant cette procédure régulièrement.
|
|||
|
||||
Pour mettre en place une telle commande *CLI* personnalisée, il est nécessaire de :
|
||||
|
||||
- Déclarer cette vue dans la fonction `LSaddon_[addon]_support` de l'addon à l'aide de la méthode
|
||||
`LScli :: add_command()` ;
|
||||
- Déclarer cette commande *CLI* personnalisée dans la fonction `LSaddon_[addon]_support` de l'addon
|
||||
à l'aide de la méthode `LScli::add_command()` ;
|
||||
|
||||
- Déclarer la fonction implémentant cette commande *CLI* 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 `True` ou `False` en cas de succès/d'erreur d'exécution de la commande. Cette valeur de
|
||||
retour influencera le code retourné par la commande : `0` en cas de succès, `1` en cas d'erreur.
|
||||
retournera `True` ou `False` en cas de succès/d'erreur d'exécution de la commande. Cette valeur
|
||||
de retour influencera le code retourné par la commande : `0` en cas de succès, `1` en cas
|
||||
d'erreur.
|
||||
|
||||
- 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.
|
||||
permettant l'autocomplétion des arguments acceptés par la commande. Pour plus d'informations à ce
|
||||
propos, reportez-vous à la [section dédiée](#auto-completion).
|
||||
|
||||
Cette méthode recevra en paramètre :
|
||||
## Outils à votre disposition
|
||||
|
||||
- `$command_args`
|
||||
Pour vous aider dans l'écriture de vos méthodes *CLI*, la classe `LScli` offre des méthodes
|
||||
pour les tâches les plus courantes :
|
||||
|
||||
Un tableau des arguments déjà reçus par la commande.
|
||||
- `LScli::usage($error, ...$extra_args)`
|
||||
|
||||
- `$comp_word_num`
|
||||
Affichage du message d'aide de votre commande avant arrêt. Un message d'erreur peut également
|
||||
être spécifié avec d'éventuels arguments supplémentaires pour le composer (via `sprintf()`). Si un
|
||||
message d'erreur est fourni, le code de retour de la commande sera `1` et à défaut, `0`.
|
||||
|
||||
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 `$command_args` 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.
|
||||
- `LScli::need_ldap_con()`
|
||||
|
||||
- `$comp_word`
|
||||
Permet d'établir la connexion à l'annuaire LDAP (si ce n'est pas déjà fait).
|
||||
|
||||
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.
|
||||
- `LScli::run_external_command($command, $data_stdin=null, $escape_command_args=true, $cwd=null)` :
|
||||
|
||||
- `$opts`
|
||||
Permet d'exécuter une commande externe et de récupérer un tableau contenant le code de
|
||||
retour de la commande exécutée, le contenu affiché sur la sortie standard et le contenu
|
||||
affiché sur la sortie d'erreur.
|
||||
|
||||
Un tableau des potentiels arguments globaux acceptés par *LScli* dans le contexte actuel (par
|
||||
exemple, `-d` ou `--debug` 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).
|
||||
La commande à exécuter peut être passée sous la forme d'une chaîne de caractères ou d'un
|
||||
tableau de chaînes de caractères correspondant à la commande et ses arguments. Par défaut,
|
||||
les caractères spéciaux contenus dans les paramètres passés à la commande seront
|
||||
"échappés", mais il est possible de désactiver cela via le paramètre `$escape_command_args`.
|
||||
|
||||
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.
|
||||
Il est possible de fournir des données à passer à la commande via son entrée standard via
|
||||
le paramètre `$data_stdin`.
|
||||
|
||||
!!! note
|
||||
Enfin, il est possible de spécifier l'emplacement du dossier courant d'exécution de la
|
||||
commande via le paramètre `$cwd`.
|
||||
|
||||
Pour vous aider dans l'écrire d'une telle méthode d'autocomplétion, des méthodes statiques
|
||||
sont fournies par la classe `LScli` pour les autocomplétions les plus courantes :
|
||||
- `LScli::confirm($question=null)`
|
||||
|
||||
- `LScli :: autocomplete_class_name()` : Autocomplétion du nom d'une classe PHP.
|
||||
Permet de demander à l'utilisateur de confirmer quelque chose. La question à poser peut être
|
||||
passée en paramètre et cette méthode retournera `true` ou `false` en fonction du choix de
|
||||
l'utilisateur.
|
||||
|
||||
- `LScli :: autocomplete_addon_name()` : Autocomplétion du nom d'un
|
||||
[LSaddon](../../conf/index.md#configuration-des-lsaddons).
|
||||
- `LScli::parse_arg_value($value, $custom_values=null)`
|
||||
|
||||
- `LScli :: autocomplete_int()` : Autocomplétion d'un nombre entier.
|
||||
Permet d'interpréter la valeur d'un argument fourni par l'utilisateur. Celui-ci pourra spécifier
|
||||
le type de l'argument en préfixant l'argument de son type entre crochets (exemple : `[bool]1`,
|
||||
types supportés : `string`, `str`, `bool`, `boolean`, `int`, `integer`, `float`, `array`) et à
|
||||
défaut, la valeur sera analysée comme une valeur JSON permettant de passer des paramètres
|
||||
complexes à vos méthodes (un tableau associatif arborescent par exemple).
|
||||
|
||||
- `LScli :: autocomplete_LSobject_types()` : Autocomplétion du nom d'un type
|
||||
d'[LSobject](../../conf/index.md#configuration-lsobject).
|
||||
Des valeurs particulières seront également analysées de manières prédéfinies si elles ne
|
||||
sont pas préfixées d'un type particulier. C'est le cas par défaut des chaînes de
|
||||
caractères `true` et `false` qui seront comprises comme des booléens et `null` qui sera
|
||||
compris comme la valeur `NULL` au sens PHP.
|
||||
|
||||
- `LScli :: autocomplete_LSobject_dn()` : Autocomplétion du DN d'un type précis
|
||||
d'[LSobject](../../conf/index.md#configuration-lsobject) de l'annuaire.
|
||||
Vous pouvez également spécifier vos propres valeurs particulières via l'argument
|
||||
`$custom_values` sous la forme d'un tableau associatif dont les clés sont les valeurs
|
||||
particulières fournies par l'utilisateur et la valeur correspondante, la valeur au sens
|
||||
_PHP_.
|
||||
|
||||
- `LScli :: autocomplete_LSobject_attr_name()` : Autocomplétion du nom d'un attribut précis
|
||||
pour un type d'[LSobject](../../conf/index.md#configuration-lsobject) de l'annuaire.
|
||||
__Important :__ l'analyse des valeurs particulières sera faite en mettant
|
||||
__en minuscule__ la valeur fournie par l'utilisateur. Il est donc important que vos
|
||||
valeurs particulières spécifiées via l'argument `$custom_values` soient toutes en
|
||||
minuscule.
|
||||
|
||||
- `LScli :: autocomplete_LSobject_ioFormat()` : Autocomplétion du nom d'un
|
||||
[ioFormat](../../conf/LSobject/ioFormat.md#ioformat) pour un type
|
||||
d'[LSobject](../../conf/index.md#configuration-lsobject) de l'annuaire.
|
||||
## Auto-complétion
|
||||
|
||||
- `LScli :: autocomplete_LSform_name()` : Autocomplétion du nom d'un formulaire de
|
||||
l'application.
|
||||
Lors de la déclaration de votre commande CLI personnalisée à l'aide de la méthode
|
||||
`LScli::add_command()`, vous avez la possibilité de spécifier une fonction permettant
|
||||
l'autocomplétion des arguments acceptés par celle-ci.
|
||||
|
||||
Par ailleurs, la méthode `LScli :: autocomplete_opts()` 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 `$comp_word`). 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.
|
||||
Cette fonction recevra en paramètre :
|
||||
|
||||
- `$command_args`
|
||||
|
||||
Un tableau des arguments déjà reçus par la commande.
|
||||
|
||||
- `$comp_word_num`
|
||||
|
||||
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 `$command_args` 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 autres arguments que pourrait accepter cette commande.
|
||||
|
||||
- `$comp_word`
|
||||
|
||||
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.
|
||||
|
||||
- `$opts`
|
||||
|
||||
Un tableau des potentiels arguments globaux acceptés par *LScli* dans le contexte actuel (par
|
||||
exemple, `-d` ou `--debug` pour l'activation du mode debug). La réponse de cette fonction devra
|
||||
inclure ces potentiels arguments si le contexte d'autocomplétion s'y prête (nouvel argument par
|
||||
exemple).
|
||||
|
||||
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.
|
||||
|
||||
!!! note
|
||||
|
||||
Pour vous aider dans l'écriture d'une telle méthode d'autocomplétion, des méthodes statiques
|
||||
sont fournies par la classe `LScli` pour les autocomplétions les plus courantes :
|
||||
|
||||
- `LScli::autocomplete_class_name()` : Autocomplétion du nom d'une classe PHP.
|
||||
|
||||
- `LScli::autocomplete_addon_name()` : Autocomplétion du nom d'un
|
||||
[LSaddon](../../conf/index.md#configuration-des-lsaddons).
|
||||
|
||||
- `LScli::autocomplete_int()` : Autocomplétion d'un nombre entier.
|
||||
|
||||
- `LScli::autocomplete_LSobject_types()` : Autocomplétion du nom d'un type
|
||||
d'[LSobject](../../conf/index.md#configuration-lsobject).
|
||||
|
||||
- `LScli::autocomplete_LSobject_dn()` : Autocomplétion du DN d'un type précis
|
||||
d'[LSobject](../../conf/index.md#configuration-lsobject) de l'annuaire.
|
||||
|
||||
- `LScli::autocomplete_LSobject_attr_name()` : Autocomplétion du nom d'un attribut précis
|
||||
pour un type d'[LSobject](../../conf/index.md#configuration-lsobject) de l'annuaire.
|
||||
|
||||
- `LScli::autocomplete_LSobject_ioFormat()` : Autocomplétion du nom d'un
|
||||
[ioFormat](../../conf/LSobject/ioFormat.md#ioformat) pour un type
|
||||
d'[LSobject](../../conf/index.md#configuration-lsobject) de l'annuaire.
|
||||
|
||||
- `LScli::autocomplete_LSform_name()` : Autocomplétion du nom d'un formulaire de
|
||||
l'application.
|
||||
|
||||
Par ailleurs, la méthode `LScli::autocomplete_opts()` 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 `$comp_word`). 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.
|
||||
|
||||
## Exemple d'implémentation
|
||||
|
||||
Pour implémenter une telle commande *CLI* personnalisée, vous pouvez vous inspirer de l'exemple
|
||||
fourni ci-dessous ou encore des commandes *CLI* fournies par les autres
|
||||
|
@ -90,30 +163,38 @@ fourni ci-dessous ou encore des commandes *CLI* fournies par les autres
|
|||
|
||||
**Structure du fichier includes/addons/LSaddons.[addon name].php :**
|
||||
|
||||
```
|
||||
```php
|
||||
<?php
|
||||
function LSaddon_myaddon_support() {
|
||||
|
||||
$retval=true;
|
||||
|
||||
// Some check
|
||||
# Some other checks need to verify your addon support
|
||||
|
||||
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)
|
||||
LScli::add_command(
|
||||
# The CLI command name (required)
|
||||
'my_custom_cli_cmd',
|
||||
# The CLI command handler (must be callable, required)
|
||||
'cli_my_custom_cli_cmd',
|
||||
# A short description of what this command does (required)
|
||||
'My custom CLI command',
|
||||
# A short list of commands available arguments show in usage message
|
||||
# (optional, default: false)
|
||||
'[arg1] [arg2] [...]',
|
||||
# A long description of what this command does
|
||||
# (optional, default: false)
|
||||
'This command permit to ...',
|
||||
# Permit to define if this command need connection to LDAP server
|
||||
# (optional, default: true)
|
||||
true,
|
||||
# Callable of the CLI command arguments autocompleter
|
||||
# (optional, default: null)
|
||||
'cli_my_custom_cli_cmd_autocompleter',
|
||||
# Allow override if a command already exists with the same name
|
||||
# (optional, default: null)
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -157,18 +238,18 @@ function cli_my_custom_cli_cmd($command_args) {
|
|||
$dn = $arg;
|
||||
}
|
||||
else
|
||||
LScli :: usage("Invalid $arg parameter.");
|
||||
LScli::usage("Invalid $arg parameter.");
|
||||
}
|
||||
|
||||
if (is_null($objType) || is_null($dn))
|
||||
LScli :: usage('You must provide LSobject type and DN.');
|
||||
LScli::usage('You must provide LSobject type and DN.');
|
||||
|
||||
if (!LSsession :: loadLSobject($objType))
|
||||
if (!LSsession::loadLSobject($objType))
|
||||
return false;
|
||||
|
||||
$obj = new $objType();
|
||||
if (!$obj->loadData($dn)) {
|
||||
self :: log_fatal("Fail to load object $dn data from LDAP");
|
||||
self::log_fatal("Fail to load object $dn data from LDAP");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -188,7 +269,9 @@ function cli_my_custom_cli_cmd($command_args) {
|
|||
*
|
||||
* @return array<string> 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) {
|
||||
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
|
||||
|
@ -202,33 +285,40 @@ public static function cli_my_custom_cli_cmd_autocompleter($command_args, $comp_
|
|||
if (is_null($objType)) {
|
||||
// Defined it
|
||||
$objType = $command_args[$i];
|
||||
LScli :: unquote_word($objType);
|
||||
LScli::unquote_word($objType);
|
||||
$objType_arg_num = $i;
|
||||
|
||||
// Check object type exists
|
||||
$objTypes = LScli :: autocomplete_LSobject_types($objType);
|
||||
$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);
|
||||
LSsession::loadLSobject($objType, false);
|
||||
}
|
||||
}
|
||||
elseif (is_null($dn)) {
|
||||
$dn = $command_args[$i];
|
||||
LScli :: unquote_word($dn);
|
||||
LScli::unquote_word($dn);
|
||||
$dn_arg_num = $i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If objType not already choiced (or currently autocomplete), add LSobject types to available options
|
||||
// If objType not already chosen (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));
|
||||
$opts = array_merge(
|
||||
$opts,
|
||||
LScli::autocomplete_LSobject_types($comp_word)
|
||||
);
|
||||
|
||||
// If dn not alreay choiced (or currently autocomplete), try autocomplete it
|
||||
// If dn not already chosen (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));
|
||||
$opts = array_merge(
|
||||
$opts,
|
||||
LScli::autocomplete_LSobject_dn($objType, $comp_word)
|
||||
);
|
||||
|
||||
return LScli :: autocomplete_opts($opts, $comp_word);
|
||||
return LScli::autocomplete_opts($opts, $comp_word);
|
||||
}
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue