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

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

Si une saisie date est présente, on crée le code de normalisation adéquat…
il faudrait mettre la dépendance au plugin verifier (si c'est pas déjà fait).

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