79f657cbb1bb9796275581c3893f62ed0e4c1b5a
[lhc/web/www.git] / www / ecrire / inc / chercher_rubrique.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2017 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 /**
14 * Gestion du sélecteur de rubrique pour les objets éditoriaux s'insérant
15 * dans une hiérarchie de rubriques
16 *
17 * @package SPIP\Core\Rubriques
18 **/
19
20 if (!defined('_ECRIRE_INC_VERSION')) {
21 return;
22 }
23
24 define('_SPIP_SELECT_RUBRIQUES', 20); /* mettre 100000 pour desactiver ajax */
25
26
27 /**
28 * Sélecteur de rubriques pour l'espace privé
29 *
30 * @uses selecteur_rubrique_html()
31 * @uses selecteur_rubrique_ajax()
32 *
33 * @param int $id_rubrique
34 * Identifiant de rubrique courante (0 si NEW)
35 * @param string $type
36 * Type de l'objet à placer.
37 *
38 * Une rubrique peut aller à la racine mais pas dans elle-même,
39 * les articles et sites peuvent aller n'importe où (défaut),
40 * et les brèves dans les secteurs.
41 * @param bool $restreint
42 * True pour indiquer qu'il faut limiter les rubriques affichées
43 * aux rubriques éditables par l'admin restreint
44 * @param int $idem
45 * En mode rubrique, identifiant de soi-même
46 * @param string $do
47 * Type d'action
48 * @return string
49 * Code HTML du sélecteur
50 **/
51 function inc_chercher_rubrique_dist($id_rubrique, $type, $restreint, $idem = 0, $do = 'aff') {
52 if (sql_countsel('spip_rubriques') < 1) {
53 return '';
54 }
55
56 // Mode sans Ajax :
57 // - soit parce que le cookie ajax n'est pas la
58 // - soit parce qu'il y a peu de rubriques
59 if (_SPIP_AJAX < 1
60 or $type == 'breve'
61 or sql_countsel('spip_rubriques') < _SPIP_SELECT_RUBRIQUES
62 ) {
63 return selecteur_rubrique_html($id_rubrique, $type, $restreint, $idem);
64 } else {
65 return selecteur_rubrique_ajax($id_rubrique, $type, $restreint, $idem, $do);
66 }
67
68 }
69
70 // compatibilite pour extensions qui utilisaient l'ancien nom
71 $GLOBALS['selecteur_rubrique'] = 'inc_chercher_rubrique_dist';
72
73 /**
74 * Styles appliqués sur le texte d'une rubrique pour créer visuellement
75 * une indentation en fonction de sa profondeur dans le sélecteur
76 *
77 * @param int $i
78 * Profondeur de la rubrique
79 * @return array
80 * Liste (classe CSS, styles en ligne, Espaces insécables)
81 **/
82 function style_menu_rubriques($i) {
83
84 $espace = '';
85 $style = '';
86 for ($count = 1; $count <= $i; $count++) {
87 $espace .= "&nbsp;&nbsp;&nbsp;&nbsp;";
88 }
89 if ($i == 1) {
90 $espace = "";
91 }
92 $class = "niveau_$i";
93
94 return array($class, $style, $espace);
95 }
96
97 /**
98 * Sélecteur de sous rubriques pour l'espace privé
99 *
100 * @uses style_menu_rubriques()
101 *
102 * @param int $id_rubrique
103 * Identifiant de parente
104 * @param int $root
105 * @param int $niv
106 * @param array $data
107 * @param array $enfants
108 * @param int $exclus
109 * @param bool $restreint
110 * True pour indiquer qu'il faut limiter les rubriques affichées
111 * aux rubriques éditables par l'admin restreint
112 * @param string $type
113 * Type de l'objet à placer.
114 * @return string
115 * Code HTML du sélecteur
116 **/
117 function sous_menu_rubriques($id_rubrique, $root, $niv, &$data, &$enfants, $exclus, $restreint, $type) {
118 static $decalage_secteur;
119
120 // Si on a demande l'exclusion ne pas descendre dans la rubrique courante
121 if ($exclus > 0
122 and $root == $exclus
123 ) {
124 return '';
125 }
126
127 // en fonction du niveau faire un affichage plus ou moins kikoo
128
129 // selected ?
130 $selected = ($root == $id_rubrique) ? ' selected="selected"' : '';
131
132 // le style en fonction de la profondeur
133 list($class, $style, $espace) = style_menu_rubriques($niv);
134
135 $class .= " selec_rub";
136
137 // creer l'<option> pour la rubrique $root
138
139 if (isset($data[$root])) # pas de racine sauf pour les rubriques
140 {
141 $r = "<option$selected value='$root' class='$class' style='$style'>$espace"
142 . $data[$root]
143 . '</option>' . "\n";
144 } else {
145 $r = '';
146 }
147
148 // et le sous-menu pour ses enfants
149 $sous = '';
150 if (isset($enfants[$root])) {
151 foreach ($enfants[$root] as $sousrub) {
152 $sous .= sous_menu_rubriques($id_rubrique, $sousrub,
153 $niv + 1, $data, $enfants, $exclus, $restreint, $type);
154 }
155 }
156
157 // si l'objet a deplacer est publie, verifier qu'on a acces aux rubriques
158 if ($restreint and $root != $id_rubrique and !autoriser('publierdans', 'rubrique', $root)) {
159 return $sous;
160 }
161
162 // et voila le travail
163 return $r . $sous;
164 }
165
166 /**
167 * Sélecteur de rubriques pour l'espace privé en mode classique (menu)
168 *
169 * @uses sous_menu_rubriques()
170 *
171 * @param int $id_rubrique
172 * Identifiant de rubrique courante (0 si NEW)
173 * @param string $type
174 * Type de l'objet à placer.
175 * @param bool $restreint
176 * True pour indiquer qu'il faut limiter les rubriques affichées
177 * aux rubriques éditables par l'admin restreint
178 * @param int $idem
179 * En mode rubrique, identifiant de soi-même
180 * @return string
181 * Code HTML du sélecteur
182 **/
183 function selecteur_rubrique_html($id_rubrique, $type, $restreint, $idem = 0) {
184 $data = array();
185 if ($type == 'rubrique' and autoriser('publierdans', 'rubrique', 0)) {
186 $data[0] = _T('info_racine_site');
187 }
188 # premier choix = neant
189 # si auteur (rubriques restreintes)
190 # ou si creation avec id_rubrique=0
191 elseif ($type == 'auteur' or !$id_rubrique) {
192 $data[0] = '&nbsp;';
193 }
194
195 //
196 // creer une structure contenant toute l'arborescence
197 //
198
199 include_spip('base/abstract_sql');
200 $q = sql_select("id_rubrique, id_parent, titre, statut, lang, langue_choisie", "spip_rubriques",
201 ($type == 'breve' ? ' id_parent=0 ' : ''), '', "0+titre,titre");
202 while ($r = sql_fetch($q)) {
203 if (autoriser('voir', 'rubrique', $r['id_rubrique'])) {
204 // titre largeur maxi a 50
205 $titre = couper(supprimer_tags(typo($r['titre'])) . " ", 50);
206 if ($GLOBALS['meta']['multi_rubriques'] == 'oui'
207 and ($r['langue_choisie'] == "oui" or $r['id_parent'] == 0)
208 ) {
209 $titre .= ' [' . traduire_nom_langue($r['lang']) . ']';
210 }
211 $data[$r['id_rubrique']] = $titre;
212 $enfants[$r['id_parent']][] = $r['id_rubrique'];
213 if ($id_rubrique == $r['id_rubrique']) {
214 $id_parent = $r['id_parent'];
215 }
216 }
217 }
218
219 // si une seule rubrique comme choix possible,
220 // inutile de mettre le selecteur sur un choix vide par defaut
221 // sauf si le selecteur s'adresse a une rubrique puisque on peut la mettre a la racine dans ce cas
222 if (count($data) == 2
223 and isset($data[0])
224 and !in_array($type, array('auteur', 'rubrique'))
225 and !$id_rubrique
226 ) {
227 unset($data[0]);
228 }
229
230
231 $opt = sous_menu_rubriques($id_rubrique, 0, 0, $data, $enfants, $idem, $restreint, $type);
232 $att = " id='id_parent' name='id_parent'\nclass='selecteur_parent verdana1'";
233
234 if (preg_match(',^<option[^<>]*value=.(\d*).[^<>]*>([^<]*)</option>$,', $opt, $r)) {
235 $r = "<input$att type='hidden' value='" . $r[1] . "' />" . $r[2];
236 } else {
237 $r = "<select" . $att . " size='1'>\n$opt</select>\n";
238 }
239
240 # message pour neuneus (a supprimer ?)
241 # if ($type != 'auteur' AND $type != 'breve')
242 # $r .= "\n<br />"._T('texte_rappel_selection_champs');
243
244 return $r;
245 }
246
247 /**
248 * Sélecteur de rubrique pour l'espace privé, en mode AJAX
249 *
250 * @note
251 * `$restreint` indique qu'il faut limiter les rubriques affichées
252 * aux rubriques éditables par l'admin restreint... or, ca ne marche pas.
253 * Pour la version HTML c'est bon (cf. ci-dessus), mais pour l'ajax...
254 * je laisse ça aux spécialistes de l'ajax & des admins restreints
255 *
256 * Toutefois c'est juste un pb d'interface, car question securite
257 * la vérification est faite à l'arrivée des données (Fil)
258 *
259 * @uses construire_selecteur()
260 * @see exec_selectionner_dist() Pour l'obtention du contenu AJAX ensuite
261 *
262 * @param int $id_rubrique
263 * Identifiant de rubrique courante (0 si NEW)
264 * @param string $type
265 * Type de l'objet à placer.
266 * @param bool $restreint
267 * True pour indiquer qu'il faut limiter les rubriques affichées
268 * aux rubriques éditables par l'admin restreint. Ne fonctionne actuellement pas ici.
269 * @param int $idem
270 * En mode rubrique, identifiant de soi-même
271 * @param string $do
272 * Type d'action
273 * @return string
274 * Code HTML du sélecteur
275 */
276 function selecteur_rubrique_ajax($id_rubrique, $type, $restreint, $idem = 0, $do) {
277
278 if ($id_rubrique) {
279 $titre = sql_getfetsel("titre", "spip_rubriques", "id_rubrique=" . intval($id_rubrique));
280 } else {
281 if ($type == 'auteur') {
282 $titre = '&nbsp;';
283 } else {
284 $titre = _T('info_racine_site');
285 }
286 }
287
288 $titre = str_replace('&amp;', '&', entites_html(textebrut(typo($titre))));
289 $init = " disabled='disabled' type='text' value=\"" . $titre . "\"\nstyle='width:300px;'";
290
291 $url = generer_url_ecrire('selectionner', "id=$id_rubrique&type=$type&do=$do"
292 . (!$idem ? '' : "&exclus=$idem")
293 . ($restreint ? "" : "&racine=oui")
294 . (isset($GLOBALS['var_profile']) ? '&var_profile=1' : ''));
295
296
297 return construire_selecteur($url, '', 'selection_rubrique', 'id_parent', $init, $id_rubrique);
298 }
299
300 /**
301 * Construit un bloc permettant d'activer le sélecteur de rubrique AJAX
302 *
303 * Construit un bloc comportant une icone clicable avec image animée à côté
304 * pour charger en Ajax du code à mettre sous cette icone.
305 *
306 * @note
307 * Attention: changer le onclick si on change le code Html.
308 * (la fonction JS charger_node ignore l'attribut id qui ne sert en fait pas;
309 * getElement en mode Ajax est trop couteux).
310 *
311 * @param string $url
312 * URL qui retournera le contenu du sélecteur en AJAX
313 * @param string $js
314 * Code javascript ajouté sur onclick
315 * @param string $idom
316 * Identifiant donné à l'image activant l'ajax et au block recevant son contenu
317 * @param string $name
318 * Nom du champ à envoyer par le formulaire
319 * @param string $init
320 * Code HTML à l'intérieur de l'input titreparent
321 * @param int $id
322 * Valeur actuelle du champ
323 * @return string
324 * Code HTML du sélecteur de rubrique AJAX
325 **/
326 function construire_selecteur($url, $js, $idom, $name, $init = '', $id = 0) {
327 $icone = (strpos($idom, 'auteur') !== false) ? 'auteur-24.png' : 'rechercher-20.png';
328
329 return
330 "<div class='rubrique_actuelle'><a href='#' onclick=\""
331 . $js
332 . "return charger_node_url_si_vide('"
333 . $url
334 . "', this.parentNode.nextSibling, this.nextSibling,'',event)\" title='" . attribut_html(_T('titre_image_selecteur')) . "'><img src='"
335 . chemin_image($icone)
336 . "'\nstyle='vertical-align: middle;' alt='" . attribut_html(_T('titre_image_selecteur')) . "' /></a><img src='"
337 . chemin_image('searching.gif')
338 . "' id='img_"
339 . $idom
340 . "'\nstyle='visibility: hidden;' alt='*' />"
341 . "<input id='titreparent' name='titreparent'"
342 . $init
343 . " />"
344 . "<input type='hidden' id='$name' name='$name' value='"
345 . $id
346 . "' /><div class='nettoyeur'></div></div><div id='"
347 . $idom
348 . "'\nstyle='display: none;'></div>";
349 }