[SPIP] ~v3.0.20-->v3.0.25
[lhc/web/clavette_www.git] / www / ecrire / public / styliser_par_z.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2016 *
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 if (!defined("_ECRIRE_INC_VERSION")) return;
15
16 /**
17 * Fonction Page automatique a partir de contenu/xx
18 *
19 * @param array $flux
20 * @return array
21 */
22 function public_styliser_par_z_dist($flux){
23 static $prefix_path=null;
24 static $prefix_length;
25 static $z_blocs;
26 static $apl_constant;
27 static $page;
28 static $disponible = array();
29 static $echafauder;
30 static $prepend = "";
31
32 if (!isset($prefix_path)) {
33 $z_blocs = z_blocs(test_espace_prive());
34 if (test_espace_prive ()){
35 $prefix_path = "prive/squelettes/";
36 $prefix_length = strlen($prefix_path);
37 $apl_constant = '_ECRIRE_AJAX_PARALLEL_LOAD';
38 $page = 'exec';
39 $echafauder = charger_fonction('echafauder','prive',true);
40 define('_ZCORE_EXCLURE_PATH','');
41 }
42 else {
43 $prefix_path = "";
44 $prefix_length = 0;
45 $apl_constant = '_Z_AJAX_PARALLEL_LOAD';
46 $page = _SPIP_PAGE;
47 $echafauder = charger_fonction('echafauder','public',true);
48 define('_ZCORE_EXCLURE_PATH','\bprive|\bsquelettes-dist'.(defined('_DIR_PLUGIN_DIST')?'|\b'.rtrim(_DIR_PLUGIN_DIST,'/'):''));
49 }
50 $prepend = (defined('_Z_PREPEND_PATH')?_Z_PREPEND_PATH:"");
51 }
52 $z_contenu = reset($z_blocs); // contenu par defaut
53
54 $fond = $flux['args']['fond'];
55
56 if ($prepend OR strncmp($fond,$prefix_path,$prefix_length)==0) {
57 $fond = substr($fond, $prefix_length);
58 $squelette = $flux['data'];
59 $ext = $flux['args']['ext'];
60 // Ajax Parallel loading : ne pas calculer le bloc, mais renvoyer un js qui le loadera en ajax
61 if (defined('_Z_AJAX_PARALLEL_LOAD_OK')
62 AND $dir = explode('/',$fond)
63 AND count($dir)==2 // pas un sous repertoire
64 AND $dir = reset($dir)
65 AND in_array($dir,$z_blocs) // verifier deja qu'on est dans un bloc Z
66 AND defined($apl_constant)
67 AND in_array($dir,explode(',',constant($apl_constant))) // et dans un demande en APL
68 AND $pipe = z_trouver_bloc($prefix_path.$prepend,$dir,'z_apl',$ext) // et qui contient le squelette APL
69 ){
70 $flux['data'] = $pipe;
71 return $flux;
72 }
73
74 // surcharger aussi les squelettes venant de squelettes-dist/
75 if ($squelette AND !z_fond_valide($squelette)){
76 $squelette = "";
77 $echafauder = "";
78 }
79 if ($prepend){
80 $squelette = substr(find_in_path($prefix_path.$prepend."$fond.$ext"), 0, - strlen(".$ext"));
81 if ($squelette)
82 $flux['data'] = $squelette;
83 }
84
85 // gerer les squelettes non trouves
86 // -> router vers les /dist.html
87 // ou scaffolding ou page automatique les contenus
88 if (!$squelette){
89
90 // si on est sur un ?page=XX non trouve
91 if ($flux['args']['contexte'][$page] == $fond
92 OR $flux['args']['contexte']['type-page'] == $fond
93 OR ($fond=='sommaire' AND !$flux['args']['contexte'][$page])) {
94
95 // si on est sur un ?page=XX non trouve
96 // se brancher sur contenu/xx si il existe
97 // ou si c'est un objet spip, associe a une table, utiliser le fond homonyme
98 if (!isset($disponible[$fond]))
99 $disponible[$fond] = z_contenu_disponible($prefix_path.$prepend,$z_contenu,$fond,$ext,$echafauder);
100
101 if ($disponible[$fond])
102 $flux['data'] = substr(find_in_path($prefix_path."page.$ext"), 0, - strlen(".$ext"));
103 }
104
105 // echafaudage :
106 // si c'est un fond de contenu d'un objet en base
107 // generer un fond automatique a la volee pour les webmestres
108 elseif (strncmp($fond, "$z_contenu/", strlen($z_contenu)+1)==0){
109 $type = substr($fond,strlen($z_contenu)+1);
110 if (($type=='page') AND isset($flux['args']['contexte'][$page]))
111 $type = $flux['args']['contexte'][$page];
112 if (!isset($disponible[$type]))
113 $disponible[$type] = z_contenu_disponible($prefix_path.$prepend,$z_contenu,$type,$ext,$echafauder);
114 if (is_string($disponible[$type])) {
115 $flux['data'] = $disponible[$type];
116 }
117 elseif ($echafauder
118 AND include_spip('inc/autoriser')
119 AND isset($GLOBALS['visiteur_session']['statut']) // performance
120 AND autoriser('echafauder',$type)
121 AND $is = $disponible[$type]
122 AND is_array($is)) {
123 $flux['data'] = $echafauder($type,$is[0],$is[1],$is[2],$ext);
124 }
125 else{
126 $flux['data'] = ($disponible['404'] = z_contenu_disponible($prefix_path.$prepend,$z_contenu,'404',$ext,$echafauder));
127 }
128 }
129
130 // sinon, si on demande un fond non trouve dans un des autres blocs
131 // et si il y a bien un contenu correspondant ou echafaudable
132 // se rabbatre sur le dist.html du bloc concerne
133 else{
134 if ( $dir = explode('/',$fond)
135 AND $dir = reset($dir)
136 AND $dir !== $z_contenu
137 AND in_array($dir,$z_blocs)){
138 $type = substr($fond,strlen("$dir/"));
139 if (($type=='page') AND isset($flux['args']['contexte'][$page]))
140 $type = $flux['args']['contexte'][$page];
141 if ($type!=='page' AND !isset($disponible[$type]))
142 $disponible[$type] = z_contenu_disponible($prefix_path.$prepend,$z_contenu,$type,$ext,$echafauder);
143 if ($type=='page' OR $disponible[$type])
144 $flux['data'] = z_trouver_bloc($prefix_path.$prepend,$dir,'dist',$ext);
145 }
146 }
147 $squelette = $flux['data'];
148 }
149 // layout specifiques par type et compositions :
150 // body-article.html
151 // body-sommaire.html
152 // pour des raisons de perfo, les declinaisons doivent etre dans le
153 // meme dossier que body.html
154 if ($fond=='body' AND substr($squelette,-strlen($fond))==$fond){
155 if (isset($flux['args']['contexte']['type-page'])
156 AND (
157 (isset($flux['args']['contexte']['composition'])
158 AND file_exists(($f=$squelette."-".$flux['args']['contexte']['type-page']."-".$flux['args']['contexte']['composition']).".$ext"))
159 OR
160 file_exists(($f=$squelette."-".$flux['args']['contexte']['type-page']).".$ext")
161 ))
162 $flux['data'] = $f;
163 }
164 elseif ($fond=='structure'
165 AND z_sanitize_var_zajax()
166 AND $f = find_in_path($prefix_path.$prepend.'ajax'.".$ext")) {
167 $flux['data'] = substr($f,0,-strlen(".$ext"));
168 }
169 // chercher le fond correspondant a la composition
170 elseif (isset($flux['args']['contexte']['composition'])
171 AND (basename($fond)=='page' OR ($squelette AND substr($squelette,-strlen($fond))==$fond))
172 AND $dir = substr($fond,$prefix_length)
173 AND $dir = explode('/',$dir)
174 AND $dir = reset($dir)
175 AND in_array($dir,$z_blocs)
176 AND $f=find_in_path($prefix_path.$prepend.$fond."-".$flux['args']['contexte']['composition'].".$ext")){
177 $flux['data'] = substr($f,0,-strlen(".$ext"));
178 }
179 }
180 return $flux;
181 }
182
183 /**
184 * Lister les blocs de la page selon le contexte prive/public
185 *
186 * @param bool $espace_prive
187 * @return array
188 */
189 function z_blocs($espace_prive=false) {
190 if ($espace_prive)
191 return (isset($GLOBALS['z_blocs_ecrire'])?$GLOBALS['z_blocs_ecrire']:array('contenu','navigation','extra','head','hierarchie','top'));
192 return (isset($GLOBALS['z_blocs'])?$GLOBALS['z_blocs']:array('contenu'));
193 }
194
195 /**
196 * Verifier qu'un type a un contenu disponible,
197 * soit parcequ'il a un fond, soit parce qu'il est echafaudable
198 *
199 * @param string $prefix_path
200 * @param string $z_contenu
201 * @param string $type
202 * @param string $ext
203 * @param bool $echafauder
204 * @return mixed
205 */
206 function z_contenu_disponible($prefix_path,$z_contenu,$type,$ext,$echafauder=true){
207 if ($d = z_trouver_bloc($prefix_path,$z_contenu,$type,$ext))
208 return $d;
209 return $echafauder?z_echafaudable($type):false;
210 }
211
212 function z_fond_valide($squelette){
213 if (!_ZCORE_EXCLURE_PATH
214 OR !preg_match(',('._ZCORE_EXCLURE_PATH.')/,',$squelette))
215 return true;
216 return false;
217 }
218
219 /**
220 * Trouver un bloc qui peut etre sous le nom
221 * contenu/article.html
222 * ou
223 * contenu/contenu.article.html
224 *
225 * @param string $prefix_path
226 * chemin de base qui prefixe la recherche
227 * @param string $bloc
228 * nom du bloc cherche
229 * @param string $fond
230 * nom de la page (ou 'dist' pour le bloc par defaut)
231 * @param string $ext
232 * extension du squelette
233 * @return string
234 */
235 function z_trouver_bloc($prefix_path,$bloc,$fond,$ext){
236 if (
237 (defined('_ZCORE_BLOC_PREFIX_SKEL') AND $f = find_in_path("$prefix_path$bloc/$bloc.$fond.$ext") AND z_fond_valide($f))
238 OR ($f = find_in_path("$prefix_path$bloc/$fond.$ext") AND z_fond_valide($f))
239 ){
240 return substr($f, 0, - strlen(".$ext"));
241 }
242 return "";
243 }
244 /**
245 * Tester si un type est echafaudable
246 * cad si il correspond bien a un objet en base
247 *
248 * @staticvar array $echafaudable
249 * @param string $type
250 * @return bool
251 */
252 function z_echafaudable($type){
253 static $pages = null;
254 static $echafaudable = array();
255 if (isset($echafaudable[$type]))
256 return $echafaudable[$type];
257 if (preg_match(',[^\w],',$type))
258 return $echafaudable[$type] = false;
259
260 if (test_espace_prive()){
261 if (!function_exists('trouver_objet_exec'))
262 include_spip('inc/pipelines_ecrire');
263 if ($e=trouver_objet_exec($type)){
264 return $echafaudable[$type] = array($e['table'],$e['table_objet_sql'],$e);
265 }
266 else {
267 // peut etre c'est un exec=types qui liste tous les objets "type"
268 if (($t=objet_type($type,false))!==$type
269 AND $e=trouver_objet_exec($t)){
270 return $echafaudable[$type] = array($e['table'],$e['table_objet_sql'],$t);
271 }
272 }
273 }
274 else {
275 if (is_null($pages)) {
276 $pages = array();
277 $liste = lister_tables_objets_sql();
278 foreach($liste as $t=>$d)
279 if ($d['page']) $pages[$d['page']] = array($d['table_objet'],$t);
280 }
281 if (!isset($pages[$type]))
282 return $echafaudable[$type] = false;
283 if (count($pages[$type])==2){
284 $trouver_table = charger_fonction('trouver_table','base');
285 $pages[$type][] = $trouver_table(reset($pages[$type]));
286 }
287 return $echafaudable[$type] = $pages[$type];
288 }
289 return $echafaudable[$type] = false;
290 }
291
292
293 /**
294 * Generer a la volee un fond a partir d'un contenu connu
295 * tous les squelettes d'echafaudage du prive sont en fait explicites dans prive/echafaudage
296 * on ne fait qu'un mini squelette d'inclusion pour reecrire les variables d'env
297 *
298 * @param string $type
299 * @param string $table
300 * @param string $table_sql
301 * @param array $desc
302 * @param string $ext
303 * @return string
304 */
305 function prive_echafauder_dist($exec,$table,$table_sql,$desc_exec,$ext){
306 $scaffold = "";
307
308 // page objet ou objet_edit
309 if (is_array($desc_exec)) {
310 $type = $desc_exec['type'];
311 $primary = $desc_exec['id_table_objet'];
312
313 if ($desc_exec['edition']===false)
314 $fond = "objet";
315 else {
316 $trouver_table = charger_fonction('trouver_table','base');
317 $desc = $trouver_table($table_sql);
318 if (isset($desc['field']['id_rubrique']))
319 $fond = 'objet_edit';
320 else
321 $fond = 'objet_edit.sans_rubrique';
322 }
323 $dir = z_blocs(test_espace_prive());
324 $dir = reset($dir);
325 $scaffold = "<INCLURE{fond=prive/echafaudage/$dir/".$fond.",objet=".$type.",id_objet=#".strtoupper($primary).",env}>";
326 }
327 // page objets
328 elseif($type = $desc_exec AND strpos($type,"/")===false){
329 $dir = z_blocs(test_espace_prive());
330 $dir = reset($dir);
331 $scaffold = "<INCLURE{fond=prive/echafaudage/$dir/objets,objet=".$type.",env} />";
332 }
333 // morceau d'objet : on fournit le fond de sibstitution dans $desc_exec
334 // et objet et tire de $table
335 elseif($fond = $desc_exec){
336 $dir = md5(dirname($fond));
337 $scaffold = "<INCLURE{fond=$fond,objet=".objet_type($table).",env} />";
338 }
339
340 $base_dir = sous_repertoire(_DIR_CACHE,"scaffold",false);
341 $base_dir = sous_repertoire($base_dir,$dir,false);
342 $f = $base_dir."$exec";
343 ecrire_fichier("$f.$ext",$scaffold);
344 return $f;
345 }
346
347 /**
348 * Recuperer et verifier var_zajax si demande dans l'url
349 * @return bool|string
350 */
351 function z_sanitize_var_zajax(){
352 $z_ajax = _request('var_zajax');
353 if (!$z_ajax) return false;
354 if (!$z_blocs = z_blocs(test_espace_prive())
355 OR !in_array($z_ajax,$z_blocs)) {
356 set_request('var_zajax'); // enlever cette demande incongrue
357 $z_ajax = false;
358 }
359 return $z_ajax;
360 }
361 ?>