Browse Source

Et voilà… On liste TOUTES les fonctions des fichiers .php sauf celles dans tmp/ et local/.

Ce code doit être amélioré car on solicite bcp de le disque. Il faudrait faire un json ou un xml listant toutes les fonctions et on parcourera son contenu. Avantage => mise en cache. Inconvénient => mise en cache. ;-)
svn/root/tags/plugins/dev/0.3.9
teddy.spip@gmail.com 9 years ago
parent
commit
890f9b5724
  1. 12
      .gitattributes
  2. 276
      dev_fonctions.php
  3. 23
      formulaires/lister_fonctions_completes.html
  4. 6
      formulaires/lister_fonctions_completes.php
  5. 0
      formulaires/lister_fonctions_utilisateur.html
  6. 25
      formulaires/lister_fonctions_utilisateur.php
  7. 4
      lang/fonction_fr.php
  8. 9
      paquet.xml
  9. 2
      prive/squelettes/contenu/source_constantes.html
  10. 45
      prive/squelettes/contenu/source_fonctions_completes.html
  11. 6
      prive/squelettes/contenu/source_fonctions_utilisateur.html
  12. 2
      prive/squelettes/contenu/source_images.html
  13. 2
      prive/squelettes/navigation/source_fonctions.html
  14. 2
      prive/squelettes/navigation/source_fonctions_completes.html
  15. 2
      prive/squelettes/navigation/source_fonctions_utilisateur.html

12
.gitattributes vendored

@ -6,8 +6,10 @@ formulaires/charter.php -text
formulaires/charter_chantier_en_cours.html -text
formulaires/lister_constantes.html -text
formulaires/lister_constantes.php -text
formulaires/lister_fonctions.html -text
formulaires/lister_fonctions.php -text
formulaires/lister_fonctions_completes.html -text
formulaires/lister_fonctions_completes.php -text
formulaires/lister_fonctions_utilisateur.html -text
formulaires/lister_fonctions_utilisateur.php -text
formulaires/lister_images.html -text
formulaires/lister_images.php -text
inc/minipres.php -text
@ -38,12 +40,14 @@ prive/squelettes/contenu/charte_listes.html -text
prive/squelettes/contenu/charte_php.html -text
prive/squelettes/contenu/charte_typo.html -text
prive/squelettes/contenu/source_constantes.html -text
prive/squelettes/contenu/source_fonctions.html -text
prive/squelettes/contenu/source_fonctions_completes.html -text
prive/squelettes/contenu/source_fonctions_utilisateur.html -text
prive/squelettes/contenu/source_images.html -text
prive/squelettes/inclure/fonction_info_ligne.html -text
prive/squelettes/inclure/image_info_ligne.html -text
prive/squelettes/navigation/source_constantes.html -text
prive/squelettes/navigation/source_fonctions.html -text
prive/squelettes/navigation/source_fonctions_completes.html -text
prive/squelettes/navigation/source_fonctions_utilisateur.html -text
prive/squelettes/navigation/source_images.html -text
prive/squelettes/top/charte.html -text
prive/squelettes/top/charte_boites.html -text

276
dev_fonctions.php

@ -4,37 +4,36 @@ if (!defined('_ECRIRE_INC_VERSION')) return;
/**
* Une fonction récursive pour joliment afficher #ENV, #GET, #SESSION...
* en squelette : [(#ENV|bel_env)], [(#GET|bel_env)], [(#SESSION|bel_env)]
* ou encore [(#ARRAY{0,1, a,#SESSION, 1,#ARRAY{x,y}}|bel_env)]
* en squelette : [(#ENV|bel_env)], [(#GET|bel_env)], [(#SESSION|bel_env)]
* ou encore [(#ARRAY{0,1, a,#SESSION, 1,#ARRAY{x,y}}|bel_env)]
*
* @param string|array $env
* si une string est passée elle doit être le serialize d'un array
* si une string est passée elle doit être le serialize d'un array
*
* @return string
* une chaîne html affichant une <table>
* une chaîne html affichant une <table>
**/
function bel_env($env) {
$env = str_replace(array('&quot;', '&#039;'), array('"', '\''), $env);
if (is_array($env_tab = @unserialize($env))) {
$env = $env_tab;
}
if (!is_array($env)) {
return '';
}
$style = " style='border:1px solid #ddd;'";
$res = "<table style='border-collapse:collapse;'>\n";
foreach ($env as $nom => $val) {
if (is_array($val) || is_array(@unserialize($val))) {
$val = bel_env($val);
}
else {
$val = entites_html($val);
}
$res .= "<tr>\n<td$style><strong>". entites_html($nom).
"&nbsp;:&nbsp;</strong></td><td$style>" .$val. "</td>\n</tr>\n";
}
$res .= "</table>";
return $res;
$env = str_replace(array('&quot;', '&#039;'), array('"', '\''), $env);
if (is_array($env_tab = @unserialize($env))) {
$env = $env_tab;
}
if (!is_array($env)) {
return '';
}
$style = " style='border:1px solid #ddd;'";
$res = "<table style='border-collapse:collapse;'>\n";
foreach ($env as $nom => $val) {
if (is_array($val) || is_array(@unserialize($val))) {
$val = bel_env($val);
} else {
$val = entites_html($val);
}
$res .= "<tr>\n<td$style><strong>". entites_html($nom).
"&nbsp;:&nbsp;</strong></td><td$style>" .$val. "</td>\n</tr>\n";
}
$res .= "</table>";
return $res;
}
/**
@ -48,30 +47,30 @@ function bel_env($env) {
* Si un préfixe est identifié, on listera toutes les fonctions avec ce préfixe.
*/
function lister_fonctions ($prefixe = null) {
$fonctions = get_defined_functions();
$fonctions = get_defined_functions();
$fonctions_user = $fonctions["user"];
sort($fonctions_user);
$fonctions_user = $fonctions["user"];
sort($fonctions_user);
foreach ($fonctions_user as $value) {
if ($fonction = preg_split('/_/', $value, -1, PREG_SPLIT_NO_EMPTY)) {
$fonctions_user[$fonction[0]][] = $value;
if (($key = array_search($value, $fonctions_user)) !== false) {
unset($fonctions_user[$key]);
}
}
}
ksort($fonctions_user);
foreach ($fonctions_user as $value) {
if ($fonction = preg_split('/_/', $value, -1, PREG_SPLIT_NO_EMPTY)) {
$fonctions_user[$fonction[0]][] = $value;
if (($key = array_search($value, $fonctions_user)) !== false) {
unset($fonctions_user[$key]);
}
}
}
ksort($fonctions_user);
$resultat = $fonctions_user;
$resultat = $fonctions_user;
if ($prefixe) {
// On pourrait faire aussi un contrôle avec array_key_exists()
// Mais ça risque de fausser le résultat attendu.
$resultat = $fonctions_user[$prefixe];
}
if ($prefixe) {
// On pourrait faire aussi un contrôle avec array_key_exists()
// Mais ça risque de fausser le résultat attendu.
$resultat = $fonctions_user[$prefixe];
}
return $resultat;
return $resultat;
}
@ -86,32 +85,32 @@ function lister_fonctions ($prefixe = null) {
* Si un préfixe est identifié, on listera toutes les constantes avec ce préfixe.
*/
function lister_constantes ($prefixe = null) {
$constantes = get_defined_constants(true);
$constantes = get_defined_constants(true);
$constantes_user = $constantes["user"];
$constantes_user = $constantes["user"];
foreach ($constantes_user as $key => $value) {
if ($constante = preg_split('/_/', $key, -1, PREG_SPLIT_NO_EMPTY)) {
if ($constante[0] == '_') {
$constantes_user[$constante[1]][$key] = $value;
} else {
$constantes_user[$constante[0]][$key] = $value;
}
unset($constantes_user[$key]);
}
}
foreach ($constantes_user as $key => $value) {
if ($constante = preg_split('/_/', $key, -1, PREG_SPLIT_NO_EMPTY)) {
if ($constante[0] == '_') {
$constantes_user[$constante[1]][$key] = $value;
} else {
$constantes_user[$constante[0]][$key] = $value;
}
unset($constantes_user[$key]);
}
}
ksort($constantes_user);
ksort($constantes_user);
$resultat = $constantes_user;
$resultat = $constantes_user;
if ($prefixe) {
// On pourrait faire aussi un contrôle avec array_key_exists()
// Mais ça risque de fausser le résultat attendu.
$resultat = $constantes_user[$prefixe];
}
if ($prefixe) {
// On pourrait faire aussi un contrôle avec array_key_exists()
// Mais ça risque de fausser le résultat attendu.
$resultat = $constantes_user[$prefixe];
}
return $resultat;
return $resultat;
}
@ -126,36 +125,36 @@ function lister_constantes ($prefixe = null) {
* Si un préfixe est identifié, on listera toutes les images avec ce préfixe.
*/
function lister_images ($prefixe = null) {
$images = find_all_in_path("prive/themes/spip/images/", "\w.\w");
foreach ($images as $key => $value) {
// On ne prend que les images issues des thèmes.
if (est_image($value)) {
if ($image = preg_split('/-/', $key, -1, PREG_SPLIT_NO_EMPTY)) {
if (count($image) > 1) {
$images[$image[0]][] = $value;
} else {
$image = explode('.', $image[0]);
$images[$image[0]][] = $value;
}
unset($images[$key]);
}
} else {
// Si ce n'est pas une image, on l'enlève du tableau.
unset($images[$key]);
}
}
ksort($images);
$resultat = $images;
if ($prefixe) {
// On pourrait faire aussi un contrôle avec array_key_exists()
// Mais ça risque de fausser le résultat attendu.
$resultat = $images[$prefixe];
}
return $resultat;
$images = find_all_in_path("prive/themes/spip/images/", "\w.\w");
foreach ($images as $key => $value) {
// On ne prend que les images issues des thèmes.
if (est_image($value)) {
if ($image = preg_split('/-/', $key, -1, PREG_SPLIT_NO_EMPTY)) {
if (count($image) > 1) {
$images[$image[0]][] = $value;
} else {
$image = explode('.', $image[0]);
$images[$image[0]][] = $value;
}
unset($images[$key]);
}
} else {
// Si ce n'est pas une image, on l'enlève du tableau.
unset($images[$key]);
}
}
ksort($images);
$resultat = $images;
if ($prefixe) {
// On pourrait faire aussi un contrôle avec array_key_exists()
// Mais ça risque de fausser le résultat attendu.
$resultat = $images[$prefixe];
}
return $resultat;
}
@ -192,18 +191,87 @@ function est_image ($fichier)
*/
function fonction_fichier ($fonction = null) {
if ($fonction == null) {
return;
}
// On prépare le pattern pour ne pas avoir le chemin depuis les méandres du serveur d'hébergement.
$pattern_root = "/^" . preg_replace('/\//', '\/', $_SERVER['DOCUMENT_ROOT']) . "/";
if ($fonction == null) {
return;
}
// On prépare le pattern pour ne pas avoir le chemin depuis les méandres du serveur d'hébergement.
$pattern_root = "/^" . preg_replace('/\//', '\/', $_SERVER['DOCUMENT_ROOT']) . "/";
// API offerte par PHP 5.
$refFonction = new ReflectionFunction($fonction);
// API offerte par PHP 5.
$refFonction = new ReflectionFunction($fonction);
// On enlève le chemin 'root' pour ne garder que le chemin à la "racine" de notre site.
$filename = preg_replace($pattern_root, '', $refFonction->getFileName()) . ':' . $refFonction->getStartLine();
// On enlève le chemin 'root' pour ne garder que le chemin à la "racine" de notre site.
$filename = preg_replace($pattern_root, '', $refFonction->getFileName()) . '#L' . $refFonction->getStartLine();
return $filename;
}
function lister_fichiers_php ($dir = _DIR_RACINE) {
global $list;
$ffs = scandir($dir);
$exclu = preg_match('/(tmp|local)/', $dir);
foreach ($ffs as $ff) {
if ($ff != '.' and $ff != '..' and $ff != '.svn' and $exclu == false) {
if (strlen($ff) >= 5) {
if (substr($ff, -4) == '.php') {
if (substr($dir, -1) == '/') {
$list[] = $dir . $ff;
} else {
$list[] = $dir . '/' . $ff;
}
//echo dirname($ff) . $ff . "<br/>";
}
}
if (is_dir($dir . $ff)) {
lister_fichiers_php($dir . $ff);
} elseif (is_dir($dir . '/' . $ff)) {
lister_fichiers_php($dir . '/' . $ff);
}
}
}
return $list;
}
function lister_noms_fonctions ($fichier) {
$liste_fonctions = array();
$content = file_get_contents($fichier);
preg_match_all("/(function)([\s|\t]+)(\w+)/", $content, $fonctions);
foreach ($fonctions[3] as $fonction) {
$liste_fonctions[] = array('fichier' => $fichier, 'fonction' => $fonction);
}
return $liste_fonctions;
}
function lister_toutes_fonctions ($prefixe = null) {
$fichiers_php = lister_fichiers_php();
$fonctions_user = array();
foreach ($fichiers_php as $fichier) {
foreach (lister_noms_fonctions($fichier) as $value) {
$fonctions_user[] = $value;
}
}
natcasesort($fonctions_user);
foreach ($fonctions_user as $value) {
if ($fonction = preg_split('/_/', $value['fonction'], -1, PREG_SPLIT_NO_EMPTY)) {
$fonctions_user[$fonction[0]][] = $value;
if (($key = array_search($value, $fonctions_user)) !== false) {
unset($fonctions_user[$key]);
}
}
}
ksort($fonctions_user);
$resultat = $fonctions_user;
if ($prefixe) {
// On pourrait faire aussi un contrôle avec array_key_exists()
// Mais ça risque de fausser le résultat attendu.
$resultat = $fonctions_user[$prefixe];
}
return $filename;
return $resultat;
}
?>

23
formulaires/lister_fonctions_completes.html

@ -0,0 +1,23 @@
<div class="formulaire_spip formulaire_configurer formulaire_#FORM">
[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
<form action="#ENV{action}" method="post">
[(#ACTION_FORMULAIRE{#ENV{action}})]
[(#SELF|parametre_url{prefixe,''}|form_hidden)]
<ul>
<li>
<label for="champ_prefixe"><:fonction:label_prefixe_fonction:></label>
<select name="prefixe" id="champ_prefixe">
<option value=""><:fonction:tout_voir:></option>
<BOUCLE_lister (DATA) {source table, (#REM|lister_toutes_fonctions|array_keys)} {par valeur}>
<option value="#VALEUR" [(#ENV{prefixe}|=={#VALEUR}|oui)selected="selected"]>#VALEUR [((#VALEUR|lister_toutes_fonctions|count))]</option>
</BOUCLE_lister>
</select>
</li>
</ul>
<p class="boutons">
<input type="submit" class="submit" value="<:bouton_valider:>" />
</p>
</form>
</div>

6
formulaires/lister_fonctions.php → formulaires/lister_fonctions_completes.php

@ -2,7 +2,7 @@
if (!defined('_ECRIRE_INC_VERSION')) return;
function formulaires_liste_fonctions_charger_dist () {
function formulaires_liste_fonctions_completes_charger_dist () {
$valeurs = array();
$valeurs['prefixe'] = (_request('prefixe')) ? _request('prefixe') : '' ;
@ -10,13 +10,13 @@ function formulaires_liste_fonctions_charger_dist () {
return $valeurs;
}
function formulaires_liste_fonctions_verifier_dist () {
function formulaires_liste_fonctions_completes_verifier_dist () {
$erreurs = array();
return $erreurs;
}
function formulaires_liste_fonctions_traiter_dist () {
function formulaires_liste_fonctions_completes_traiter_dist () {
$res = array();
return $res;

0
formulaires/lister_fonctions.html → formulaires/lister_fonctions_utilisateur.html

25
formulaires/lister_fonctions_utilisateur.php

@ -0,0 +1,25 @@
<?php
if (!defined('_ECRIRE_INC_VERSION')) return;
function formulaires_liste_fonctions_utilisateur_charger_dist () {
$valeurs = array();
$valeurs['prefixe'] = (_request('prefixe')) ? _request('prefixe') : '' ;
return $valeurs;
}
function formulaires_liste_fonctions_utilisateur_verifier_dist () {
$erreurs = array();
return $erreurs;
}
function formulaires_liste_fonctions_utilisateur_traiter_dist () {
$res = array();
return $res;
}
?>

4
lang/fonction_fr.php

@ -29,9 +29,13 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
// T
'titre_onglet_constantes' => 'Les constantes',
'titre_onglet_fonctions' => 'Les fonctions',
'titre_onglet_fonctions_completes' => 'Toutes les fonctions',
'titre_onglet_fonctions_utilisateur' => 'Les fonctions chargées',
'titre_onglet_images' => 'Les images de thèmes',
'titre_page_constantes' => 'Lister les constantes',
'titre_page_fonctions' => 'Lister les fonctions',
'titre_page_fonctions_completes' => 'Lister toutes les fonctions',
'titre_page_fonctions_utilisateur' => 'Lister les fonctions chargées',
'titre_page_images' => 'Lister les images des thèmes de SPIP',
'tout_voir' => 'Tout voir',

9
paquet.xml

@ -13,7 +13,7 @@
<auteur>Collectif SPIP</auteur>
<menu nom="charte" titre="charter:titre_charte" parent="menu_squelette"/>
<menu nom="source_fonctions" titre="fonction:titre_onglet_fonctions" parent="menu_squelette" icone="images/fonctions-16.png"/>
<menu nom="source_fonctions_utilisateur" titre="fonction:titre_onglet_fonctions" parent="menu_squelette" icone="images/fonctions-16.png"/>
<onglet nom="charte" titre="charter:titre_charte" parent="charte" action="charte" />
<onglet nom="charte_icones" titre="charter:titre_icones" parent="charte" action="charte_icones" />
@ -22,7 +22,8 @@
<onglet nom="charte_listes" titre="charter:titre_listes" parent="charte" action="charte_listes" />
<onglet nom="charte_forms" titre="charter:titre_formulaires" parent="charte" action="charte_forms" />
<onglet nom="source_fonctions" titre="fonction:titre_onglet_fonctions" parent="source_fonctions" action="source_fonctions" />
<onglet nom="source_constantes" titre="fonction:titre_onglet_constantes" parent="source_fonctions" action="source_constantes" />
<onglet nom="source_images" titre="fonction:titre_onglet_images" parent="source_fonctions" action="source_images" />
<onglet nom="source_fonctions_utilisateur" titre="fonction:titre_onglet_fonctions_utilisateur" parent="source_fonctions_utilisateur" action="source_fonctions_utilisateur" />
<onglet nom="source_fonctions_completes" titre="fonction:titre_onglet_fonctions_completes" parent="source_fonctions_utilisateur" action="source_fonctions_completes" />
<onglet nom="source_constantes" titre="fonction:titre_onglet_constantes" parent="source_fonctions_utilisateur" action="source_constantes" />
<onglet nom="source_images" titre="fonction:titre_onglet_images" parent="source_fonctions_utilisateur" action="source_images" />
</paquet>

2
prive/squelettes/contenu/source_constantes.html

@ -1,4 +1,4 @@
[(#VAL{source_fonctions}|barre_onglets{source_constantes})]
[(#VAL{source_fonctions_utilisateur}|barre_onglets{source_constantes})]
<h1><:fonction:titre_page_constantes:></h1>

45
prive/squelettes/contenu/source_fonctions_completes.html

@ -0,0 +1,45 @@
[(#VAL{source_fonctions_utilisateur}|barre_onglets{source_fonctions_completes})]
<h1><:fonction:titre_page_fonctions_completes:></h1>
<B_fonctions>
<div class="liste-objets fonctions">
[<h3>(#ENV{titre})</h3>]
<table class="spip liste">
[<caption>[(#ENV{prefixe,''})&nbsp;: ](#GRAND_TOTAL|singulier_ou_pluriel{fonction:une_fonction,fonction:des_fonctions})</caption>]
<thead>
<tr class="first_row">
<th class="fonction principale"><:fonction:info_fonction:></th>
<th class="filename secondaire"><:fonction:info_filename:></th>
<th class="surcharge secondaire"><:fonction:info_surchargeable:></th>
</tr>
</thead>
<tbody>
<BOUCLE_fonctions (DATA) {source table, (#VAL{''}|lister_toutes_fonctions)}>
<BOUCLE_prefixe (DATA) {source table, #VALEUR} {si #VALEUR|is_array}>
[<tr class="prefixe">
<td colspan="3"><h3>(#_fonctions:CLE|unique)</h3></td>
</tr>]
<tr class="[(#ENV{class})]">
<td class="fonction principale">[(#VALEUR{fonction}|replace{'_','_<wbr/>'})] [(#VALEUR{fichier}|match{'/plugins/'}|non)<a href="http://code.spip.net/@#VALEUR{fonction}" target="_blank" class="aide">[(#CHEMIN_IMAGE{aide-16.png}|balise_img|inserer_attribut{title,<:titre_image_aide:>})]</a>]</td>
<td class="filename secondaire">[(#VALEUR{fichier}|replace{(/|_),$1<wbr/>})]</td>
<td class="surcharge secondaire">[(#VALEUR{fonction}|match{(_dist)$}|?{[(#CHEMIN_IMAGE{ok-16.png}|balise_img)],[(#CHEMIN_IMAGE{supprimer-8.png}|balise_img)]})]</td>
</tr>
</BOUCLE_prefixe>
</B_prefixe>
[<tr class="prefixe">
<td colspan="3"><h3>(#ENV{prefixe,''}|unique)</h3></td>
</tr>]
<tr class="[(#ENV{class})]">
<td class="fonction principale">[(#VALEUR{fonction}|replace{'_','_<wbr/>'})] [(#VALEUR{fichier}|match{'/plugins/'}|non)<a href="http://code.spip.net/@#VALEUR{fonction}" target="_blank" class="aide">[(#CHEMIN_IMAGE{aide-16.png}|balise_img|inserer_attribut{title,<:titre_image_aide:>})]</a>]</td>
<td class="filename secondaire">[(#VALEUR{fichier}|replace{(/|_),$1<wbr/>})]</td>
<td class="surcharge secondaire">[(#VALEUR{fonction}|match{(_dist)$}|?{[(#CHEMIN_IMAGE{ok-16.png}|balise_img)],[(#CHEMIN_IMAGE{supprimer-8.png}|balise_img)]})]</td>
</tr>
<//B_prefixe>
</BOUCLE_fonctions>
</tbody>
</table>
</div>
</B_fonctions>

6
prive/squelettes/contenu/source_fonctions.html → prive/squelettes/contenu/source_fonctions_utilisateur.html

@ -1,6 +1,6 @@
[(#VAL{source_fonctions}|barre_onglets{source_fonctions})]
[(#VAL{source_fonctions_utilisateur}|barre_onglets{source_fonctions_utilisateur})]
<h1><:fonction:titre_page_fonctions:></h1>
<h1><:fonction:titre_page_fonctions_utilisateur:></h1>
<B_fonctions>
<div class="liste-objets fonctions">
@ -18,7 +18,7 @@
<tbody>
<BOUCLE_fonctions (DATA) {source table, (#ENV{prefixe,''}|lister_fonctions)}>
<BOUCLE_prefixe (DATA) {source table, #VALEUR} {si #VALEUR|is_array}>
#INCLURE{fond=prive/squelettes/inclure/fonction_info_ligne,fonction=#VALEUR,class=(#COMPTEUR_BOUCLE|alterner{'row_odd','row_even'}),prefixe=(#_images:CLE|unique)}
#INCLURE{fond=prive/squelettes/inclure/fonction_info_ligne,fonction=#VALEUR,class=(#COMPTEUR_BOUCLE|alterner{'row_odd','row_even'}),prefixe=(#_fonctions:CLE|unique)}
</BOUCLE_prefixe>
</B_prefixe>
#INCLURE{fond=prive/squelettes/inclure/fonction_info_ligne,fonction=#VALEUR,class=(#COMPTEUR_BOUCLE|alterner{'row_odd','row_even'}),prefixe=(#ENV{prefixe,''}|unique),env}

2
prive/squelettes/contenu/source_images.html

@ -1,4 +1,4 @@
[(#VAL{source_fonctions}|barre_onglets{source_images})]
[(#VAL{source_fonctions_utilisateur}|barre_onglets{source_images})]
<h1><:fonction:titre_page_images:></h1>

2
prive/squelettes/navigation/source_fonctions.html

@ -1,2 +0,0 @@
#FORMULAIRE_LISTER_FONCTIONS
<div class="nettoyeur"></div>

2
prive/squelettes/navigation/source_fonctions_completes.html

@ -0,0 +1,2 @@
#FORMULAIRE_LISTER_FONCTIONS_COMPLETES
<div class="nettoyeur"></div>

2
prive/squelettes/navigation/source_fonctions_utilisateur.html

@ -0,0 +1,2 @@
#FORMULAIRE_LISTER_FONCTIONS_UTILISATEUR
<div class="nettoyeur"></div>
Loading…
Cancel
Save