[SPIP] ~2.1.12 -->2.1.25
[velocampus/web/www.git] / www / ecrire / public / decompiler.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2014 *
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 if (!defined('_ECRIRE_INC_VERSION')) return;
14
15 // Decompilation de l'arbre de syntaxe abstraite d'un squelette SPIP
16
17 function decompiler_boucle($struct, $fmt='', $prof=0)
18 {
19 $nom = $struct->id_boucle;
20 $avant = public_decompiler($struct->avant, $fmt, $prof);
21 $apres = public_decompiler($struct->apres, $fmt, $prof);
22 $altern = public_decompiler($struct->altern, $fmt, $prof);
23 $milieu = public_decompiler($struct->milieu, $fmt, $prof);
24
25 $type = $struct->sql_serveur ? "$struct->sql_serveur:" : '';
26 $type .= ($struct->type_requete ? $struct->type_requete :
27 $struct->table_optionnelle);
28
29 if ($struct->jointures_explicites)
30 $type .= " " . $struct->jointures_explicites;
31 if ($struct->table_optionnelle)
32 $type .= "?";
33 // Revoir le cas de la boucle recursive
34
35 $crit = $struct->param;
36 if ($crit AND !is_array($crit[0])) {
37 $type = strtolower($type) . array_shift($crit);
38 }
39 $crit = decompiler_criteres($crit, $struct->criteres, $fmt, $prof) ;
40
41 $f = 'format_boucle_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
42 return $f($avant, $nom, $type, $crit, $milieu, $apres, $altern, $prof);
43 }
44
45 function decompiler_include($struct, $fmt='', $prof=0)
46 {
47 $res = array();
48 foreach($struct->param ? $struct->param : array() as $couple) {
49 array_shift($couple);
50 foreach($couple as $v) {
51 $res[]= public_decompiler($v, $fmt, $prof);
52 }
53 }
54 $file = is_string($struct->texte) ? $struct->texte :
55 public_decompiler($struct->texte, $fmt, $prof);
56 $f = 'format_inclure_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
57 return $f($file, $res, $prof);
58 }
59
60 function decompiler_texte($struct, $fmt='', $prof=0)
61 {
62 $f = 'format_texte_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
63 return strlen($struct->texte) ? $f($struct->texte, $prof) : '';
64 }
65
66 function decompiler_polyglotte($struct, $fmt='', $prof=0)
67 {
68 $f = 'format_polyglotte_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
69 return $f($struct->traductions, $prof);
70 }
71
72 function decompiler_idiome($struct, $fmt='', $prof=0)
73 {
74 $args = array();
75 foreach ($struct->arg as $k => $v) {
76 $args[$k]= public_decompiler($v, $fmt, $prof);
77 }
78
79 $filtres = decompiler_liste($struct->param, $fmt, $prof);
80
81 $f = 'format_idiome_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
82 return $f($struct->nom_champ, $struct->module, $args, $filtres, $prof);
83 }
84
85 function decompiler_champ($struct, $fmt='', $prof=0)
86 {
87 $avant = public_decompiler($struct->avant, $fmt, $prof);
88 $apres = public_decompiler($struct->apres, $fmt, $prof);
89 $args = $filtres = '';
90 if ($p = $struct->param) {
91 if ($p[0][0]==='')
92 $args = decompiler_liste(array(array_shift($p)), $fmt, $prof);
93 $filtres = decompiler_liste($p, $fmt, $prof);
94 }
95 $f = 'format_champ_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
96 return $f($struct->nom_champ, $struct->nom_boucle, $struct->etoile, $avant, $apres, $args, $filtres, $prof);
97 }
98
99 function decompiler_liste($sources, $fmt='', $prof=0) {
100 if (!is_array($sources)) return '';
101 $f = 'format_liste_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
102 $res = '';
103 foreach($sources as $arg) {
104 if (!is_array($arg)) {
105 continue; // ne devrait pas arriver.
106 } else {$r = array_shift($arg);}
107 $args = array();
108 foreach($arg as $v) {
109 // cas des arguments entoures de ' ou "
110 if ((count($v) == 1)
111 AND $v[0]->type=='texte'
112 AND (strlen($v[0]->apres) == 1)
113 AND $v[0]->apres == $v[0]->avant)
114 $args[]= $v[0]->avant . $v[0]->texte . $v[0]->apres;
115 else $args[]= public_decompiler($v, $fmt, 0-$prof);
116 }
117 if (($r!=='') OR $args) $res .= $f($r, $args, $prof);
118 }
119 return $res;
120 }
121
122 // Decompilation des criteres: on triche et on deroge:
123 // - le phraseur fournit un bout du source en plus de la compil
124 // - le champ apres signale le critere {"separateur"} ou {'separateur'}
125 // - les champs sont implicitement etendus (crochets implicites mais interdits)
126 function decompiler_criteres($sources, $comp, $fmt='', $prof=0) {
127 if (!is_array($sources)) return '';
128 $res = '';
129 $f = 'format_critere_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
130 include_spip('public/format_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES));
131 foreach($sources as $crit) {
132 if (!is_array($crit)) continue; // boucle recursive
133 array_shift($crit);
134 $args = array();
135 foreach($crit as $i => $v) {
136 if ((count($v) == 1)
137 AND $v[0]->type=='texte'
138 AND $v[0]->apres)
139 $args[]= array(array('texte', ( $v[0]->apres . $v[0]->texte . $v[0]->apres)));
140 else {
141 $res2 = array();
142 foreach($v as $k => $p) {
143 if (isset($p->type)
144 AND function_exists($d = 'decompiler_' . $p->type)) {
145 $r = $d($p, $fmt, (0-$prof), @$v[$k+1]);
146 $res2[]= array($p->type, $r);
147 } else spip_log("critere $i / $k mal forme");
148 }
149 $args[]= $res2;
150 }
151 }
152 $res .= $f($args);
153 }
154 return $res;
155 }
156
157
158 function public_decompiler($liste, $fmt='', $prof=0)
159 {
160 if (!is_array($liste)) return '';
161 include_spip('public/format_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES));
162 $prof2 = ($prof < 0) ? ($prof-1) : ($prof+1);
163 $contenu = array();
164 foreach($liste as $k => $p) {
165 if (!isset($p->type)) continue; #??????
166 $d = 'decompiler_' . $p->type;
167 $next = isset($liste[$k+1]) ? $liste[$k+1] : false;
168 // Forcer le champ etendu si son source (pas les reecritures)
169 // contenait des args et s'il est suivi d'espaces,
170 // le champ simple les eliminant est un bug helas perenne.
171
172 if ($next
173 AND ($next->type == 'texte')
174 AND $p->type == 'champ'
175 AND !$p->apres
176 AND !$p->avant
177 AND $p->fonctions) {
178 $n = strlen($next->texte) - strlen(ltrim($next->texte));
179 if ($n) {
180 $champ = new Texte;
181 $champ->texte = substr($next->texte, 0, $n);
182 $champ->ligne = $p->ligne;
183 $p->apres = array($champ);
184 $next->texte = substr($next->texte, $n);
185 }
186 }
187 $contenu[] = array($d($p, $fmt, $prof2), $p->type);
188
189 }
190 $f = 'format_suite_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
191 return $f($contenu);
192 }
193 ?>