[SPIP] v3.2.1-->v3.2.2
[lhc/web/www.git] / www / ecrire / action / menu_rubriques.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 de l'action d'affichage du navigateur de rubrique du bandeau
15 *
16 * @package SPIP\Core\Rubriques
17 **/
18
19 if (!defined('_ECRIRE_INC_VERSION')) {
20 return;
21 }
22
23 include_spip('inc/autoriser');
24 include_spip('inc/texte');
25 include_spip('inc/filtres');
26
27 /**
28 * Action d'affichage en ajax du navigateur de rubrique du bandeau
29 *
30 * @uses gen_liste_rubriques()
31 * @uses menu_rubriques()
32 *
33 * @return string
34 * Code HTML présentant la liste des rubriques
35 **/
36 function action_menu_rubriques_dist() {
37
38 // si pas acces a ecrire, pas acces au menu
39 // on renvoi un 401 qui fait echouer la requete ajax silencieusement
40 if (!autoriser('ecrire')) {
41 $retour = "<ul class='cols_1'><li class='toutsite'><a href='" . generer_url_ecrire('accueil') . "'>" . _T('public:lien_connecter') . "</a></li></ul>";
42 include_spip('inc/actions');
43 ajax_retour($retour);
44 exit;
45 }
46
47 if ($date = intval(_request('date'))) {
48 header("Last-Modified: " . gmdate("D, d M Y H:i:s", $date) . " GMT");
49 }
50
51 $r = gen_liste_rubriques();
52 if (!$r
53 and isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
54 and !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/')
55 ) {
56 include_spip('inc/headers');
57 header('Content-Type: text/html; charset=' . $GLOBALS['meta']['charset']);
58 http_status(304);
59 exit;
60 } else {
61 include_spip('inc/actions');
62 $ret = menu_rubriques();
63 ajax_retour($ret);
64 }
65 }
66
67 /**
68 * Retourne une liste HTML des rubriques et rubriques enfants
69 *
70 * @param bool $complet
71 * - false pour n'avoir que le bouton racine «plan du site»
72 * - true pour avoir l'ensemble des rubriques en plus
73 *
74 * @return string
75 * Code HTML présentant la liste des rubriques
76 **/
77 function menu_rubriques($complet = true) {
78 $ret = "<li class='toutsite'><a href='" . generer_url_ecrire('plan') . "'>" . _T('info_tout_site') . "</a></li>";
79
80 if (!$complet) {
81 return "<ul class='cols_1'>$ret\n</ul>\n";
82 }
83
84 if (!isset($GLOBALS['db_art_cache'])) {
85 gen_liste_rubriques();
86 }
87 $arr_low = extraire_article(0, $GLOBALS['db_art_cache']);
88
89 $total_lignes = $i = sizeof($arr_low);
90
91 if ($i > 0) {
92 $nb_col = min(8, ceil($total_lignes / 30));
93 if ($nb_col <= 1) {
94 $nb_col = ceil($total_lignes / 10);
95 }
96 foreach ($arr_low as $id_rubrique => $titre_rubrique) {
97 if (autoriser('voir', 'rubrique', $id_rubrique)) {
98 $ret .= bandeau_rubrique($id_rubrique, $titre_rubrique, $i);
99 $i++;
100 }
101 }
102
103 $ret = "<ul class='cols_$nb_col'>"
104 . $ret
105 . "\n</ul>\n";
106 } else {
107 $ret = "<ul class='cols_1'>$ret\n</ul>\n";
108 }
109
110 return $ret;
111 }
112
113 /**
114 * Retourne une liste HTML des rubriques enfants d'une rubrique
115 *
116 * @uses extraire_article()
117 *
118 * @param int $id_rubrique
119 * Identifiant de la rubrique parente
120 * @param string $titre_rubrique
121 * Titre de cette rubrique
122 * @param int $zdecal
123 * Décalage vertical, en nombre d'élément
124 *
125 * @return string
126 * Code HTML présentant la liste des rubriques
127 **/
128 function bandeau_rubrique($id_rubrique, $titre_rubrique, $zdecal) {
129 static $zmax = 6;
130
131 $nav = "<a href='"
132 . generer_url_entite($id_rubrique, 'rubrique', '', '', false)
133 . "'>"
134 . supprimer_tags(preg_replace(',[\x00-\x1f]+,', ' ', $titre_rubrique))
135 . "</a>\n";
136
137 // Limiter volontairement le nombre de sous-menus
138 if (!(--$zmax)) {
139 $zmax++;
140
141 return "\n<li>$nav</li>";
142 }
143
144 $arr_rub = extraire_article($id_rubrique, $GLOBALS['db_art_cache']);
145 $i = sizeof($arr_rub);
146 if (!$i) {
147 $zmax++;
148
149 return "\n<li>$nav</li>";
150 }
151
152
153 $nb_col = 1;
154 if ($nb_rub = count($arr_rub)) {
155 $nb_col = min(10, max(1, ceil($nb_rub / 10)));
156 }
157 $ret = "<li class='haschild'>$nav<ul class='cols_$nb_col'>";
158 foreach ($arr_rub as $id_rub => $titre_rub) {
159 if (autoriser('voir', 'rubrique', $id_rub)) {
160 $titre = supprimer_numero(typo($titre_rub));
161 $ret .= bandeau_rubrique($id_rub, $titre, $zdecal + $i);
162 $i++;
163 }
164 }
165 $ret .= "</ul></li>\n";
166 $zmax++;
167
168 return $ret;
169 }
170
171
172 /**
173 * Obtient la liste des rubriques enfants d'une rubrique, prise dans le cache
174 * du navigateur de rubrique
175 *
176 * @see gen_liste_rubriques() pour le calcul du cache
177 *
178 * @param int $id_p
179 * Identifiant de la rubrique parente des articles
180 * @param array $t
181 * Cache des rubriques
182 * @return array
183 * Liste des rubriques enfants de la rubrique (et leur titre)
184 **/
185 function extraire_article($id_p, $t) {
186 return array_key_exists($id_p, $t) ? $t[$id_p] : array();
187 }
188
189 /**
190 * Génère le cache de la liste des rubriques pour la navigation du bandeau
191 *
192 * Le cache, qui comprend pour chaque rubrique ses rubriques enfants et leur titre, est :
193 *
194 * - réactualisé en fonction de la meta `date_calcul_rubriques`
195 * - mis en cache dans le fichier défini par la constante `_CACHE_RUBRIQUES`
196 * - stocké également dans la globale `db_art_cache`
197 *
198 * @return bool true.
199 **/
200 function gen_liste_rubriques() {
201
202 include_spip('inc/config');
203 // ici, un petit fichier cache ne fait pas de mal
204 $last = lire_config('date_calcul_rubriques', 0);
205 if (lire_fichier(_CACHE_RUBRIQUES, $cache)) {
206 list($date, $GLOBALS['db_art_cache']) = @unserialize($cache);
207 if ($date == $last) {
208 return false;
209 } // c'etait en cache :-)
210 }
211 // se restreindre aux rubriques utilisees recemment +secteurs
212
213 $where = sql_in_select("id_rubrique", "id_rubrique", "spip_rubriques", "", "", "id_parent=0 DESC, date DESC",
214 _CACHE_RUBRIQUES_MAX);
215
216 // puis refaire la requete pour avoir l'ordre alphabetique
217
218 $res = sql_select("id_rubrique, titre, id_parent", "spip_rubriques", $where, '', 'id_parent, 0+titre, titre');
219
220 // il ne faut pas filtrer le autoriser voir ici
221 // car on met le resultat en cache, commun a tout le monde
222 $GLOBALS['db_art_cache'] = array();
223 while ($r = sql_fetch($res)) {
224 $t = sinon($r['titre'], _T('ecrire:info_sans_titre'));
225 $GLOBALS['db_art_cache'][$r['id_parent']][$r['id_rubrique']] = supprimer_numero(typo($t));
226 }
227
228 $t = array($last ? $last : time(), $GLOBALS['db_art_cache']);
229 ecrire_fichier(_CACHE_RUBRIQUES, serialize($t));
230
231 return true;
232 }