source: spip-zone/_plugins_/fabrique/trunk/fabrique_fonctions.php @ 100632

Last change on this file since 100632 was 100632, checked in by marcimat@…, 4 years ago

Correction pour https://core.spip.net/issues/3863 : les listes d'objets doivent avoir un critère sur la clé primaire de la table également.

File size: 44.1 KB
Line 
1<?php
2
3/**
4 * Fonctions utiles pour les squelettes de la fabrique
5 *
6 * @package SPIP\Fabrique\Fonctions
7**/
8
9if (!defined("_ECRIRE_INC_VERSION")) return;
10
11
12/**
13 * Déterminer le répertoire de travail
14 * de la Fabrique.
15 *
16 * Dans :
17 * - plugins/fabrique_auto si possible, sinon dans
18 * - tmp/cache/fabrique
19 *
20 * @return string
21 *     Le chemin de destination depuis la racine de SPIP.
22**/
23function fabrique_destination() {
24        static $destination = null;
25        if (is_null($destination)) {
26                if (is_writable(_DIR_PLUGINS . rtrim(FABRIQUE_DESTINATION_PLUGINS, '/'))) {
27                        $destination = _DIR_PLUGINS . FABRIQUE_DESTINATION_PLUGINS;
28                } else {
29                        sous_repertoire(_DIR_CACHE, rtrim(FABRIQUE_DESTINATION_CACHE, '/'));
30                        $destination = _DIR_CACHE . FABRIQUE_DESTINATION_CACHE;
31                }
32        }
33        return $destination;
34}
35
36
37/**
38 * Crée l'arborescence manquante
39 *
40 * Crée tous les répertoires manquants dans une arborescence donnée.
41 * Les répertoires sont séparés par des '/'
42 *
43 * @example
44 *     sous_repertoire_complet('a/b/c/d');
45 *     appelle sous_repertoire() autant de fois que nécéssaire.
46 *
47 * @param string $arbo
48 *     Arborescence, tel que 'prive/squelettes/contenu'
49 * @return void
50**/
51function sous_repertoire_complet($arbo) {
52        $a = explode('/', $arbo);
53        if ($a[0] == '.' OR $a[0] == '..') {
54                $base = $a[0] . '/' . $a[1];
55                array_shift($a);
56                array_shift($a);
57        } else {
58                $base = $a[0];
59                array_shift($a);
60        }
61
62        foreach ($a as $dir) {
63                $base .= '/' . $dir;
64                sous_repertoire($base);
65        }
66}
67
68
69/**
70 * Concatène en utilisant implode, un tableau, de maniere récursive
71 *
72 * @param array $tableau
73 *     Tableau à transformer
74 * @param string $glue
75 *     Chaine insérée entre les valeurs
76 * @return string|bool
77 *     - False si pas un tableau
78 *     - Chaine concaténée sinon
79**/
80function fabrique_implode_recursif($tableau, $glue='') {
81        if (!is_array($tableau)) {
82                return false;
83        }
84
85        foreach ($tableau as $c =>$valeur) {
86                if (is_array($valeur)) {
87                        $tableau[$c] = fabrique_implode_recursif($valeur, $glue);
88                }
89        }
90
91        return implode($glue, $tableau);
92}
93
94
95/**
96 * Écrit une ouverture de code PHP
97 *
98 * Fait écrire '<?php' sans que ce php soit executé par SPIP !
99 *
100 * @param Champ $p
101 *     Pile au niveau de la balise
102 * @return Champ
103 *     Pile complétée du code à produire
104**/
105function balise_PHP_dist($p) {
106        $p->code = "'<?php echo \'<?php\n\'; ?>'";
107        $p->interdire_scripts = false;
108        return $p;
109}
110
111/**
112 * Convertie une chaîne pour en faire une chaîne de langue
113 *
114 * Permet d'insérer un texte comme valeur d'une clé de langue, lorsqu'on
115 * crée un fichier de langue avec la fabrique.
116 *
117 * Transforme les caractères &# et échappe les apostrophes :
118 * - &#xxx => le bon caractère
119 * - ' => \'
120 *
121 * @example
122 *     '#ENV{prefixe}_description' => '[(#ENV{paquet/description}|chaine_de_langue)]',
123 *
124 * @link http://www.php.net/manual/fr/function.html-entity-decode.php#104617
125 * @param string $texte
126 *     Le texte à écrire dans la chaîne de langue
127 * @return string
128 *     Le texte transformé
129**/
130function chaine_de_langue($texte) {
131        $texte = html_entity_decode($texte, ENT_QUOTES, 'UTF-8');
132        # egalement
133        # http://www.php.net/manual/fr/function.html-entity-decode.php#104617
134
135        return addslashes($texte);
136}
137
138/**
139 * Modifie le nom de la clé de langue pour
140 * utiliser le vrai nom de l'objet
141 *
142 * Remplace 'objets' par le nom de l'objet, et 'objet' par le type d'objet,
143 * mais ne touche pas à '\objets' ou '\objet'.
144 *
145 * @note
146 *     Cette fonction ne sert pas uniquement à définir des clés pour
147 *     les fichiers de chaînes de langue, et pourrait être renommée
148 *
149 * @example
150 *     ```
151 *     cle_de_langue('titre_objets') => titre_chats
152 *     cle_de_langue('icone_creer_objet') => icone_creer_chat
153 *     cle_de_langue('prive/\objets/infos/objet.html') => prive/objets/infos/chat.html
154 *     ```
155 * @param string $cle
156 *     La clé à transformer
157 * @param array $desc_objet
158 *     Couples d'information sur l'objet en cours, avec les index
159 *     'objet' et 'type' définis
160 * @return string
161 *     La clé transformée
162**/
163function cle_de_langue($cle, $desc_objet) {
164        // on permet d'echapper \objets pour trouver 'objets' au bout du compte
165        // sans qu'il soit transforme dans le nom reel de l'objet
166        // cas : 'prive/\objets/infos/objet.html' => 'prive/objets/infos/nom.html'
167        $cle = str_replace("\o", "\1o\\", $cle);
168        $cle =  str_replace(
169                array('objets', 'objet'),
170                array($desc_objet['objet'], $desc_objet['type']), $cle);
171        return str_replace("\1o\\", "o", $cle);
172}
173
174/**
175 * Identique à |cle_de_langue sur toutes les valeurs d'un tableau
176 *
177 * @see cle_de_langue()
178 * @param array $tableau
179 *     Tableau dont on veut transformer les valeurs
180 * @param array $desc_objet
181 *     Couples d'information sur l'objet en cours, avec les index
182 *     'objet' et 'type' définis
183 * @return array
184 *     Tableau avec les valeurs transformées
185**/
186function tab_cle_de_langue($tableau, $desc_objet) {
187        foreach($tableau as $c => $v) {
188                $tableau[$c] = cle_de_langue($v, $desc_objet);
189        }
190        return $tableau;
191}
192
193/**
194 * Cherche s'il existe une chaîne de langue pour les clés de tableaux
195 * et ajoute alors la traduction dans la valeur de ce tableau
196 *
197 * @param array $tableau
198 *     Couples (clé => texte)
199 * @param string $prefixe_cle
200 *     Préfixe ajouté aux clés pour chercher les trads
201 * @param string $sep
202 *     Séparateur entre l'ancienne valeur et la concaténation de traduction
203 * @return array
204 *     Couples (clé => texte complété de la traduction si elle existe)
205**/
206function tab_cle_traduite_ajoute_dans_valeur($tableau, $prefixe_cle="", $sep = "&nbsp;: ") {
207        foreach($tableau as $c => $v) {
208                $trad = _T("fabrique:". $prefixe_cle . $c, array(), array('force' => false));
209                if ($trad) {
210                        $tableau[$c] = $v . $sep . $trad;
211                } else {
212                        $tableau[$c] = $v;
213                }
214        }
215        return $tableau;
216}
217
218/**
219 * Équivalent de wrap() sur les valeurs du tableau
220 *
221 * @param array $tableau
222 *     Tableau cle => texte
223 * @param string $balise
224 *     Balise qui encapsule
225 * @return array $tableau
226 *     Tableau clé => <balise>texte</balise>
227**/
228function tab_wrap($tableau, $balise) {
229        foreach ($tableau as $c => $v) {
230                $tableau[$c] = wrap($v, $balise);
231        }
232        return $tableau;
233}
234
235
236/**
237 * Fabrique un tableau de chaînes de langues
238 * avec des clés d'origines passées dans la fonctions
239 * cle_de_langue, et trie.
240 *
241 * @param array $objet
242 *     Description de l'objet dans la fabrique
243 * @return array
244 *     Couples (clé de langue => Texte)
245**/
246function fabriquer_tableau_chaines($objet) {
247        $chaines = array();
248        if (!is_array($objet)) { return $chaines; }
249        if (!$table = $objet['table'] OR !isset($objet['chaines']) OR !is_array($objet['chaines'])) {
250                return $chaines;
251        }
252        // les chaines definies pour l'objet
253        foreach ($objet['chaines'] as $cle => $chaine) {
254                $chaines[ cle_de_langue($cle, $objet) ] = $chaine;
255        }
256        // les chaines definies pour chaque champ de l'objet
257        if (is_array($objet['champs'])) {
258                foreach ($objet['champs'] as $info) {
259                        $chaines[ cle_de_langue('champ_' . $info['champ'] . '_label', $objet) ] = $info['nom'];
260                        if ($info['explication']) {
261                                $chaines[ cle_de_langue('champ_' . $info['champ'] . '_explication', $objet) ] = $info['explication'];
262                        }
263                }
264        }
265        // les rôles définis
266        if ($roles = fabrique_description_roles($objet)) {
267                foreach ($roles['roles_trads'] as $cle => $texte) {
268                        $chaines[ $cle ] = $texte;
269                }
270        }
271
272        ksort($chaines);
273        return $chaines;
274}
275
276/**
277 * Retourne la description des rôles pour un objet
278 *
279 * @param array $objet
280 *     Descrption de l'objet
281 * @return array
282 *     Description des rôles. 4 index :
283 *     - roles_colonne : la colonne utilisée, toujours 'role'
284 *     - roles_titre   : couples clé du role, clé de langue du role
285 *     - roles_objets  : tableau objet => liste des clés de roles
286 *     - roles_trads   : couples clé de langue => Texte
287 *     - roles_defaut  : la clé du role par défaut
288 */
289function fabrique_description_roles($objet) {
290        $desc = array();
291        // les rôles définis
292        if (!options_presentes($objet, array('table_liens', 'roles'))
293        OR !($roles = trim($objet['roles']))) {
294                return $desc;
295        }
296        $desc['roles_colonne'] = 'role';
297        $desc['roles_titres'] = array(); # cle => cle_langue
298        $desc['roles_objets'] = array();
299        $desc['roles_trads']  = array(); # cle_langue => Texte
300        $desc['roles_defaut']  = '';
301
302        $roles = explode("\n", $roles);
303        foreach ($roles as $i=>$r) {
304                list($cle, $texte) = explode(',', $r, 2);
305                $cle = trim($cle);
306                if (!$i) $desc['roles_defaut'] = $cle; # la valeur par défaut est la première indiquée
307                $cle_langue = 'role_' . $cle;
308                $desc['roles_titres'][$cle] = $objet['type'] . ':' . $cle_langue;
309                $desc['roles_trads'][$cle_langue] = trim($texte);
310        }
311        $liens = array_map('table_objet', $objet['vue_liens']);
312        foreach ($liens as $l) {
313                $desc['roles_objets'][$l] = array_keys($desc['roles_titres']);
314        }
315        return $desc;
316}
317
318
319/**
320 * Indique si le champ est présent dans l'objet
321 *
322 * Champ, au sens de colonne SQL
323 *
324 * @param array $objet
325 *     Descrption de l'objet
326 * @param string $champ
327 *     Nom du champ SQL à tester
328 * @return string
329 *     Même retour que le filtre |oui :
330 *     - Un espace si le champ SQL exsitera dans l'objet
331 *     - Chaîne vide sinon
332**/
333function champ_present($objet, $champ) {
334        if (!$objet) {
335                return false;
336        }
337        if (isset($objet['champs']) and is_array($objet['champs'])) {
338                foreach ($objet['champs'] as $info) {
339                        if (isset($info['champ']) and $info['champ'] == $champ) {
340                                return " "; // true
341                        }
342                }
343        }
344        // id_rubrique, id_secteur
345        if (isset($objet['rubriques']) AND is_array($objet['rubriques'])) {
346                if (in_array($champ, $objet['rubriques'])) {
347                        return " "; // true
348                }
349        }
350        // lang, langue_choisie, id_trad
351        if (isset($objet['langues']) AND is_array($objet['langues'])) {
352                if (in_array($champ, $objet['langues'])) {
353                        return " "; // true
354                }
355                if (isset($objet['langues']['lang'])
356                        and ($objet['langues']['lang'])
357                        and ($champ == 'langue_choisie')) {
358                                return " "; // true
359                }
360        }
361        // date
362        if ($objet['champ_date']) {
363                if ($champ == $objet['champ_date']) {
364                        return " "; // true
365                }
366        }
367        // statut
368        if ($objet['statut']) {
369                if ($champ == 'statut') {
370                        return " "; // true
371                }
372        }
373
374        return ""; // false
375}
376
377
378/**
379 * Indique si toutes les options sont présentes dans l'objet
380 *
381 * Option au sens de clé de configuration, pas un nom de champ SQL
382 *
383 * @param array $objet
384 *     Descrption de l'objet
385 * @param array $champs
386 *     Liste de nom d'options à tester
387 * @return string
388 *     Même retour que le filtre |oui :
389 *     - Un espace si toutes les options sont présentes dans l'objet
390 *     - Chaîne vide sinon
391**/
392function options_presentes($objet, $champs) {
393        if (!$champs) return false;
394        if (!is_array($champs)) $champs = array($champs);
395        foreach ($champs as $champ) {
396                if (!option_presente($objet, $champ)) {
397                        return ""; // false
398                }
399        }
400        return " "; // true
401
402}
403
404/**
405 * Indique si une option est présente dans l'objet
406 *
407 * Option au sens de clé de configuration, pas un nom de champ SQL
408 *
409 * @param array $objet
410 *     Descrption de l'objet
411 * @param array $champ
412 *     Nom de l'option à tester
413 * @return string
414 *     Même retour que le filtre |oui :
415 *     - Un espace si l'option est présente dans l'objet
416 *     - Chaîne vide sinon
417**/
418function option_presente($objet, $champ) {
419        // a la racine
420        if (isset($objet[$champ]) and $objet[$champ]) {
421                return " "; // true
422        }
423
424        // id_rubrique, vue_rubrique, plan
425        if (isset($objet['rubriques']) AND is_array($objet['rubriques'])) {
426                if (in_array($champ, $objet['rubriques'])) {
427                        return " "; // true
428                }
429        }
430
431        // lang, id_trad
432        if (isset($objet['langues']) AND is_array($objet['langues'])) {
433                if (in_array($champ, $objet['langues'])) {
434                        return " "; // true
435                }
436        }
437       
438        // menu_edition, outils_rapides
439        if (isset($objet['boutons']) AND is_array($objet['boutons'])) {
440                if (in_array($champ, $objet['boutons'])) {
441                        return " "; // true
442                }
443        }
444
445        return ""; // false
446}
447
448
449/**
450 * Indique si une saisie est présente dans l'objet
451 *
452 * @param array $objet
453 *     Descrption de l'objet
454 * @param array $saisie
455 *     Nom de la saisie à tester
456 * @return string
457 *     Même retour que le filtre |oui :
458 *     - Un espace si l'option est présente dans l'objet
459 *     - Chaîne vide sinon
460**/
461function saisie_presente($objet, $saisie) {
462        if (isset($objet['champs']) and is_array($objet['champs'])) {
463                foreach ($objet['champs'] as $champ) {
464                        if (isset($champ['saisie']) and $champ['saisie'] == $saisie) {
465                                return " "; // true
466                        }
467                }
468        }
469        return ""; // false
470}
471
472
473/**
474 * Indique si une option donnée est presente dans la définition d'un champ
475 * de la fabrique
476 *
477 * @param array $champ
478 *     Description d'un champ SQL d'un objet créé avec la fabrique
479 * @param string $option
480 *     Option testée
481 * @return string
482 *     Même retour que le filtre |oui :
483 *     - Un espace si l'option est présente dans le champ de l'objet
484 *     - Chaîne vide sinon
485 */
486function champ_option_presente($champ, $option) {
487        if (isset($champ[$option]) and $champ[$option]) {
488                return " "; // true
489        }
490
491        // editable, versionne, obligatoire
492        if (isset($champ['caracteristiques']) and is_array($champ['caracteristiques'])) {
493                if (in_array($option, $champ['caracteristiques'])) {
494                        return " "; // true
495                }
496        }
497
498        return false;
499}
500
501
502/**
503 * Indique si une saisie donnée est presente dans la définition d'un champ
504 * de la fabrique
505 *
506 * @param array $champ
507 *     Description d'un champ SQL d'un objet créé avec la fabrique
508 * @param string $saisie
509 *     Saisie testée
510 * @return string
511 *     Même retour que le filtre |oui :
512 *     - Un espace si l'option est présente dans le champ de l'objet
513 *     - Chaîne vide sinon
514 */
515function champ_saisie_presente($champ, $saisie) {
516        if (isset($champ['saisie']) and $champ['saisie'] == $saisie) {
517                return " "; // true
518        }
519        return false;
520}
521
522
523/**
524 * Retourne les objets possédant un certain champ SQL
525 *
526 * Cela simplifie des boucles DATA
527 *
528 * @example
529 *     - `#OBJETS|objets_champ_present{id_rubrique}`
530 *     - On peut ne retourner qu'une liste de type de valeur (objet, type, id_objet)
531 *       `#OBJETS|objets_champ_present{id_rubrique, objet}` // chats,souris
532 *
533 * @param array $objets
534 *     Liste des descriptions d'objets créés avec la fabrique
535 * @param string $champ
536 *     Type de champ sélectionné
537 * @param string $type
538 *     Information de retour désiré :
539 *     - vide pour toute la description de l'objet
540 *     - clé dans la description de l'objet pour obtenir uniquement ces descriptions
541 * @return array
542 *     - tableau de description des objets sélectionnés (si type non défini)
543 *     - tableau les valeurs du type demandé dans les objets sélectionnés (si type défini)
544**/
545function objets_champ_present($objets, $champ, $type='') {
546        return _tableau_option_presente('champ_present', $objets, $champ, $type);
547}
548
549
550/**
551 * Retourne les objets possédant une certaine option
552 *
553 * Option au sens des clés du formulaire de configuration de l'objet
554 *
555 * @example
556 *     - `#OBJETS|objets_option_presente{vue_rubrique}`
557 *     - `#OBJETS|objets_option_presente{auteurs_liens}`
558 *     - On peut ne retourner qu'une liste de type de valeur (objet, type, id_objet)
559 *       `#OBJETS|objets_option_presente{auteurs_liens, objet}` // chats,souris
560 *
561 * @param array $objets
562 *     Liste des descriptions d'objets créés avec la fabrique
563 * @param string $option
564 *     Type d'option sélectionnée
565 * @param string $type
566 *     Information de retour désiré :
567 *     - vide pour toute la description de l'objet
568 *     - clé dans la description de l'objet pour obtenir uniquement ces descriptions
569 * @return array
570 *     - tableau de description des objets sélectionnés (si type non défini)
571 *     - tableau les valeurs du type demandé dans les objets sélectionnés (si type défini)
572**/
573function objets_option_presente($objets, $option, $type='') {
574        return _tableau_option_presente('option_presente', $objets, $option, $type);
575}
576
577
578/**
579 * Retourne les objets possédant une certaine saisie
580 *
581 * @example
582 *     - `#OBJETS|objets_saisie_presente{date}`
583 *     - On peut ne retourner qu'une liste de type de valeur (objet, type, id_objet)
584 *       `#OBJETS|objets_saisie_presente{date, objet}` // chats,souris
585 *
586 * @param array $objets
587 *     Liste des descriptions d'objets créés avec la fabrique
588 * @param string $saisie
589 *     Type de saisie sélectionnée
590 * @param string $type
591 *     Information de retour désiré :
592 *     - vide pour toute la description de l'objet
593 *     - clé dans la description de l'objet pour obtenir uniquement ces descriptions
594 * @return array
595 *     - tableau de description des objets sélectionnés (si type non défini)
596 *     - tableau les valeurs du type demandé dans les objets sélectionnés (si type défini)
597**/
598function objets_saisie_presente($objets, $saisie, $type='') {
599        return _tableau_option_presente('saisie_presente', $objets, $saisie, $type);
600}
601
602
603/**
604 * Retourne les objets possédant plusieurs options
605 *
606 * Option au sens des clés du formulaire de configuration de l'objet
607 *
608 * @example
609 *     - `#OBJETS|objets_options_presentes{#LISTE{table_liens,vue_liens}}`
610 *     - On peut ne retourner qu'une liste de type de valeur (objet, type, id_objet)
611 *       `#OBJETS|objets_options_presentes{#LISTE{table_liens,vue_liens}, objet}` // chats,souris
612 *
613 * @param array $objets
614 *     Liste des descriptions d'objets créés avec la fabrique
615 * @param array $options
616 *     Liste de type d'option à sélectionner
617 * @param string $type
618 *     Information de retour désiré :
619 *     - vide pour toute la description de l'objet
620 *     - clé dans la description de l'objet pour obtenir uniquement ces descriptions
621 * @return array
622 *     - tableau de description des objets sélectionnés (si type non défini)
623 *     - tableau les valeurs du type demandé dans les objets sélectionnés (si type défini)
624**/
625function objets_options_presentes($objets, $options, $type='') {
626        return _tableau_options_presentes('option_presente', $objets, $options, $type);
627}
628
629/**
630 * Retourne des champs en fonction d'une option trouvée
631 *
632 * @example
633 *     - `#CHAMPS|champs_option_presente{editable}`
634 *     - `#CHAMPS|champs_option_presente{versionne}`
635 *
636 * @param array $champs
637 *     Liste des descriptions de champs d'un objet créé avec la fabrique
638 * @param string $option
639 *     Type d'option sélectionnée
640 * @param string $type
641 *     Information de retour désiré :
642 *     - vide pour toute la description du champ
643 *     - clé dans la description du champ pour obtenir uniquement ces descriptions
644 * @return array
645 *     - tableau de description des champs sélectionnés (si type non défini)
646 *     - tableau les valeurs du type demandé dans les champs sélectionnés (si type défini)
647**/
648function champs_option_presente($champs, $option, $type='') {
649        return _tableau_option_presente('champ_option_presente', $champs, $option, $type);
650}
651
652/**
653 * Retourne des champs en fonction des options trouvées
654 *
655 * @example
656 *     `#CHAMPS|champs_options_presentes{#LISTE{obligatoire,saisie}}`
657 *
658 * @param array $champs
659 *     Liste des descriptions de champs d'un objet créé avec la fabrique
660 * @param array $options
661 *     Liste de type d'options à sélectionner
662 * @param string $type
663 *     Information de retour désiré :
664 *     - vide pour toute la description du champ
665 *     - clé dans la description du champ pour obtenir uniquement ces descriptions
666 * @return array
667 *     - tableau de description des champs sélectionnés (si type non défini)
668 *     - tableau les valeurs du type demandé dans les champs sélectionnés (si type défini)
669**/
670function champs_options_presentes($champs, $options, $type='') {
671        return _tableau_options_presentes('champ_option_presente', $champs, $options, $type);
672}
673
674/**
675 * Retourne des champs en fonction d'une option trouvée
676 *
677 * @example
678 *     `#CHAMPS|champs_saisie_presente{date}`
679 *
680 * @param array $champs
681 *     Liste des descriptions de champs d'un objet créé avec la fabrique
682 * @param string $saisie
683 *     Type de saisie sélectionnée
684 * @param string $type
685 *     Information de retour désiré :
686 *     - vide pour toute la description du champ
687 *     - clé dans la description du champ pour obtenir uniquement ces descriptions
688 * @return array
689 *     - tableau de description des champs sélectionnés (si type non défini)
690 *     - tableau les valeurs du type demandé dans les champs sélectionnés (si type défini)
691**/
692function champs_saisie_presente($champs, $saisie, $type='') {
693        return _tableau_option_presente('champ_saisie_presente', $champs, $saisie, $type);
694}
695
696/**
697 * Fonction générique pour retourner une liste de choses dans un tableau
698 *
699 * @param string $func
700 *     Nom de la fonction à appeler, tel que
701 *     - champ_option_presente
702 *     - option_presente
703 *     - ...
704 * @param array $tableau
705 *     Tableau de descriptions (descriptions d'objet ou descriptions de champ d'objet)
706 * @param string $option
707 *     Nom de l'option dont on teste la présence
708 * @param string $type
709 *     Information de retour désiré :
710 *     - vide pour toute la description
711 *     - clé dans la description pour obtenir uniquement ces descriptions
712 * @return array
713 *     Liste des descriptions correspondant à l'option demandée
714 */
715function _tableau_option_presente($func, $tableau, $option, $type='') {
716        $o = array();
717
718        if (!is_array($tableau) OR !$func) {
719                return $o;
720        }
721        // tableau est un tableau complexe de donnee
722        foreach ($tableau as $objet) {
723                // on cherche la donnee 'option' dans le tableau
724                // en utilisant une fonction specifique de recherche (option_presente, champ_present, ...)
725                if ($func($objet, $option)) {
726                        // si on a trouve notre option :
727                        // type permet de recuperer une cle specifique dans la liste des cles parcourues.
728                        // sinon, retourne tout le sous tableau.
729                        if ($type and isset($objet[$type])) {
730                                $o[] = $objet[$type];
731                        } elseif (!$type) {
732                                $o[] = $objet;
733                        }
734                }
735        }
736        return $o;
737}
738
739/**
740 * Fonction générique pour retourner une liste de choses multiples dans un tableau
741 *
742 * @param string $func
743 *     Nom de la fonction à appeler, tel que
744 *     - champ_option_presente
745 *     - option_presente
746 *     - ...
747 * @param array $tableau
748 *     Tableau de descriptions (descriptions d'objet ou descriptions de champ d'objet)
749 * @param array $options
750 *     Nom des l'options dont on teste leur présence
751 * @param string $type
752 *     Information de retour désiré :
753 *     - vide pour toute la description
754 *     - clé dans la description pour obtenir uniquement ces descriptions
755 * @return array
756 *     Liste des descriptions correspondant aux options demandées
757 */
758function _tableau_options_presentes($func, $tableau, $options, $type='') {
759        if (!$options) return array();
760
761        if (!is_array($options)) {
762                $options = array($options);
763        }
764
765        $first = false;
766        foreach ($options as $option) {
767                $r = _tableau_option_presente($func, $tableau, $option, $type);
768                if (!$first) {
769                        $res = $r;
770                        $first = true;
771                } else {
772                        #$res = array_intersect($res, $r);
773                        // array_intersect() ne prend pas en compte les sous tableaux
774                        foreach ($res as $i => $v) {
775                                if (false === array_search($v, $r)) {
776                                        unset($res[$i]);
777                                }
778                        }
779                        $res = array_values($res);
780                }
781        }
782
783        return $res;
784}
785
786/**
787 * Retrouve si cet objet a des enfants déclarés dans un autre objet
788 *
789 * @param array $objet
790 *     Description de l'objet dans la fabrique
791 * @param array $objets
792 *     Description de tous les objets dans la fabrique
793 * @return
794**/
795function fabrique_objets_enfants_directs($objet, $objets) {
796        $liste = array();
797        foreach ($objets as $autre_objet) {
798                if ($autre_objet !== $objet) {
799                        if (option_presente($autre_objet, 'liaison_directe')) {
800                                if ($objet['table'] == $autre_objet['liaison_directe']) {
801                                        $liste[] = $autre_objet;
802                                }
803                        }
804                }
805        }
806        return $liste;
807}
808
809/**
810 * Retourne une écriture de critères `{id_xxx ?}`
811 *
812 * Tous les champs déclarés commençant par `id_x` sont retournés
813 * sous forme d'une écriture de critère, tel que `{id_parent?}{id_documentation?}`
814 *
815 * La clé primaire est également ajoutée, sauf contre indication.
816 *
817 * Les champs indirects `{B_liens.id_B ?}` sont aussi ajoutés s'ils sont déclarés
818 * dans la Fabrique en même temps.
819 *
820 * @param array $objet
821 *     Description de l'objet dans la fabrique
822 * @param array $objets
823 *     Description de tous les objets dans la fabrique
824 * @param bool $avec_cle_primaire
825 *     Ajouter la clé primaire de la table également
826 * @return string
827 *     L'écriture des critères de boucle
828**/
829function criteres_champs_id($objet, $objets, $avec_cle_primaire = true) {
830        $ids = array();
831
832        if ($avec_cle_primaire) {
833                $ids[] = $objet['id_objet'];
834        }
835
836        // parenté directe sur Rubrique ?
837        if (champ_present($objet, 'id_rubrique')) {
838                $ids[] = 'id_rubrique';
839        }
840        if (champ_present($objet, 'id_secteur')) {
841                $ids[] = 'id_secteur';
842        }
843
844        // parenté directe sur un autre objet ?
845        if (option_presente($objet, 'liaison_directe') and $_id = fabrique_id_table_objet($objet['liaison_directe'], $objets)) {
846                $ids[] = $_id;
847        }
848        if (is_array($objet['champs'])) {
849                foreach ($objet['champs'] as $info) {
850                        if (substr($info['champ'], 0, 3) == 'id_') {
851                                $ids[] = $info['champ'];
852                        }
853                }
854        }
855
856        // Liaisons indirectes via table de liens déclarée dans la Fabrique ?
857        // D'autres objets peuvent avoir une table de liens et demander à être lié sur cet objet.
858        // On ajoute leurs champs de liaison.
859        foreach ($objets as $autre_objet) {
860                if ($autre_objet !== $objet) {
861                        if (options_presentes($autre_objet, array('table_liens', 'vue_liens'))) {
862                                if (in_array($objet['table'], $autre_objet['vue_liens'])) {
863                                        $ids[] = $autre_objet['objet'] . '_liens.' . $autre_objet['id_objet'];
864                                }
865                        }
866                }
867        }
868
869        if (!$ids) {
870                return "";
871        }
872        return "{" . implode("?}{", $ids) . "?}";
873}
874
875/**
876 * Retourne un tableau de toutes les tables SQL
877 * pour tous les objets.
878 *
879 * @param array $objets
880 *     Liste des descriptions d'objets créés avec la fabrique
881 * @param string $quoi
882 *     Choix du retour désiré :
883 *     - 'tout'   => toutes les tables (par défaut)
884 *     - 'objets' => les tables d'objet (spip_xx, spip_yy)
885 *     - 'liens'  => les tables de liens (spip_xx_liens, spip_yy_liens)
886 * @return array
887 *     Liste des tables
888**/
889function fabrique_lister_tables($objets, $quoi='tout') {
890        static $tables = array();
891
892        if (!$objets) return array();
893
894        $hash = md5(serialize($objets));
895       
896        if (!isset($tables[$hash])) {
897                $tables[$hash] = array(
898                        'tout' => array(),
899                        'objets' => array(),
900                        'liens' => array(),
901                );
902                foreach ($objets as $o) {
903                        // tables principales
904                        if (isset($o['table']) and $o['table']) {
905                                $tables[$hash]['objets'][] = $o['table'];
906                                $tables[$hash]['tout'][] = $o['table'];
907                                // tables de liens
908                                if ($o['table_liens']) {
909                                        $tables[$hash]['liens'][] = $o['nom_table_liens'];
910                                        $tables[$hash]['tout'][]  = $o['nom_table_liens'];
911                                }
912                        }
913                }
914        }
915       
916        return $tables[$hash][$quoi];
917}
918
919
920/**
921 * Retourne la liste des noms de certains champs pour cet objet
922 *
923 * Champs déclarés complétés des champs spéciaux (editable, versionne, obligatoire)
924 *
925 * @param array $objet
926 *     Description de l'objet concerné
927 * @param string $option
928 *     Option souhaitée.
929 * @param array $objets
930 *     Description de l'ensemble des objets générés par la Fabrique.
931 * @return array
932 *     Liste des champs concernés
933**/
934function fabrique_lister_objet_champs($objet, $option) {
935        if (!$objet) {
936                return array();
937        }
938        $liste = array();
939        if (is_array($objet['champs'])) {
940                $liste = champs_option_presente($objet['champs'], $option, 'champ');
941        }
942        if (champ_present($objet, 'id_rubrique')) {
943                $liste[] = 'id_rubrique';
944        }
945        if (champ_present($objet, 'id_secteur')) {
946                $liste[] = 'id_secteur';
947        }
948        if (option_presente($objet, 'liaison_directe')) {
949                $liste[] = $objet['parent']['id_objet'];
950        }
951        return $liste;
952}
953
954
955/**
956 * Indique si un des objets a besoin du pipeline demandé
957 *
958 * @param array $objets
959 *     Liste des descriptions d'objets créés avec la fabrique
960 * @param string $pipeline
961 *     Nom du pipeline
962 * @return array
963 *     Liste des objets (descriptions) utilisant le pipeline
964 */
965function fabrique_necessite_pipeline($objets, $pipeline) {
966
967        if (!$objets) return false;
968
969        switch ($pipeline) {
970                case "autoriser":
971                case "declarer_tables_objets_sql":
972                case "declarer_tables_interfaces":
973                        return (bool)fabrique_lister_tables($objets, 'objets');
974                        break;
975
976                case "declarer_tables_auxiliaires":
977                        return (bool)fabrique_lister_tables($objets, 'liens');
978                        break;
979
980                case "affiche_enfants":
981                        if (objets_option_presente($objets, 'vue_rubrique')
982                                OR objets_option_presente($objets, 'liaison_directe')) {
983                                return true;
984                        }
985                        break;
986
987                case "affiche_milieu":
988                        if (objets_option_presente($objets, 'auteurs_liens')
989                        OR  objets_options_presentes($objets, array('table_liens', 'vue_liens'))) {
990                                return true;
991                        }
992                        break;
993
994                case "affiche_auteurs_interventions":
995                        if (objets_option_presente($objets, 'vue_auteurs_liens')) {
996                                return true;
997                        }
998                        break;
999
1000                case "afficher_contenu_objet":
1001                        return false;
1002                        break;
1003
1004                case "boite_infos":
1005                        if (objets_option_presente($objets, 'id_rubrique')
1006                                or objets_option_presente($objets, 'liaison_directe')) {
1007                                return true;
1008                        }
1009                        break;
1010
1011                case "objet_compte_enfants":
1012                        if (objets_options_presentes($objets, array('id_rubrique', 'statut_rubrique'))
1013                                or objets_option_presente($objets, 'liaison_directe')) {
1014                                return true;
1015                        }
1016                        break;
1017
1018               
1019                case "optimiser_base_disparus":
1020                        # nettoie depuis spip_{objet}_liens
1021                        # mais aussi les liaisions vers spip_{objet} (uniquement si une table de liens existe)
1022                        if (fabrique_lister_tables($objets, 'liens')) {
1023                                return true;
1024                        }
1025                        # nettoie aussi les objets à la poubelle (si avec statut)
1026                        if (objets_champ_present($objets, 'statut')) {
1027                                return true;
1028                        }
1029                        break;
1030                       
1031                case "trig_propager_les_secteurs":
1032                        if (objets_options_presentes($objets, array('id_rubrique', 'id_secteur'))) {
1033                                return true;
1034                        }
1035                        break;
1036        }
1037        return false;
1038}
1039
1040
1041/**
1042 * Crée le code PHP de création d'un tableau
1043 *
1044 * Fonction un peu équivalente à var_export()
1045 *
1046 * @param array $tableau
1047 *     Le tableau dont on veut obtenir le code de création array( ... )
1048 * @param bool $quote
1049 *     Appliquer sql_quote() sur chaque valeur (dans le code retourne)
1050 * @param string $defaut
1051 *     Si $tableau est vide ou n'est pas une chaîne, la fonction retourne cette valeur
1052 * @return string
1053 *     - Le code de création du tableau, avec éventuellement le code pour appliquer sql_quote.
1054 *     - $defaut si le tableau est vide
1055**/
1056function ecrire_tableau($tableau, $quote = false, $defaut = "array()") {
1057        // pas de tableau ?
1058        if (!is_array($tableau) OR !count($tableau)) {
1059                return $defaut;
1060        }
1061
1062        $res = "array('" . implode("', '", array_map('addslashes', $tableau)) . "')";
1063
1064        if ($quote) {
1065                $res = "array_map('sql_quote', $res)";
1066        }
1067        return $res;
1068}
1069
1070/**
1071 * Crée le code PHP de création d'un tableau sauf s'il est vide
1072 *
1073 * Identique à ecrire_tableau() mais ne retourne rien si le tableau est vide
1074 * @see ecrire_tableau()
1075 *
1076 * @param array $tableau
1077 *     Le tableau dont on veut obtenir le code de création array( ... )
1078 * @param bool $quote
1079 *     Appliquer sql_quote() sur chaque valeur (dans le code retourne)
1080 * @return string
1081 *     - Le code de création du tableau, avec éventuellement le code pour appliquer sql_quote.
1082 *     - Chaîne vide si le tableau est vide
1083**/
1084function ecrire_tableau_sinon_rien($tableau, $quote = false) {
1085        return ecrire_tableau($tableau, $quote, "");
1086}
1087
1088/**
1089 * Ajoute autant des espaces à la fin d'une chaîne jusqu'à la taille indiquée
1090 *
1091 * Fonction un peu equivalente à str_pad() mais avec une valeur par défaut
1092 * définie par la constante `_FABRIQUE_ESPACER`
1093 *
1094 * @param string $texte
1095 *     Texte à compléter
1096 * @param int $taille
1097 *     Taille spécifique, utilisée à la place de la constante si renseignée
1098 * @return
1099 *     Texte complété des espaces de fin
1100 */
1101function espacer($texte, $taille = 0) {
1102        if (!$taille) $taille = _FABRIQUE_ESPACER;
1103        return str_pad($texte, $taille);
1104}
1105
1106
1107/**
1108 * Tabule à gauche chaque ligne du nombre de tabulations indiquées
1109 * + on enleve les espaces sur les lignes vides
1110 *
1111 * @param string $texte
1112 *     Un texte, qui peut avoir plusieurs lignes
1113 * @param int $nb_tabulations
1114 *     Nombre de tabulations à appliquer à gauche de chaque ligne
1115 * @return string
1116 *     Texte indenté du nombre de tabulations indiqué
1117 */
1118function fabrique_tabulations($texte, $nb_tabulations) {
1119        $tab = "";
1120        if ($nb_tabulations) {
1121                $tab = str_pad("\t", $nb_tabulations);
1122        }
1123        $texte = explode("\n", $texte);
1124        foreach ($texte as $c => $ligne) {
1125                $l = ltrim(ltrim($ligne), "\t");
1126                if (!$l) {
1127                        $texte[$c] = "";
1128                } else {
1129                        $texte[$c] = $tab . $ligne;
1130                }
1131        }
1132        return implode("\n", $texte);
1133}
1134
1135
1136
1137
1138/**
1139 * Passer en majuscule en utilisant mb de préférence
1140 * s'il est disponible.
1141 *
1142 * @param string $str
1143 *     La chaine à passer en majuscule
1144 * @return string
1145 *     La chaine en majuscule
1146**/
1147function fabrique_mb_strtoupper($str) {
1148        if (function_exists('mb_strtoupper')) {
1149                return mb_strtoupper($str);
1150        } else {
1151                return strtoupper($str);
1152        }
1153}
1154
1155/**
1156 * Passer en minuscule en utilisant mb de préférence
1157 * s'il est disponible.
1158 *
1159 * @param string $str
1160 *              La chaine à passer en minuscule
1161 * @return string
1162 *              La chaine en minuscule
1163**/
1164function fabrique_mb_strtolower($str) {
1165        if (function_exists('mb_strtolower')) {
1166                return mb_strtolower($str);
1167        } else {
1168                return strtolower($str);
1169        }
1170}
1171
1172
1173/**
1174 * Crée une balise HTML <img> à partir d'un fichier,
1175 * réactualisée à chaque calcul, selon une réduction donnée.
1176 *
1177 * Cela évite un |array_shift qui ne passe pas en PHP 5.4
1178 *
1179 * Attention à bien rafraîchir l'image réduite lorsqu'on change de logo.
1180 *
1181 * @example
1182 *     `#URL_IMAGE|fabrique_miniature_image{128}`
1183 *     Applique l'équivalent de :
1184 *     ```
1185 *     #URL_IMAGE
1186 *         |image_reduire{128}|extraire_attribut{src}
1187 *         |explode{?}|array_shift|timestamp|balise_img
1188 *     ```
1189 *
1190 * @param string $fichier
1191 *     Chemin du fichier
1192 * @param int $taille
1193 *     Taille de réduction de l'image
1194 * @return string
1195 *     Balise HTML IMG de l'image réduite et à jour
1196 */
1197function filtre_fabrique_miniature_image($fichier, $taille=256) {
1198        $im = filtrer('image_reduire', $fichier, $taille);
1199        $im = extraire_attribut($im, 'src');
1200        $im = explode('?', $im);
1201        $im = array_shift($im);
1202        $im = timestamp($im);
1203        $im = filtrer('balise_img', $im);
1204        return $im;
1205}
1206
1207
1208
1209/**
1210 * Retourne un tableau table_sql=>Nom des objets de SPIP
1211 * complété des objets declares dans la fabrique ainsi
1212 * que de tables indiquees même si elles ne font pas parties
1213 * de declarations connues.
1214 *
1215 * @param array $objets_fabrique
1216 *              Déclaration d'objets de la fabrique
1217 * @param array $inclus
1218 *              Liste de tables SQL que l'on veut forcement presentes
1219 *              meme si l'objet n'est pas declare
1220 * @param array $exclus
1221 *              Liste de tables SQL que l'on veut forcement exclues
1222 *              meme si l'objet n'est pas declare
1223 * @return array
1224 *              Tableau table_sql => Nom
1225**/
1226function filtre_fabrique_lister_objets_editoriaux($objets_fabrique, $inclus=array(), $exclus=array()) {
1227        if (!is_array($inclus)) {
1228                $inclus = $inclus ? array($inclus) : array();
1229        }
1230        if (!is_array($exclus)) {
1231                $exclus = $exclus ? array($exclus) : array();
1232        }
1233
1234        // les objets existants
1235        $objets = lister_tables_objets_sql();
1236        foreach ($objets as $sql => $o) {
1237                if ($o['editable']) {
1238                        $liste[$sql] = _T($o['texte_objets']);
1239                }
1240        }
1241        unset($objets);
1242
1243        // les objets de la fabrique
1244        foreach ($objets_fabrique as $o) {
1245                if (isset($o['table']) and !isset($liste[$o['table']])) {
1246                        $liste[ $o['table'] ] = $o['nom'];
1247                }
1248        }
1249
1250        // des objets qui n'existent pas mais qui sont actuellement coches dans la saisie
1251        foreach ($inclus as $sql) {
1252                if (!isset($liste[$sql])) {
1253                        $liste[$sql] = $sql; // on ne connait pas le nom
1254                }
1255        }
1256
1257        // tables forcement exclues
1258        foreach ($exclus as $sql) {
1259                unset($liste[$sql]);
1260        }
1261        // enlever un eventuel element vide
1262        unset($liste['']);
1263
1264        asort($liste);
1265
1266        return $liste;
1267}
1268
1269
1270/**
1271 * Indique si cet objet a un parent direct déclaré
1272 *
1273 * @param array $objet
1274 *     Déclaration d'un objet dans la Fabrique
1275 * @param array $objet s
1276 *     Déclaration de tous les objets dans la Fabrique
1277 * @return array
1278 *     Description du parent
1279**/
1280function fabrique_parent($objet, $objets) {
1281        $table = '';
1282        if (champ_present($objet, 'id_rubrique')) {
1283                $table = 'spip_rubriques';
1284        }
1285        if (option_presente($objet, 'liaison_directe')) {
1286                $table = $objet['liaison_directe'];
1287        }
1288        if (!$table) {
1289                return array();
1290        }
1291
1292        $desc = array(
1293                'table' => $table,
1294                'id_objet' => fabrique_id_table_objet($table, $objets),
1295                'type' => fabrique_objet_type($table, $objets),
1296                'objet' => fabrique_table_objet($table, $objets),
1297        );
1298        $desc['mid_objet'] = strtoupper($desc['id_objet']);
1299        $desc['mobjet'] = strtoupper($desc['objet']);
1300        $desc['lobjet'] = $desc['objet'];
1301        $desc['mtype'] = strtoupper($desc['type']);
1302
1303        return $desc;
1304}
1305
1306/**
1307 * Retrouve la clé primaire d'un objet éditorial
1308 *
1309 * D'abord en cherchant dans les déclaration de la Fabrique,
1310 * sinon en cherchant dans les objets actifs sur ce SPIP.
1311 *
1312 * @param string $table
1313 *     Table SQL
1314 * @param array $objets
1315 *     Description des objets générés par la Fabrique.
1316 * @return string
1317**/
1318function fabrique_id_table_objet($table, $objets) {
1319        if (!$table) {
1320                return '';
1321        }
1322        // déclaré dans la Fabrique
1323        foreach ($objets as $objet) {
1324                if ($objet['table'] == $table) {
1325                        return $objet['id_objet'];
1326                }
1327        }
1328        // déclaré dans SPIP
1329        return id_table_objet($table);
1330}
1331
1332/**
1333 * Retrouve le nom d'objet d'un objet éditorial
1334 *
1335 * D'abord en cherchant dans les déclaration de la Fabrique,
1336 * sinon en cherchant dans les objets actifs sur ce SPIP.
1337 *
1338 * @param string $table
1339 *     Table SQL
1340 * @param array $objets
1341 *     Description des objets générés par la Fabrique.
1342 * @return string
1343**/
1344function fabrique_table_objet($table, $objets) {
1345        if (!$table) {
1346                return '';
1347        }
1348        // déclaré dans la Fabrique
1349        foreach ($objets as $objet) {
1350                if ($objet['table'] == $table) {
1351                        return $objet['objet'];
1352                }
1353        }
1354        // déclaré dans SPIP
1355        return table_objet($table);
1356}
1357
1358/**
1359 * Retrouve le type d'un objet éditorial
1360 *
1361 * D'abord en cherchant dans les déclaration de la Fabrique,
1362 * sinon en cherchant dans les objets actifs sur ce SPIP.
1363 *
1364 * @param string $table
1365 *     Table SQL
1366 * @param array $objets
1367 *     Description des objets générés par la Fabrique.
1368 * @return string
1369**/
1370function fabrique_objet_type($table, $objets) {
1371        if (!$table) {
1372                return '';
1373        }
1374        // déclaré dans la Fabrique
1375        foreach ($objets as $objet) {
1376                if ($objet['table'] == $table) {
1377                        return $objet['type'];
1378                }
1379        }
1380        // déclaré dans SPIP
1381        return objet_type($table);
1382}
1383
1384
1385/**
1386 * Retourne le code pour tester un type d'autorisation
1387 *
1388 * @param string $type
1389 *     Quel type d'autorisation est voulue
1390 * @param string $prefixe
1391 *     Préfixe du plugin généré
1392 * @param array $objet
1393 *     Description de l'objet dans la Fabrique
1394 * @return string
1395 *     Code de test de l'autorisation
1396**/
1397function fabrique_code_autorisation($type, $prefixe, $objet) {
1398
1399        switch($type) {
1400
1401                case "jamais":
1402                        return "false";
1403                        break;
1404
1405                case "toujours":
1406                        return "true";
1407                        break;
1408
1409                // au moins auteur de l'objet, ou administrateur complet ou admin restreint sur rubrique de l'objet
1410                case "auteur_objet":
1411                        $auteurs_objet = '$auteurs = ' . $prefixe . '_auteurs_objet(\'' . $objet['type'] . '\', $id) and in_array($qui[\'id_auteur\'], $auteurs)';
1412                        if (champ_present($objet, 'id_rubrique')) {
1413                                $admin = $prefixe . '_autoriser_admins(\'' . $objet['type'] . '\', $id, $qui)';
1414                        } else {
1415                                $admin = '($qui[\'statut\'] == \'0minirezo\' and !$qui[\'restreint\'])';
1416                        }
1417                        return "$admin\n\t\tor ($auteurs_objet)";
1418                        break;
1419
1420                // au moins auteur de l'objet si l'objet n'est pas publié, ou administrateur complet ou admin restreint sur la rubrique de l'objet
1421                // Note : normalement statut doit forcément être présent pour ce test !
1422                case "auteur_objet_statut":
1423                        $auteurs_objet = '$auteurs = ' . $prefixe . '_auteurs_objet(\'' . $objet['type'] . '\', $id) and in_array($qui[\'id_auteur\'], $auteurs)';
1424                        $test_statut = $prefixe . '_autoriser_statuts(\'' . $objet['type'] . '\', $id, $qui, $opt)';
1425                        if (champ_present($objet, 'id_rubrique')) {
1426                                $admin = $prefixe . '_autoriser_admins(\'' . $objet['type'] . '\', $id, $qui)';
1427                        } else {
1428                                $admin = '($qui[\'statut\'] == \'0minirezo\' and !$qui[\'restreint\'])';
1429                        }
1430                        if (champ_present($objet, 'statut')) {
1431                                return "$admin\n\t\tor ($test_statut\n\t\t\tand $auteurs_objet)";
1432                        } else {
1433                                return "$admin\n\t\tor ($auteurs_objet)";
1434                        }
1435                        break;
1436
1437                case "redacteur":
1438                        return "in_array(\$qui['statut'], array('0minirezo', '1comite'))";
1439                        break;
1440
1441                // Au moins administrateur complet ou restreint sur la rubrique sur l'objet
1442                // Note : normalement id_rubrique doit forcément être présent pour ce test !
1443                case "administrateur_restreint_objet":
1444                        if (champ_present($objet, 'id_rubrique')) {
1445                                $admin = $prefixe . '_autoriser_admins(\'' . $objet['type'] . '\', $id, $qui)';
1446                        } else {
1447                                $admin = '$qui[\'statut\'] == \'0minirezo\' and !$qui[\'restreint\']';
1448                        }
1449                        return $admin;
1450                        break;
1451
1452                case "administrateur_restreint":
1453                        return "\$qui['statut'] == '0minirezo'";
1454                        break;
1455
1456                case "administrateur":
1457                        return "\$qui['statut'] == '0minirezo' AND !\$qui['restreint']";
1458                        break;
1459
1460                case "webmestre":
1461                        return "autoriser('webmestre', '', '', \$qui)";
1462                        break;
1463
1464        }
1465
1466        return "";
1467}
1468
1469/**
1470 * Retourne la valeur de type d'autorisation
1471 * qui s'applique par defaut pour une autorisation donnee
1472 *
1473 * @param string $autorisation
1474 *              Nom de l'autorisation (objet et objets remplacent le veritable type et nom d'objet)
1475 * @return string
1476 *              Type d'autorisation par defaut (jamais, toujours, redacteur, ...)
1477**/
1478function fabrique_autorisation_defaut($autorisation) {
1479        switch($autorisation) {
1480                case 'objet_voir':
1481                        return "toujours";
1482                        break;
1483
1484                case 'objet_creer':
1485                case 'objet_modifier':
1486                        return "redacteur";
1487                        break;
1488
1489                case 'objet_supprimer':
1490                case 'associerobjet':
1491                        return "administrateur";
1492                        break;
1493        }
1494}
1495
1496/**
1497 * Retourne le code d'autorisation indique
1498 * sinon celui par defaut pour une fonction d'autorisation
1499 *
1500 * @param array $autorisations
1501 *     Les autorisations renseignees par l'interface pour un objet
1502 * @param string $autorisation
1503 *     Le nom de l'autorisation souhaitee
1504 * @param string $prefixe
1505 *     Préfixe du plugin généré
1506 * @param array $objet
1507 *     Description le l'objet dans la Fabrique
1508 * @return string
1509 *     Code de l'autorisation
1510**/
1511function fabrique_code_autorisation_defaut($autorisations, $autorisation, $prefixe, $objet) {
1512        if (!$autorisation) return "";
1513
1514        // trouver le type d'autorisation souhaitee, soit indiquee, soit par defaut
1515        if (!isset($autorisations[$autorisation]) OR !$type = $autorisations[$autorisation]) {
1516                $type = fabrique_autorisation_defaut($autorisation);
1517        }
1518
1519        // retourner le code PHP correspondant
1520        return fabrique_code_autorisation($type, $prefixe, $objet);
1521}
1522
1523/**
1524 * Retourne vrai si un test d'autorisation est d'un type spécifié
1525 * dans l'ensemble des autorisations à configurer de tous les objets
1526 *
1527 * @param array $objets
1528 *              Descriptions des objets de la Fabrique
1529 * @param string $recherche
1530 *              Le type d'autorisation recherché
1531 * @return bool
1532**/
1533function objets_autorisation_presente($objets, $recherche) {
1534        foreach ($objets as $objet) {
1535                if (autorisation_presente($objet, $recherche)) {
1536                        return true;
1537                }
1538        }
1539        return false;
1540}
1541
1542
1543/**
1544 * Retourne vrai si au moins une autorisation est d'un des types spécifiés
1545 * dans l'ensemble des autorisations à configurer de tous les objets
1546 *
1547 * @param array $objets
1548 *              Descriptions des objets de la Fabrique
1549 * @param string[] $recherches
1550 *              Les types d'autorisations recherchés
1551 * @return bool
1552**/
1553function objets_autorisations_presentes($objets, $recherches) {
1554        foreach ($recherches as $autorisation) {
1555                if (objets_autorisation_presente($objets, $autorisation)) {
1556                        return true;
1557                }
1558        }
1559        return false;
1560}
1561
1562/**
1563 * Retourne vrai si un test d'autorisation est d'un type spécifié
1564 * dans l'ensemble des autorisations à configurer d'un objet
1565 *
1566 * @param array $objet
1567 *              Description d'un objet de la Fabrique
1568 * @param string $recherche
1569 *              Le type d'autorisation recherché
1570 * @return bool
1571**/
1572function autorisation_presente($objet, $recherche) {
1573        foreach ($objet['autorisations'] as $autorisation => $type) {
1574                if (!$type) { 
1575                        $type = fabrique_autorisation_defaut($autorisation);
1576                }
1577                if ($type == $recherche) {
1578                        return true;
1579                }
1580        }
1581        return false;
1582}
1583
1584/**
1585 * Retourne le type pour le nom d'une fonction d'autorisation
1586 * 'article' => 'article'
1587 * 'truc_muche' => 'trucmuche'
1588 *
1589 * @param string $type
1590 *              Type ou objet
1591 * @return string
1592 *              Type pour le nom d'autorisation
1593**/
1594function fabrique_type_autorisation($type) {
1595        return str_replace('_', '', $type);
1596}
Note: See TracBrowser for help on using the repository browser.