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

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

Mise à jour des accordions, et correction de notices PHP

File size: 31.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 *     cle_de_langue('titre_objets') => titre_chats
151 *     cle_de_langue('icone_creer_objet') => icone_creer_chat
152 *     cle_de_langue('prive/\objets/infos/objet.html') => prive/objets/infos/chat.html
153 * @param string $cle
154 *     La clé à transformer
155 * @param array $desc_objet
156 *     Couples d'information sur l'objet en cours, avec les index
157 *     'objet' et 'type' définis
158 * @retrun string
159 *     La clé transformée
160**/
161function cle_de_langue($cle, $desc_objet) {
162        // on permet d'echapper \objets pour trouver 'objets' au bout du compte
163        // sans qu'il soit transforme dans le nom reel de l'objet
164        // cas : 'prive/\objets/infos/objet.html' => 'prive/objets/infos/nom.html'
165        $cle = str_replace("\o", "\1o\\", $cle);
166        $cle =  str_replace(
167                array('objets', 'objet'),
168                array($desc_objet['objet'], $desc_objet['type']), $cle);
169        return str_replace("\1o\\", "o", $cle);
170}
171
172/**
173 * Identique à |cle_de_langue sur toutes les valeurs d'un tableau
174 *
175 * @see cle_de_langue()
176 * @param array $tableau
177 *     Tableau dont on veut transformer les valeurs
178 * @param array $desc_objet
179 *     Couples d'information sur l'objet en cours, avec les index
180 *     'objet' et 'type' définis
181 * @return array
182 *     Tableau avec les valeurs transformées
183**/
184function tab_cle_de_langue($tableau, $desc_objet) {
185        foreach($tableau as $c => $v) {
186                $tableau[$c] = cle_de_langue($v, $desc_objet);
187        }
188        return $tableau;
189}
190
191/**
192 * Cherche s'il existe une chaîne de langue pour les clés de tableaux
193 * et ajoute alors la traduction dans la valeur de ce tableau
194 *
195 * @param array $tableau
196 *     Couples (clé => texte)
197 * @param string $prefixe_cle
198 *     Préfixe ajouté aux clés pour chercher les trads
199 * @param string $sep
200 *     Séparateur entre l'ancienne valeur et la concaténation de traduction
201 * @return array
202 *     Couples (clé => texte complété de la traduction si elle existe)
203**/
204function tab_cle_traduite_ajoute_dans_valeur($tableau, $prefixe_cle="", $sep = "&nbsp;: ") {
205        foreach($tableau as $c => $v) {
206                $trad = _T("fabrique:". $prefixe_cle . $c, array(), array('force' => false));
207                if ($trad) {
208                        $tableau[$c] = $v . $sep . $trad;
209                } else {
210                        $tableau[$c] = $v;
211                }
212        }
213        return $tableau;
214}
215
216/**
217 * Équivalent de wrap() sur les valeurs du tableau
218 *
219 * @param array $tableau
220 *     Tableau cle => texte
221 * @param string $balise
222 *     Balise qui encapsule
223 * @return array $tableau
224 *     Tableau clé => <balise>texte</balise>
225**/
226function tab_wrap($tableau, $balise) {
227        foreach ($tableau as $c => $v) {
228                $tableau[$c] = wrap($v, $balise);
229        }
230        return $tableau;
231}
232
233
234/**
235 * Fabrique un tableau de chaînes de langues
236 * avec des clés d'origines passées dans la fonctions
237 * cle_de_langue, et trie.
238 *
239 * @param array $objet
240 *     Description de l'objet dans la fabrique
241 * @return array
242 *     Couples (clé de langue => Texte)
243**/
244function fabriquer_tableau_chaines($objet) {
245        $chaines = array();
246        if (!is_array($objet)) { return $chaines; }
247        if (!$table = $objet['table'] OR !isset($objet['chaines']) OR !is_array($objet['chaines'])) {
248                return $chaines;
249        }
250        // les chaines definies pour l'objet
251        foreach ($objet['chaines'] as $cle => $chaine) {
252                $chaines[ cle_de_langue($cle, $objet) ] = $chaine;
253        }
254        // les chaines definies pour chaque champ de l'objet
255        if (is_array($objet['champs'])) {
256                foreach ($objet['champs'] as $info) {
257                        $chaines[ cle_de_langue('label_' . $info['champ'], $objet) ] = $info['nom'];
258                        if ($info['explication']) {
259                                $chaines[ cle_de_langue('explication_' . $info['champ'], $objet) ] = $info['explication'];
260                        }
261                }
262        }
263        // les rôles définis
264        if ($roles = fabrique_description_roles($objet)) {
265                foreach ($roles['roles_trads'] as $cle => $texte) {
266                        $chaines[ $cle ] = $texte;
267                }
268        }
269
270        ksort($chaines);
271        return $chaines;
272}
273
274/**
275 * Retourne la description des rôles pour un objet
276 *
277 * @param array $objet
278 *     Descrption de l'objet
279 * @return array
280 *     Description des rôles. 4 index :
281 *     - roles_colonne : la colonne utilisée, toujours 'role'
282 *     - roles_titre   : couples clé du role, clé de langue du role
283 *     - roles_objets  : tableau objet => liste des clés de roles
284 *     - roles_trads   : couples clé de langue => Texte
285 *     - roles_defaut  : la clé du role par défaut
286 */
287function fabrique_description_roles($objet) {
288        $desc = array();
289        // les rôles définis
290        if (!options_presentes($objet, array('table_liens', 'roles'))
291        OR !($roles = trim($objet['roles']))) {
292                return $desc;
293        }
294        $desc['roles_colonne'] = 'role';
295        $desc['roles_titres'] = array(); # cle => cle_langue
296        $desc['roles_objets'] = array();
297        $desc['roles_trads']  = array(); # cle_langue => Texte
298        $desc['roles_defaut']  = '';
299
300        $roles = explode("\n", $roles);
301        foreach ($roles as $i=>$r) {
302                list($cle, $texte) = explode(',', $r, 2);
303                $cle = trim($cle);
304                if (!$i) $desc['roles_defaut'] = $cle; # la valeur par défaut est la première indiquée
305                $cle_langue = 'role_' . $cle;
306                $desc['roles_titres'][$cle] = $objet['type'] . ':' . $cle_langue;
307                $desc['roles_trads'][$cle_langue] = trim($texte);
308        }
309        $liens = array_map('table_objet', $objet['vue_liens']);
310        foreach ($liens as $l) {
311                $desc['roles_objets'][$l] = array_keys($desc['roles_titres']);
312        }
313        return $desc;
314}
315
316
317/**
318 * Indique si le champ est présent dans l'objet
319 *
320 * Champ, au sens de colonne SQL
321 *
322 * @param array $objet
323 *     Descrption de l'objet
324 * @param string $champ
325 *     Nom du champ SQL à tester
326 * @return string
327 *     Même retour que le filtre |oui :
328 *     - Un espace si le champ SQL exsitera dans l'objet
329 *     - Chaîne vide sinon
330**/
331function champ_present($objet, $champ) {
332        if (is_array($objet['champs'])) {
333                foreach ($objet['champs'] as $info) {
334                        if ($info['champ'] == $champ) {
335                                return " "; // true
336                        }
337                }
338        }
339        // id_rubrique, id_secteur
340        if (isset($objet['rubriques']) AND is_array($objet['rubriques'])) {
341                if (in_array($champ, $objet['rubriques'])) {
342                        return " "; // true
343                }
344        }
345        // lang, langue_choisie, id_trad
346        if (isset($objet['langues']) AND is_array($objet['langues'])) {
347                if (in_array($champ, $objet['langues'])) {
348                        return " "; // true
349                }
350                if ($objet['langues']['lang'] and ($champ == 'langue_choisie')) {
351                        return " "; // true
352                }
353        }
354        // date
355        if ($objet['champ_date']) {
356                if ($champ == $objet['champ_date']) {
357                        return " "; // true
358                }
359        }
360        // statut
361        if ($objet['statut']) {
362                if ($champ == 'statut') {
363                        return " "; // true
364                }
365        }
366
367        return ""; // false
368}
369
370
371/**
372 * Indique si toutes les options sont présentes dans l'objet
373 *
374 * Option au sens de clé de configuration, pas un nom de champ SQL
375 *
376 * @param array $objet
377 *     Descrption de l'objet
378 * @param array $champs
379 *     Liste de nom d'options à tester
380 * @return string
381 *     Même retour que le filtre |oui :
382 *     - Un espace si toutes les options sont présentes dans l'objet
383 *     - Chaîne vide sinon
384**/
385function options_presentes($objet, $champs) {
386        if (!$champs) return false;
387        if (!is_array($champs)) $champs = array($champs);
388        foreach ($champs as $champ) {
389                if (!option_presente($objet, $champ)) {
390                        return ""; // false
391                }
392        }
393        return " "; // true
394
395}
396
397/**
398 * Indique si une option est présente dans l'objet
399 *
400 * Option au sens de clé de configuration, pas un nom de champ SQL
401 *
402 * @param array $objet
403 *     Descrption de l'objet
404 * @param array $champ
405 *     Nom de l'option à tester
406 * @return string
407 *     Même retour que le filtre |oui :
408 *     - Un espace si l'option est présente dans l'objet
409 *     - Chaîne vide sinon
410**/
411function option_presente($objet, $champ) {
412        // a la racine
413        if (isset($objet[$champ]) and $objet[$champ]) {
414                return " "; // true
415        }
416
417        // id_rubrique, vue_rubrique
418        if (isset($objet['rubriques']) AND is_array($objet['rubriques'])) {
419                if (in_array($champ, $objet['rubriques'])) {
420                        return " "; // true
421                }
422        }
423
424        // lang, id_trad
425        if (isset($objet['langues']) AND is_array($objet['langues'])) {
426                if (in_array($champ, $objet['langues'])) {
427                        return " "; // true
428                }
429        }
430       
431        // menu_edition, outils_rapides
432        if (isset($objet['boutons']) AND is_array($objet['boutons'])) {
433                if (in_array($champ, $objet['boutons'])) {
434                        return " "; // true
435                }
436        }
437
438        return ""; // false
439}
440
441
442/**
443 * Indique si une option donnée est presente dans la définition d'un champ
444 * de la fabrique
445 *
446 * @param array $champ
447 *     Description d'un champ SQL d'un objet créé avec la fabrique
448 * @param string $option
449 *     Option testée
450 * @return string
451 *     Même retour que le filtre |oui :
452 *     - Un espace si l'option est présente dans le champ de l'objet
453 *     - Chaîne vide sinon
454 */
455function champ_option_presente($champ, $option) {
456        if (isset($champ[$option]) and $champ[$option]) {
457                return " "; // true
458        }
459
460        // editable, versionne, obligatoire
461        if (isset($champ['caracteristiques']) and is_array($champ['caracteristiques'])) {
462                if (in_array($option, $champ['caracteristiques'])) {
463                        return " "; // true
464                }
465        }
466
467        return false;
468}
469
470/**
471 * Retourne les objets possédant un certain champ SQL
472 *
473 * Cela simplifie des boucles DATA
474 *
475 * @example
476 *     #OBJETS|objets_champ_present{id_rubrique}
477 *
478 *     On peut ne retourner qu'une liste de type de valeur (objet, type, id_objet)
479 *     #OBJETS|objets_champ_present{id_rubrique, objet} // chats,souris
480 *
481 * @param array $objets
482 *     Liste des descriptions d'objets créés avec la fabrique
483 * @param string $champ
484 *     Type de champ sélectionné
485 * @param string $type
486 *     Information de retour désiré :
487 *     - vide pour toute la description de l'objet
488 *     - clé dans la description de l'objet pour obtenir uniquement ces descriptions
489 * @return array
490 *     - tableau de description des objets sélectionnés (si type non défini)
491 *     - tableau les valeurs du type demandé dans les objets sélectionnés (si type défini)
492**/
493function objets_champ_present($objets, $champ, $type='') {
494        return _tableau_option_presente('champ_present', $objets, $champ, $type);
495}
496
497
498/**
499 * Retourne les objets possédant une certaine option
500 *
501 * Option au sens des clés du formulaire de configuration de l'objet
502 *
503 * @example
504 *     #OBJETS|objets_option_presente{vue_rubrique}
505 *     #OBJETS|objets_option_presente{auteurs_liens}
506 *
507 *     On peut ne retourner qu'une liste de type de valeur (objet, type, id_objet)
508 *     #OBJETS|objets_option_presente{auteurs_liens, objet} // chats,souris
509 *
510 * @param array $objets
511 *     Liste des descriptions d'objets créés avec la fabrique
512 * @param string $option
513 *     Type d'option sélectionnée
514 * @param string $type
515 *     Information de retour désiré :
516 *     - vide pour toute la description de l'objet
517 *     - clé dans la description de l'objet pour obtenir uniquement ces descriptions
518 * @return array
519 *     - tableau de description des objets sélectionnés (si type non défini)
520 *     - tableau les valeurs du type demandé dans les objets sélectionnés (si type défini)
521**/
522function objets_option_presente($objets, $option, $type='') {
523        return _tableau_option_presente('option_presente', $objets, $option, $type);
524}
525
526
527/**
528 * Retourne les objets possédant plusieurs options
529 *
530 * Option au sens des clés du formulaire de configuration de l'objet
531 *
532 * @example
533 *     #OBJETS|objets_options_presentes{#LISTE{table_liens,vue_liens}}
534 *
535 *     On peut ne retourner qu'une liste de type de valeur (objet, type, id_objet)
536 *     #OBJETS|objets_options_presentes{#LISTE{table_liens,vue_liens}, objet} // chats,souris
537 *
538 * @param array $objets
539 *     Liste des descriptions d'objets créés avec la fabrique
540 * @param array $options
541 *     Liste de type d'option à sélectionner
542 * @param string $type
543 *     Information de retour désiré :
544 *     - vide pour toute la description de l'objet
545 *     - clé dans la description de l'objet pour obtenir uniquement ces descriptions
546 * @return array
547 *     - tableau de description des objets sélectionnés (si type non défini)
548 *     - tableau les valeurs du type demandé dans les objets sélectionnés (si type défini)
549**/
550function objets_options_presentes($objets, $options, $type='') {
551        return _tableau_options_presentes('option_presente', $objets, $options, $type);
552}
553
554/**
555 * Retourne des champs en fonction d'une option trouvée
556 *
557 * @example
558 *     #CHAMPS|champs_option_presente{editable}
559 *     #CHAMPS|champs_option_presente{versionne}
560 *
561 * @param array $champs
562 *     Liste des descriptions de champs d'un objet créé 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 du champ
568 *     - clé dans la description du champ pour obtenir uniquement ces descriptions
569 * @return array
570 *     - tableau de description des champs sélectionnés (si type non défini)
571 *     - tableau les valeurs du type demandé dans les champs sélectionnés (si type défini)
572**/
573function champs_option_presente($champs, $option, $type='') {
574        return _tableau_option_presente('champ_option_presente', $champs, $option, $type);
575}
576
577/**
578 * Retourne des champs en fonction des options trouvées
579 *
580 * @example
581 *     #CHAMPS|champs_options_presentes{#LISTE{obligatoire,saisie}}
582 *
583 * @param array $champs
584 *     Liste des descriptions de champs d'un objet créé avec la fabrique
585 * @param array $options
586 *     Liste de type d'options à sélectionner
587 * @param string $type
588 *     Information de retour désiré :
589 *     - vide pour toute la description du champ
590 *     - clé dans la description du champ pour obtenir uniquement ces descriptions
591 * @return array
592 *     - tableau de description des champs sélectionnés (si type non défini)
593 *     - tableau les valeurs du type demandé dans les champs sélectionnés (si type défini)
594**/
595function champs_options_presentes($champs, $options, $type='') {
596        return _tableau_options_presentes('champ_option_presente', $champs, $options, $type);
597}
598
599
600/**
601 * Fonction générique pour retourner une liste de choses dans un tableau
602 *
603 * @param string $func
604 *     Nom de la fonction à appeler, tel que
605 *     - champ_option_presente
606 *     - option_presente
607 *     - ...
608 * @param array $tableau
609 *     Tableau de descriptions (descriptions d'objet ou descriptions de champ d'objet)
610 * @param string $option
611 *     Nom de l'option dont on teste la présence
612 * @param string $type
613 *     Information de retour désiré :
614 *     - vide pour toute la description
615 *     - clé dans la description pour obtenir uniquement ces descriptions
616 * @return array
617 *     Liste des descriptions correspondant à l'option demandée
618 */
619function _tableau_option_presente($func, $tableau, $option, $type='') {
620        $o = array();
621
622        if (!is_array($tableau) OR !$func) {
623                return $o;
624        }
625        // tableau est un tableau complexe de donnee
626        foreach ($tableau as $objet) {
627                // on cherche la donnee 'option' dans le tableau
628                // en utilisant une fonction specifique de recherche (option_presente, champ_present, ...)
629                if ($func($objet, $option)) {
630                        // si on a trouve notre option :
631                        // type permet de recuperer une cle specifique dans la liste des cles parcourues.
632                        // sinon, retourne tout le sous tableau.
633                        if ($type and isset($objet[$type])) {
634                                $o[] = $objet[$type];
635                        } elseif (!$type) {
636                                $o[] = $objet;
637                        }
638                }
639        }
640        return $o;
641}
642
643/**
644 * Fonction générique pour retourner une liste de choses multiples dans un tableau
645 *
646 * @param string $func
647 *     Nom de la fonction à appeler, tel que
648 *     - champ_option_presente
649 *     - option_presente
650 *     - ...
651 * @param array $tableau
652 *     Tableau de descriptions (descriptions d'objet ou descriptions de champ d'objet)
653 * @param array $options
654 *     Nom des l'options dont on teste leur présence
655 * @param string $type
656 *     Information de retour désiré :
657 *     - vide pour toute la description
658 *     - clé dans la description pour obtenir uniquement ces descriptions
659 * @return array
660 *     Liste des descriptions correspondant aux options demandées
661 */
662function _tableau_options_presentes($func, $tableau, $options, $type='') {
663        if (!$options) return array();
664
665        if (!is_array($options)) {
666                $options = array($options);
667        }
668
669        $first = false;
670        foreach ($options as $option) {
671                $r = _tableau_option_presente($func, $tableau, $option, $type);
672                if (!$first) {
673                        $res = $r;
674                        $first = true;
675                } else {
676                        #$res = array_intersect($res, $r);
677                        // array_intersect() ne prend pas en compte les sous tableaux
678                        foreach ($res as $i => $v) {
679                                if (false === array_search($v, $r)) {
680                                        unset($res[$i]);
681                                }
682                        }
683                        $res = array_values($res);
684                }
685        }
686
687        return $res;
688}
689
690
691/**
692 * Retourne une ecriture de criteres
693 * {id_parent?}{id_documentation?}
694 * avec tous les champs id_x declarés dans l'interface
695 * dans la liste des champs.
696 *
697 * Cela ne concerne pas les champs speciaux (id_rubrique, id_secteur, id_trad)
698 * qui ne seront pas inclus.
699 *
700 * @param array $objet
701 *     Description de l'objet dans la fabrique
702 * @return string
703 *     L'écriture des critères de boucle
704**/
705function criteres_champs_id($objet) {
706        $ids = array();
707        if (is_array($objet['champs'])) {
708                foreach ($objet['champs'] as $info) {
709                        if (substr($info['champ'], 0, 3) == 'id_') {
710                                $ids[] = $info['champ'];
711                        }
712                }
713        }
714        if (!$ids) {
715                return "";
716        }
717        return "{" . implode("?}{", $ids) . "?}";
718}
719
720/**
721 * Retourne un tableau de toutes les tables SQL
722 * pour tous les objets.
723 *
724 * @param array $objets
725 *     Liste des descriptions d'objets créés avec la fabrique
726 * @param string $quoi
727 *     Choix du retour désiré :
728 *     - 'tout'   => toutes les tables (par défaut)
729 *     - 'objets' => les tables d'objet (spip_xx, spip_yy)
730 *     - 'liens'  => les tables de liens (spip_xx_liens, spip_yy_liens)
731 * @return array
732 *     Liste des tables
733**/
734function fabrique_lister_tables($objets, $quoi='tout') {
735        static $tables = array();
736
737        if (!$objets) return array();
738
739        $hash = md5(serialize($objets));
740       
741        if (!isset($tables[$hash])) {
742                $tables[$hash] = array(
743                        'tout' => array(),
744                        'objets' => array(),
745                        'liens' => array(),
746                );
747                foreach ($objets as $o) {
748                        // tables principales
749                        if (isset($o['table']) and $o['table']) {
750                                $tables[$hash]['objets'][] = $o['table'];
751                                $tables[$hash]['tout'][] = $o['table'];
752                                // tables de liens
753                                if ($o['table_liens']) {
754                                        $tables[$hash]['liens'][] = $o['nom_table_liens'];
755                                        $tables[$hash]['tout'][]  = $o['nom_table_liens'];
756                                }
757                        }
758                }
759        }
760       
761        return $tables[$hash][$quoi];
762}
763
764
765/**
766 * Indique si un des objets a besoin du pipeline demandé
767 *
768 * @param array $objets
769 *     Liste des descriptions d'objets créés avec la fabrique
770 * @param string $pipeline
771 *     Nom du pipeline
772 * @return array
773 *     Liste des objets (descriptions) utilisant le pipeline
774 */
775function fabrique_necessite_pipeline($objets, $pipeline) {
776
777        if (!$objets) return false;
778
779        switch ($pipeline) {
780                case "autoriser":
781                case "declarer_tables_objets_sql":
782                case "declarer_tables_interfaces":
783                        return (bool)fabrique_lister_tables($objets, 'objets');
784                        break;
785
786                case "declarer_tables_auxiliaires":
787                        return (bool)fabrique_lister_tables($objets, 'liens');
788                        break;
789
790                case "affiche_enfants":
791                        if (objets_option_presente($objets, 'vue_rubrique')) {
792                                return true;
793                        }
794                        break;
795
796                case "affiche_milieu":
797                        if (objets_option_presente($objets, 'auteurs_liens')
798                        OR  objets_options_presentes($objets, array('table_liens', 'vue_liens'))) {
799                                return true;
800                        }
801                        break;
802
803                case "affiche_auteurs_interventions":
804                        if (objets_option_presente($objets, 'vue_auteurs_liens')) {
805                                return true;
806                        }
807                        break;
808
809                case "afficher_contenu_objet":
810                        return false;
811                        break;
812
813                case "optimiser_base_disparus":
814                        # nettoie depuis spip_{objet}_liens
815                        # mais aussi les liaisions vers spip_{objet} (uniquement si une table de liens existe)
816                        return (bool)fabrique_lister_tables($objets, 'liens');
817                        #return (bool)fabrique_lister_tables($objets, 'objets');
818                        break;
819        }
820        return false;
821}
822
823
824/**
825 * Crée le code PHP de création d'un tableau
826 *
827 * Fonction un peu équivalente à var_export()
828 *
829 * @param array $tableau
830 *     Le tableau dont on veut obtenir le code de création array( ... )
831 * @param bool $quote
832 *     Appliquer sql_quote() sur chaque valeur (dans le code retourne)
833 * @param string $defaut
834 *     Si $tableau est vide ou n'est pas une chaîne, la fonction retourne cette valeur
835 * @return string
836 *     - Le code de création du tableau, avec éventuellement le code pour appliquer sql_quote.
837 *     - $defaut si le tableau est vide
838**/
839function ecrire_tableau($tableau, $quote = false, $defaut = "array()") {
840        // pas de tableau ?
841        if (!is_array($tableau) OR !count($tableau)) {
842                return $defaut;
843        }
844
845        $res = "array('" . implode("', '", array_map('addslashes', $tableau)) . "')";
846
847        if ($quote) {
848                $res = "array_map('sql_quote', $res)";
849        }
850        return $res;
851}
852
853/**
854 * Crée le code PHP de création d'un tableau sauf s'il est vide
855 *
856 * Identique à ecrire_tableau() mais ne retourne rien si le tableau est vide
857 * @see ecrire_tableau()
858 *
859 * @param array $tableau
860 *     Le tableau dont on veut obtenir le code de création array( ... )
861 * @param bool $quote
862 *     Appliquer sql_quote() sur chaque valeur (dans le code retourne)
863 * @return string
864 *     - Le code de création du tableau, avec éventuellement le code pour appliquer sql_quote.
865 *     - Chaîne vide si le tableau est vide
866**/
867function ecrire_tableau_sinon_rien($tableau, $quote = false) {
868        return ecrire_tableau($tableau, $quote, "");
869}
870
871/**
872 * Ajoute autant des espaces à la fin d'une chaîne jusqu'à la taille indiquée
873 *
874 * Fonction un peu equivalente à str_pad() mais avec une valeur par défaut
875 * définie par la constante _FABRIQUE_ESPACER
876 *
877 * @param string $texte
878 *     Texte à compléter
879 * @param int $taille
880 *     Taille spécifique, utilisée à la place de la constante si renseignée
881 * @return
882 *     Texte complété des espaces de fin
883 */
884function espacer($texte, $taille = 0) {
885        if (!$taille) $taille = _FABRIQUE_ESPACER;
886        return str_pad($texte, $taille);
887}
888
889
890/**
891 * Tabule à gauche chaque ligne du nombre de tabulations indiquées
892 * + on enleve les espaces sur les lignes vides
893 *
894 * @param string $texte
895 *     Un texte, qui peut avoir plusieurs lignes
896 * @param int $nb_tabulations
897 *     Nombre de tabulations à appliquer à gauche de chaque ligne
898 * @return string
899 *     Texte indenté du nombre de tabulations indiqué
900 */
901function fabrique_tabulations($texte, $nb_tabulations) {
902        $tab = "";
903        if ($nb_tabulations) {
904                $tab = str_pad("\t", $nb_tabulations);
905        }
906        $texte = explode("\n", $texte);
907        foreach ($texte as $c => $ligne) {
908                $l = ltrim(ltrim($ligne), "\t");
909                if (!$l) {
910                        $texte[$c] = "";
911                } else {
912                        $texte[$c] = $tab . $ligne;
913                }
914        }
915        return implode("\n", $texte);
916}
917
918
919
920
921/**
922 * Passer en majuscule en utilisant mb de préférence
923 * s'il est disponible.
924 *
925 * @param string $str
926 *     La chaine à passer en majuscule
927 * @return string
928 *     La chaine en majuscule
929**/
930function fabrique_mb_strtoupper($str) {
931        if (function_exists('mb_strtoupper')) {
932                return mb_strtoupper($str);
933        } else {
934                return strtoupper($str);
935        }
936}
937
938/**
939 * Passer en minuscule en utilisant mb de préférence
940 * s'il est disponible.
941 *
942 * @param string $str
943 *              La chaine à passer en minuscule
944 * @return string
945 *              La chaine en minuscule
946**/
947function fabrique_mb_strtolower($str) {
948        if (function_exists('mb_strtolower')) {
949                return mb_strtolower($str);
950        } else {
951                return strtolower($str);
952        }
953}
954
955
956/**
957 * Crée une balise HTML <img> à partir d'un fichier,
958 * réactualisée à chaque calcul, selon une réduction donnée.
959 *
960 * Cela évite un |array_shift qui ne passe pas en PHP 5.4
961 *
962 * Attention à bien rafraîchir l'image réduite lorsqu'on change de logo.
963 *
964 * @example
965 *     #URL_IMAGE|fabrique_miniature_image{128}
966 *
967 *     Applique l'équivalent de :
968 *     #URL_IMAGE|image_reduire{128}|extraire_attribut{src}
969 *         |explode{?}|array_shift|timestamp|balise_img
970 *
971 * @param string $fichier
972 *     Chemin du fichier
973 * @param int $taille
974 *     Taille de réduction de l'image
975 * @return string
976 *     Balise HTML IMG de l'image réduite et à jour
977 */
978function filtre_fabrique_miniature_image($fichier, $taille=256) {
979        $im = filtrer('image_reduire', $fichier, $taille);
980        $im = extraire_attribut($im, 'src');
981        $im = explode('?', $im);
982        $im = array_shift($im);
983        $im = timestamp($im);
984        $im = filtrer('balise_img', $im);
985        return $im;
986}
987
988
989
990/**
991 * Retourne un tableau table_sql=>Nom des objets de SPIP
992 * complété des objets declares dans la fabrique ainsi
993 * que de tables indiquees même si elles ne font pas parties
994 * de declarations connues.
995 *
996 * @param array $objets_fabrique
997 *              Déclaration d'objets de la fabrique
998 * @param array $inclus
999 *              Liste de tables SQL que l'on veut forcement presentes
1000 *              meme si l'objet n'est pas declare
1001 * @param array $exclus
1002 *              Liste de tables SQL que l'on veut forcement exclues
1003 *              meme si l'objet n'est pas declare
1004 * @return array
1005 *              Tableau table_sql => Nom
1006**/
1007function filtre_fabrique_lister_objets_editoriaux($objets_fabrique, $inclus=array(), $exclus=array()) {
1008
1009        // les objets existants
1010        $objets = lister_tables_objets_sql();
1011        foreach ($objets as $sql => $o) {
1012                if ($o['editable']) {
1013                        $liste[$sql] = _T($o['texte_objets']);
1014                }
1015        }
1016        unset($objets);
1017
1018        // les objets de la fabrique
1019        foreach ($objets_fabrique as $o) {
1020                if (isset($o['table']) and !isset($liste[$o['table']])) {
1021                        $liste[ $o['table'] ] = $o['nom'];
1022                }
1023        }
1024
1025        // des objets qui n'existent pas mais qui sont actuellement coches dans la saisie
1026        foreach ($inclus as $sql) {
1027                if (!isset($liste[$sql])) {
1028                        $liste[$sql] = $sql; // on ne connait pas le nom
1029                }
1030        }
1031
1032        // tables forcement exclues
1033        foreach ($exclus as $sql) {
1034                unset($liste[$sql]);
1035        }
1036        // enlever un eventuel element vide
1037        unset($liste['']);
1038
1039        asort($liste);
1040
1041        return $liste;
1042}
1043
1044
1045/**
1046 * Retourne le code pour tester un type d'autorisation
1047 *
1048 * @param string $type
1049 *              Quelle type d'autorisation est voulue
1050 * @return string
1051 *              Code de test de l'autorisation
1052**/
1053function fabrique_code_autorisation($type) {
1054        switch($type) {
1055
1056                case "jamais":
1057                        return "false";
1058                        break;
1059
1060                case "toujours":
1061                        return "true";
1062                        break;
1063
1064                case "redacteur":
1065                        return "in_array(\$qui['statut'], array('0minirezo', '1comite'))";
1066                        break;
1067
1068                case "administrateur_restreint":
1069                        return "\$qui['statut'] == '0minirezo'";
1070                        break;
1071
1072                case "administrateur":
1073                        return "\$qui['statut'] == '0minirezo' AND !\$qui['restreint']";
1074                        break;
1075
1076                case "webmestre":
1077                        return "autoriser('webmestre', '', '', \$qui)";
1078                        break;
1079
1080        }
1081
1082        return "";
1083}
1084
1085/**
1086 * Retourne la valeur de type d'autorisation
1087 * qui s'applique par defaut pour une autorisation donnee
1088 *
1089 * @param string $autorisation
1090 *              Nom de l'autorisation (objet et objets remplacent le veritable type et nom d'objet)
1091 * @return string
1092 *              Type d'autorisation par defaut (jamais, toujours, redacteur, ...)
1093**/
1094function fabrique_autorisation_defaut($autorisation) {
1095        switch($autorisation) {
1096                case 'objet_voir':
1097                        return "toujours";
1098                        break;
1099
1100                case 'objet_creer':
1101                case 'objet_modifier':
1102                        return "redacteur";
1103                        break;
1104
1105                case 'objet_supprimer':
1106                case 'associerobjet':
1107                        return "administrateur";
1108                        break;
1109        }
1110}
1111
1112/**
1113 * Retourne le code d'autorisation indique
1114 * sinon celui par defaut pour une fonction d'autorisation
1115 *
1116 * @param array $autorisations
1117 *              Les autorisations renseignees par l'interface pour un objet
1118 * @param string $autorisation
1119 *              Le nom de l'autorisation souhaitee
1120 * @return string
1121 *              Code de l'autorisation
1122**/
1123function fabrique_code_autorisation_defaut($autorisations, $autorisation) {
1124        if (!$autorisation) return "";
1125
1126        // trouver le type d'autorisation souhaitee, soit indiquee, soit par defaut
1127        if (!isset($autorisations[$autorisation]) OR !$type = $autorisations[$autorisation]) {
1128                $type = fabrique_autorisation_defaut($autorisation);
1129        }
1130
1131        // retourner le code PHP correspondant
1132        return fabrique_code_autorisation($type);
1133}
1134
1135/**
1136 * Retourne le type pour le nom d'une fonction d'autorisation
1137 * 'article' => 'article'
1138 * 'truc_muche' => 'trucmuche'
1139 *
1140 * @param string $type
1141 *              Type ou objet
1142 * @return string
1143 *              Type pour le nom d'autorisation
1144**/
1145function fabrique_type_autorisation($type) {
1146        return str_replace('_', '', $type);
1147}
1148
1149?>
Note: See TracBrowser for help on using the repository browser.