[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / ecrire / public / styliser.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 de la sélection d'un squelette depuis son nom parmi les
15 * chemins connus de SPIP
16 *
17 * Recherche par exemple `contenu\xx` et en absence utilisera `contenu\dist`
18 *
19 * @package SPIP\Core\Public\Styliser
20 **/
21
22 if (!defined('_ECRIRE_INC_VERSION')) {
23 return;
24 }
25
26 // Ce fichier doit imperativement definir la fonction ci-dessous:
27
28 /**
29 * Déterminer le squelette qui sera utilisé pour rendre la page ou le bloc
30 * à partir de `$fond` et du `$contetxe`
31 *
32 * Actuellement tous les squelettes se terminent par `.html`
33 * pour des raisons historiques, ce qui est trompeur
34 *
35 * @param string $fond
36 * @param array $contexte
37 * @param string $lang
38 * @param string $connect
39 * @return array
40 */
41 function public_styliser_dist($fond, $contexte, $lang = '', $connect = '') {
42 static $styliser_par_z;
43
44 // s'assurer que le fond est licite
45 // car il peut etre construit a partir d'une variable d'environnement
46 if (strpos($fond, "../") !== false or strncmp($fond, '/', 1) == 0) {
47 $fond = "404";
48 }
49
50 // Choisir entre $fond-dist.html, $fond=7.html, etc?
51 $id_rubrique = 0;
52 // Chercher le fond qui va servir de squelette
53 if ($r = quete_rubrique_fond($contexte)) {
54 list($id_rubrique, $lang) = $r;
55 }
56
57 // trouver un squelette du nom demande
58 // ne rien dire si on ne trouve pas,
59 // c'est l'appelant qui sait comment gerer la situation
60 // ou les plugins qui feront mieux dans le pipeline
61 $squelette = trouver_fond($fond, "", true);
62 $ext = $squelette['extension'];
63
64 $flux = array(
65 'args' => array(
66 'id_rubrique' => $id_rubrique,
67 'ext' => $ext,
68 'fond' => $fond,
69 'lang' => $lang,
70 'contexte' => $contexte, // le style d'un objet peut dependre de lui meme
71 'connect' => $connect
72 ),
73 'data' => $squelette['fond'],
74 );
75
76 if (test_espace_prive() or defined('_ZPIP')) {
77 if (!$styliser_par_z) {
78 $styliser_par_z = charger_fonction('styliser_par_z', 'public');
79 }
80 $flux = $styliser_par_z($flux);
81 }
82
83 $flux = styliser_par_objets($flux);
84
85 // pipeline styliser
86 $squelette = pipeline('styliser', $flux);
87
88 return array($squelette, $ext, $ext, "$squelette.$ext");
89 }
90
91 /**
92 * Cherche à échafauder un squelette générique pour un objet éditorial si
93 * aucun squelette approprié n'a été trouvé
94 *
95 * Échaffaude seulement pour des appels à `prive/objets/liste/` ou
96 * `prive/objets/contenu/` pour lesquels aucun squelette n'a été trouvé,
97 * et uniquement si l'on est dans l'espace privé.
98 *
99 * @see prive_echafauder_dist()
100 *
101 * @param array $flux
102 * Données du pipeline styliser
103 * @return array
104 * Données du pipeline styliser
105 **/
106 function styliser_par_objets($flux) {
107 if (test_espace_prive()
108 and !$squelette = $flux['data']
109 and strncmp($flux['args']['fond'], 'prive/objets/', 13) == 0
110 and $echafauder = charger_fonction('echafauder', 'prive', true)
111 ) {
112 if (strncmp($flux['args']['fond'], 'prive/objets/liste/', 19) == 0) {
113 $table = table_objet(substr($flux['args']['fond'], 19));
114 $table_sql = table_objet_sql($table);
115 $objets = lister_tables_objets_sql();
116 if (isset($objets[$table_sql])) {
117 $flux['data'] = $echafauder($table, $table, $table_sql, "prive/objets/liste/objets", $flux['args']['ext']);
118 }
119 }
120 if (strncmp($flux['args']['fond'], 'prive/objets/contenu/', 21) == 0) {
121 $type = substr($flux['args']['fond'], 21);
122 $table = table_objet($type);
123 $table_sql = table_objet_sql($table);
124 $objets = lister_tables_objets_sql();
125 if (isset($objets[$table_sql])) {
126 $flux['data'] = $echafauder($type, $table, $table_sql, "prive/objets/contenu/objet", $flux['args']['ext']);
127 }
128 }
129 }
130
131 return $flux;
132 }
133
134 /**
135 * Calcul de la rubrique associée à la requête
136 * (sélection de squelette spécifique par id_rubrique & lang)
137 *
138 * Êttention, on repète cela à chaque inclusion,
139 * on optimise donc pour ne faire la recherche qu'une fois
140 * par contexte semblable du point de vue des id_xx
141 *
142 * @staticvar array $liste_objets
143 * @param array $contexte
144 * @return array
145 */
146 function quete_rubrique_fond($contexte) {
147 static $liste_objets = null;
148 static $quete = array();
149 if (is_null($liste_objets)) {
150 $liste_objets = array();
151 include_spip('inc/urls');
152 include_spip('public/quete');
153 $l = urls_liste_objets(false);
154 // placer la rubrique en tete des objets
155 $l = array_diff($l, array('rubrique'));
156 array_unshift($l, 'rubrique');
157 foreach ($l as $objet) {
158 $id = id_table_objet($objet);
159 if (!isset($liste_objets[$id])) {
160 $liste_objets[$id] = objet_type($objet, false);
161 }
162 }
163 }
164 $c = array_intersect_key($contexte, $liste_objets);
165 if (!count($c)) {
166 return false;
167 }
168
169 $c = array_map('intval', $c);
170 $s = serialize($c);
171 if (isset($quete[$s])) {
172 return $quete[$s];
173 }
174
175 if (isset($c['id_rubrique']) and $r = $c['id_rubrique']) {
176 unset($c['id_rubrique']);
177 $c = array('id_rubrique' => $r) + $c;
178 }
179
180 foreach ($c as $_id => $id) {
181 if ($id
182 and $row = quete_parent_lang(table_objet_sql($liste_objets[$_id]), $id)
183 ) {
184 $lang = isset($row['lang']) ? $row['lang'] : '';
185 if ($_id == 'id_rubrique' or (isset($row['id_rubrique']) and $id = $row['id_rubrique'])) {
186 return $quete[$s] = array($id, $lang);
187 }
188 }
189 }
190
191 return $quete[$s] = false;
192 }