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