[SPIP] ~maj v3.0.14-->v3.0.17
[ptitvelo/web/www.git] / www / prive / formulaires / selecteur / generique_fonctions.php
1 <?php
2
3 if (!defined('_ECRIRE_INC_VERSION')) return;
4
5 /*
6 * Fournit la liste des objets ayant un sélecteur
7 * Concrètement, va chercher tous les formulaires/selecteur/hierarchie-trucs.html
8 * Ensuite on ajoute les parents obligatoires éventuels
9 *
10 * @param array $whitelist Liste blanche décrivant les objets à lister
11 * @param array $blacklist Liste noire décrivant les objets à ne pas lister
12 * @return array Retourne un tableau de deux entrées listant les objets à lister et les objets sélectionnables
13 * selectionner : tableau des objets que l'on pourra sélectionner (avec un +)
14 * afficher : tableau des objets à afficher (mais pas forcément sélectionnables)
15 */
16 function selecteur_lister_objets($whitelist=array(), $blacklist=array()){
17 static $liste_selecteurs, $liste_parents;
18
19 if (!$liste_selecteurs){
20 $liste_selecteurs = find_all_in_path('formulaires/selecteur/', 'hierarchie-[\w]+[.]html$');
21 }
22 $objets_selectionner = array();
23 foreach ($liste_selecteurs as $fichier=>$chemin){
24 $objets_selectionner[] = preg_replace('/^hierarchie-([\w]+)[.]html$/', '$1', $fichier);
25 }
26
27 // S'il y a une whitelist on ne garde que ce qui est dedans
28 if (!empty($whitelist)){
29 $whitelist = array_map('table_objet', $whitelist);
30 $objets_selectionner = array_intersect($objets_selectionner, $whitelist);
31 }
32 // On supprime ce qui est dans la blacklist
33 $blacklist = array_map('table_objet', $blacklist);
34 // On enlève toujours la racine
35 $blacklist[] = 'racine';
36 $objets_selectionner = array_diff($objets_selectionner, $blacklist);
37
38 // Ensuite on cherche ce qu'on doit afficher : au moins ceux qu'on peut sélectionner
39 $objets_afficher = $objets_selectionner;
40
41 // Il faut alors chercher d'éventuels parents obligatoires en plus :
42 // lister-trucs-bidules.html => on doit afficher des "trucs" pour trouver des "bidules"
43 if (!$liste_parents){
44 $liste_parents = find_all_in_path('formulaires/selecteur/', 'lister-[\w]+-[\w]+[.]html$');
45 }
46 foreach ($liste_parents as $fichier=>$chemin){
47 preg_match('/^lister-([\w]+)-([\w]+)[.]html$/', $fichier, $captures);
48 $parent = $captures[1];
49 $type = $captures[2];
50 // Si le type fait partie de ce qu'on doit afficher alors on ajoute aussi le parent à l'affichage
51 if (in_array($type, $objets_afficher)){
52 $objets_afficher[] = $parent;
53 }
54 }
55
56 $objets = array(
57 'selectionner' => array_unique($objets_selectionner),
58 'afficher' => array_unique($objets_afficher),
59 );
60
61 return $objets;
62 }
63
64 /**
65 * Transformer un tableau d'entrees array("rubrique|9","article|8",...)
66 * en un tableau contenant uniquement les identifiants d'un type donne.
67 * Accepte aussi que les valeurs d'entrees soient une chaine brute
68 * "rubrique|9,article|8,..."
69 *
70 * @param array/string $selected liste des entrees : tableau ou chaine separee par des virgules
71 * @param string $type type de valeur a recuperer ('rubrique', 'article')
72 *
73 * @return array liste des identifiants trouves.
74 **/
75 function picker_selected($selected, $type=''){
76 $select = array();
77 $type = preg_replace(',\W,','',$type);
78
79 if ($selected and !is_array($selected))
80 $selected = explode(',', $selected);
81
82 if (is_array($selected))
83 foreach($selected as $value){
84 // Si c'est le bon format déjà
85 if (preg_match('/^([\w]+)[|]([0-9]+)$/', $value, $captures)){
86 $objet = $captures[1];
87 $id_objet = intval($captures[2]);
88
89 // Si on cherche un type et que c'est le bon, on renvoit un tableau que d'identifiants
90 if (is_string($type) AND $type == $objet AND ($id_objet OR in_array($objet, array('racine', 'rubrique')))){
91 $select[] = $id_objet;
92 }
93 elseif(!$type AND ($id_objet OR in_array($objet, array('racine', 'rubrique')))){
94 $select[] = array('objet' => $objet, 'id_objet' => $id_objet);
95 }
96 }
97 }
98 return $select;
99 }
100
101 /*
102 * Récupère des informations sur un objet pour pouvoir l'ajouter aux éléments sélectionnés
103 *
104 * @param string $ref Référence de l'objet à chercher, de la forme "type|id", par exemple "rubrique|123".
105 * @param mixed $rubriques_ou_objets Soit un booléen (pouvant être une chaîne vide aussi) indiquant que les rubriques sont sélectionnables soit un tableau complet des objets sélectionnables.
106 * @param bool $articles Booléen indiquant si les articles sont sélectionnables
107 */
108 function picker_identifie_id_rapide($ref, $rubriques_ou_objets=false, $articles=false){
109 include_spip('inc/json');
110 include_spip('inc/lien');
111
112 // On construit un tableau des objets sélectionnables suivant les paramètres
113 $objets = array();
114 if ($rubriques_ou_objets and is_array($rubriques_ou_objets)){
115 $objets = $rubriques_ou_objets;
116 }
117 else{
118 if ($rubriques_ou_objets){ $objets[] = 'rubriques'; }
119 if ($articles){ $objets[] = 'articles'; }
120 }
121
122 // Si la référence ne correspond à rien, c'est fini
123 if (!($match = typer_raccourci($ref))){
124 return json_export(false);
125 }
126 // Sinon on récupère les infos utiles
127 @list($type,,$id,,,,) = $match;
128
129 // On regarde si le type trouvé fait partie des objets sélectionnables
130 if (!in_array(table_objet($type), $objets)){
131 return json_export(false);
132 }
133
134 // Maintenant que tout est bon, on cherche les informations sur cet objet
135 include_spip('inc/filtres');
136 if (!$titre = generer_info_entite($id, $type, 'titre')){
137 return json_export(false);
138 }
139
140 // On simplifie le texte
141 $titre = attribut_html($titre);
142
143 return json_export(array('type' => $type, 'id' => "$type|$id", 'titre' => $titre));
144 }
145
146 /**
147 * Determiner si une rubrique a des enfants a afficher ou non
148 * on test d'abord si la rubrique a des sous rubriques, et sinon on regarde les autrs types selectionnables
149 * et on regarde la rubrique contient certains de ces objets
150 *
151 * Pour optimiser, la fonction calcule sa valeur sur toute la fratrie d'un coup, puisqu'elle est appellee N fois
152 * pour toutes les rubriques d'un meme niveau
153 *
154 * @param $id_rubrique
155 * @param array $types
156 * @return string
157 */
158 function test_enfants_rubrique($id_rubrique,$types=array()){
159 static $has_child = array();
160 if (!isset($has_child[$id_rubrique])){
161 $types = (is_array($types)?array_filter($types):array());
162 // recuperer tous les freres et soeurs de la rubrique visee
163 $id_parent = sql_getfetsel('id_parent','spip_rubriques','id_rubrique='.intval($id_rubrique));
164 $fratrie = sql_allfetsel('id_rubrique','spip_rubriques','id_parent='.intval($id_parent));
165 $fratrie = array_map('reset',$fratrie);
166 $has = sql_allfetsel("DISTINCT id_parent","spip_rubriques",sql_in('id_parent',$fratrie));
167 $has = array_map('reset',$has);
168 $fratrie = array_diff($fratrie,$has);
169 while (count($fratrie) AND is_array($types) AND count($types)){
170 $type = array_shift($types);
171 $h = sql_allfetsel("DISTINCT id_rubrique",table_objet_sql($type),sql_in('id_rubrique',$fratrie));
172 $h = array_map('reset',$h);
173 $has = array_merge($has,$h);
174 $fratrie = array_diff($fratrie,$h);
175 }
176 if (count($has))
177 $has_child = $has_child + array_combine($has,array_pad(array(),count($has),true));
178 if (count($fratrie))
179 $has_child = $has_child + array_combine($fratrie,array_pad(array(),count($fratrie),false));
180 }
181
182 return $has_child[$id_rubrique]?' ':'';
183 }
184
185 ?>