@@ -17,7 +17,7 @@ discard block |
||
| 17 | 17 | **/ |
| 18 | 18 | |
| 19 | 19 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 20 | - return; |
|
| 20 | + return; |
|
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | /** Repérer un code ne calculant rien, meme avec commentaire */ |
@@ -58,92 +58,92 @@ discard block |
||
| 58 | 58 | |
| 59 | 59 | |
| 60 | 60 | function argumenter_inclure( |
| 61 | - $params, |
|
| 62 | - $rejet_filtres, |
|
| 63 | - $p, |
|
| 64 | - &$boucles, |
|
| 65 | - $id_boucle, |
|
| 66 | - $echap = true, |
|
| 67 | - $lang = '', |
|
| 68 | - $fond1 = false |
|
| 61 | + $params, |
|
| 62 | + $rejet_filtres, |
|
| 63 | + $p, |
|
| 64 | + &$boucles, |
|
| 65 | + $id_boucle, |
|
| 66 | + $echap = true, |
|
| 67 | + $lang = '', |
|
| 68 | + $fond1 = false |
|
| 69 | 69 | ) { |
| 70 | - $l = []; |
|
| 71 | - $erreur_p_i_i = ''; |
|
| 72 | - if (!is_array($params)) { |
|
| 73 | - return $l; |
|
| 74 | - } |
|
| 75 | - foreach ($params as $k => $couple) { |
|
| 76 | - // la liste d'arguments d'inclusion peut se terminer par un filtre |
|
| 77 | - $filtre = array_shift($couple); |
|
| 78 | - if ($filtre) { |
|
| 79 | - break; |
|
| 80 | - } |
|
| 81 | - foreach ($couple as $n => $val) { |
|
| 82 | - $var = $val[0]; |
|
| 83 | - if ($var->type != 'texte') { |
|
| 84 | - if ($n or $k or $fond1) { |
|
| 85 | - $erreur_p_i_i = [ |
|
| 86 | - 'zbug_parametres_inclus_incorrects', |
|
| 87 | - ['param' => $var->nom_champ] |
|
| 88 | - ]; |
|
| 89 | - erreur_squelette($erreur_p_i_i, $p); |
|
| 90 | - break; |
|
| 91 | - } else { |
|
| 92 | - $l[1] = calculer_liste($val, $p->descr, $boucles, $id_boucle); |
|
| 93 | - } |
|
| 94 | - } else { |
|
| 95 | - preg_match(',^([^=]*)(=?)(.*)$,m', $var->texte, $m); |
|
| 96 | - $m = array_pad($m, 3, null); |
|
| 97 | - $var = $m[1]; |
|
| 98 | - $auto = false; |
|
| 70 | + $l = []; |
|
| 71 | + $erreur_p_i_i = ''; |
|
| 72 | + if (!is_array($params)) { |
|
| 73 | + return $l; |
|
| 74 | + } |
|
| 75 | + foreach ($params as $k => $couple) { |
|
| 76 | + // la liste d'arguments d'inclusion peut se terminer par un filtre |
|
| 77 | + $filtre = array_shift($couple); |
|
| 78 | + if ($filtre) { |
|
| 79 | + break; |
|
| 80 | + } |
|
| 81 | + foreach ($couple as $n => $val) { |
|
| 82 | + $var = $val[0]; |
|
| 83 | + if ($var->type != 'texte') { |
|
| 84 | + if ($n or $k or $fond1) { |
|
| 85 | + $erreur_p_i_i = [ |
|
| 86 | + 'zbug_parametres_inclus_incorrects', |
|
| 87 | + ['param' => $var->nom_champ] |
|
| 88 | + ]; |
|
| 89 | + erreur_squelette($erreur_p_i_i, $p); |
|
| 90 | + break; |
|
| 91 | + } else { |
|
| 92 | + $l[1] = calculer_liste($val, $p->descr, $boucles, $id_boucle); |
|
| 93 | + } |
|
| 94 | + } else { |
|
| 95 | + preg_match(',^([^=]*)(=?)(.*)$,m', $var->texte, $m); |
|
| 96 | + $m = array_pad($m, 3, null); |
|
| 97 | + $var = $m[1]; |
|
| 98 | + $auto = false; |
|
| 99 | 99 | ; |
| 100 | - if ($m[2]) { |
|
| 101 | - $v = $m[3]; |
|
| 102 | - if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) { |
|
| 103 | - $v = $m[1]; |
|
| 104 | - } |
|
| 105 | - $val[0] = new Texte(); |
|
| 106 | - $val[0]->texte = $v; |
|
| 107 | - } elseif ($k or $n or $fond1) { |
|
| 108 | - $auto = true; |
|
| 109 | - } else { |
|
| 110 | - $var = 1; |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - if ($var == 'lang') { |
|
| 114 | - $lang = !$auto |
|
| 115 | - ? calculer_liste($val, $p->descr, $boucles, $id_boucle) |
|
| 116 | - : '$GLOBALS["spip_lang"]'; |
|
| 117 | - } else { |
|
| 118 | - $val = $auto |
|
| 119 | - ? index_pile($id_boucle, $var, $boucles) |
|
| 120 | - : calculer_liste($val, $p->descr, $boucles, $id_boucle); |
|
| 121 | - if ($var !== 1) { |
|
| 122 | - $val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ") |
|
| 123 | - . $val . ($echap ? ") . '" : ' '); |
|
| 124 | - } else { |
|
| 125 | - $val = $echap ? "'.$val.'" : $val; |
|
| 126 | - } |
|
| 127 | - $l[$var] = $val; |
|
| 128 | - } |
|
| 129 | - } |
|
| 130 | - } |
|
| 131 | - } |
|
| 132 | - if ($erreur_p_i_i) { |
|
| 133 | - return false; |
|
| 134 | - } |
|
| 135 | - // Cas particulier de la langue : si {lang=xx} est definie, on |
|
| 136 | - // la passe, sinon on passe la langue courante au moment du calcul |
|
| 137 | - // sauf si on n'en veut pas |
|
| 138 | - if ($lang === false) { |
|
| 139 | - return $l; |
|
| 140 | - } |
|
| 141 | - if (!$lang) { |
|
| 142 | - $lang = '$GLOBALS["spip_lang"]'; |
|
| 143 | - } |
|
| 144 | - $l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : ' '); |
|
| 145 | - |
|
| 146 | - return $l; |
|
| 100 | + if ($m[2]) { |
|
| 101 | + $v = $m[3]; |
|
| 102 | + if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) { |
|
| 103 | + $v = $m[1]; |
|
| 104 | + } |
|
| 105 | + $val[0] = new Texte(); |
|
| 106 | + $val[0]->texte = $v; |
|
| 107 | + } elseif ($k or $n or $fond1) { |
|
| 108 | + $auto = true; |
|
| 109 | + } else { |
|
| 110 | + $var = 1; |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + if ($var == 'lang') { |
|
| 114 | + $lang = !$auto |
|
| 115 | + ? calculer_liste($val, $p->descr, $boucles, $id_boucle) |
|
| 116 | + : '$GLOBALS["spip_lang"]'; |
|
| 117 | + } else { |
|
| 118 | + $val = $auto |
|
| 119 | + ? index_pile($id_boucle, $var, $boucles) |
|
| 120 | + : calculer_liste($val, $p->descr, $boucles, $id_boucle); |
|
| 121 | + if ($var !== 1) { |
|
| 122 | + $val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ") |
|
| 123 | + . $val . ($echap ? ") . '" : ' '); |
|
| 124 | + } else { |
|
| 125 | + $val = $echap ? "'.$val.'" : $val; |
|
| 126 | + } |
|
| 127 | + $l[$var] = $val; |
|
| 128 | + } |
|
| 129 | + } |
|
| 130 | + } |
|
| 131 | + } |
|
| 132 | + if ($erreur_p_i_i) { |
|
| 133 | + return false; |
|
| 134 | + } |
|
| 135 | + // Cas particulier de la langue : si {lang=xx} est definie, on |
|
| 136 | + // la passe, sinon on passe la langue courante au moment du calcul |
|
| 137 | + // sauf si on n'en veut pas |
|
| 138 | + if ($lang === false) { |
|
| 139 | + return $l; |
|
| 140 | + } |
|
| 141 | + if (!$lang) { |
|
| 142 | + $lang = '$GLOBALS["spip_lang"]'; |
|
| 143 | + } |
|
| 144 | + $l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : ' '); |
|
| 145 | + |
|
| 146 | + return $l; |
|
| 147 | 147 | } |
| 148 | 148 | |
| 149 | 149 | /** |
@@ -167,84 +167,84 @@ discard block |
||
| 167 | 167 | **/ |
| 168 | 168 | function calculer_inclure($p, &$boucles, $id_boucle) { |
| 169 | 169 | |
| 170 | - $_options = []; |
|
| 171 | - $_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true); |
|
| 172 | - if (is_string($p->texte)) { |
|
| 173 | - $fichier = $p->texte; |
|
| 174 | - $code = '"' . str_replace('"', '\"', $fichier) . '"'; |
|
| 175 | - } else { |
|
| 176 | - $code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle); |
|
| 177 | - if ($code and preg_match("/^'([^']*)'/s", $code, $r)) { |
|
| 178 | - $fichier = $r[1]; |
|
| 179 | - } else { |
|
| 180 | - $fichier = ''; |
|
| 181 | - } |
|
| 182 | - } |
|
| 183 | - if (!$code or $code === '""' or $code === "''") { |
|
| 184 | - $trace = $p->fonctions; |
|
| 185 | - while ( |
|
| 186 | - is_array($trace) |
|
| 187 | - and $trace = array_filter($trace) |
|
| 188 | - and count($trace) == 1 |
|
| 189 | - ) { |
|
| 190 | - $trace = reset($trace); |
|
| 191 | - } |
|
| 192 | - $erreur_p_i_i = [ |
|
| 193 | - 'zbug_parametres_inclus_incorrects', |
|
| 194 | - ['param' => print_r($trace, true)] |
|
| 195 | - ]; |
|
| 196 | - erreur_squelette($erreur_p_i_i, $p); |
|
| 197 | - |
|
| 198 | - return "''"; |
|
| 199 | - } |
|
| 200 | - $compil = texte_script(memoriser_contexte_compil($p)); |
|
| 201 | - |
|
| 202 | - if (is_array($_contexte)) { |
|
| 203 | - // Critere d'inclusion {env} (et {self} pour compatibilite ascendante) |
|
| 204 | - if ($env = (isset($_contexte['env']) || isset($_contexte['self']))) { |
|
| 205 | - unset($_contexte['env']); |
|
| 206 | - } |
|
| 207 | - |
|
| 208 | - // noter les doublons dans l'appel a public.php |
|
| 209 | - if (isset($_contexte['doublons'])) { |
|
| 210 | - $_contexte['doublons'] = "\\'doublons\\' => '.var_export(\$doublons,true).'"; |
|
| 211 | - } |
|
| 212 | - |
|
| 213 | - if ($ajax = isset($_contexte['ajax'])) { |
|
| 214 | - $ajax = preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']); |
|
| 215 | - unset($_contexte['ajax']); |
|
| 216 | - } |
|
| 217 | - |
|
| 218 | - $_contexte = join(",\n\t", $_contexte); |
|
| 219 | - } else { |
|
| 220 | - return false; |
|
| 221 | - } // j'aurais voulu toucher le fond ... |
|
| 222 | - |
|
| 223 | - $contexte = 'array(' . $_contexte . ')'; |
|
| 224 | - |
|
| 225 | - if ($env) { |
|
| 226 | - $contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)"; |
|
| 227 | - } |
|
| 228 | - |
|
| 229 | - // s'il y a une extension .php, ce n'est pas un squelette |
|
| 230 | - if ($fichier and preg_match('/^.+[.]php$/s', $fichier)) { |
|
| 231 | - $code = sandbox_composer_inclure_php($fichier, $p, $contexte); |
|
| 232 | - } else { |
|
| 233 | - $_options[] = "\"compil\"=>array($compil)"; |
|
| 234 | - if ($ajax) { |
|
| 235 | - $_options[] = $ajax; |
|
| 236 | - } |
|
| 237 | - $code = " ' . argumenter_squelette($code) . '"; |
|
| 238 | - $code = 'echo ' . sprintf( |
|
| 239 | - CODE_RECUPERER_FOND, |
|
| 240 | - $code, |
|
| 241 | - $contexte, |
|
| 242 | - implode(',', $_options), |
|
| 243 | - "_request(\\'connect\\') ?? \\'\\'" |
|
| 244 | - ) . ';'; |
|
| 245 | - } |
|
| 246 | - |
|
| 247 | - return "\n'<'.'" . '?php ' . $code . "\n?'." . "'>'"; |
|
| 170 | + $_options = []; |
|
| 171 | + $_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true); |
|
| 172 | + if (is_string($p->texte)) { |
|
| 173 | + $fichier = $p->texte; |
|
| 174 | + $code = '"' . str_replace('"', '\"', $fichier) . '"'; |
|
| 175 | + } else { |
|
| 176 | + $code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle); |
|
| 177 | + if ($code and preg_match("/^'([^']*)'/s", $code, $r)) { |
|
| 178 | + $fichier = $r[1]; |
|
| 179 | + } else { |
|
| 180 | + $fichier = ''; |
|
| 181 | + } |
|
| 182 | + } |
|
| 183 | + if (!$code or $code === '""' or $code === "''") { |
|
| 184 | + $trace = $p->fonctions; |
|
| 185 | + while ( |
|
| 186 | + is_array($trace) |
|
| 187 | + and $trace = array_filter($trace) |
|
| 188 | + and count($trace) == 1 |
|
| 189 | + ) { |
|
| 190 | + $trace = reset($trace); |
|
| 191 | + } |
|
| 192 | + $erreur_p_i_i = [ |
|
| 193 | + 'zbug_parametres_inclus_incorrects', |
|
| 194 | + ['param' => print_r($trace, true)] |
|
| 195 | + ]; |
|
| 196 | + erreur_squelette($erreur_p_i_i, $p); |
|
| 197 | + |
|
| 198 | + return "''"; |
|
| 199 | + } |
|
| 200 | + $compil = texte_script(memoriser_contexte_compil($p)); |
|
| 201 | + |
|
| 202 | + if (is_array($_contexte)) { |
|
| 203 | + // Critere d'inclusion {env} (et {self} pour compatibilite ascendante) |
|
| 204 | + if ($env = (isset($_contexte['env']) || isset($_contexte['self']))) { |
|
| 205 | + unset($_contexte['env']); |
|
| 206 | + } |
|
| 207 | + |
|
| 208 | + // noter les doublons dans l'appel a public.php |
|
| 209 | + if (isset($_contexte['doublons'])) { |
|
| 210 | + $_contexte['doublons'] = "\\'doublons\\' => '.var_export(\$doublons,true).'"; |
|
| 211 | + } |
|
| 212 | + |
|
| 213 | + if ($ajax = isset($_contexte['ajax'])) { |
|
| 214 | + $ajax = preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']); |
|
| 215 | + unset($_contexte['ajax']); |
|
| 216 | + } |
|
| 217 | + |
|
| 218 | + $_contexte = join(",\n\t", $_contexte); |
|
| 219 | + } else { |
|
| 220 | + return false; |
|
| 221 | + } // j'aurais voulu toucher le fond ... |
|
| 222 | + |
|
| 223 | + $contexte = 'array(' . $_contexte . ')'; |
|
| 224 | + |
|
| 225 | + if ($env) { |
|
| 226 | + $contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)"; |
|
| 227 | + } |
|
| 228 | + |
|
| 229 | + // s'il y a une extension .php, ce n'est pas un squelette |
|
| 230 | + if ($fichier and preg_match('/^.+[.]php$/s', $fichier)) { |
|
| 231 | + $code = sandbox_composer_inclure_php($fichier, $p, $contexte); |
|
| 232 | + } else { |
|
| 233 | + $_options[] = "\"compil\"=>array($compil)"; |
|
| 234 | + if ($ajax) { |
|
| 235 | + $_options[] = $ajax; |
|
| 236 | + } |
|
| 237 | + $code = " ' . argumenter_squelette($code) . '"; |
|
| 238 | + $code = 'echo ' . sprintf( |
|
| 239 | + CODE_RECUPERER_FOND, |
|
| 240 | + $code, |
|
| 241 | + $contexte, |
|
| 242 | + implode(',', $_options), |
|
| 243 | + "_request(\\'connect\\') ?? \\'\\'" |
|
| 244 | + ) . ';'; |
|
| 245 | + } |
|
| 246 | + |
|
| 247 | + return "\n'<'.'" . '?php ' . $code . "\n?'." . "'>'"; |
|
| 248 | 248 | } |
| 249 | 249 | |
| 250 | 250 | |
@@ -262,7 +262,7 @@ discard block |
||
| 262 | 262 | * true pour ne tester que le cas publie et ignorer l'eventuel var_mode=preview de la page |
| 263 | 263 | */ |
| 264 | 264 | function instituer_boucle(&$boucle, $echapper = true, $ignore_previsu = false) { |
| 265 | - /* |
|
| 265 | + /* |
|
| 266 | 266 | $show['statut'][] = array( |
| 267 | 267 | 'champ'=>'statut', // champ de la table sur lequel porte le filtrage par le statut |
| 268 | 268 | 'publie'=>'publie', // valeur ou liste de valeurs, qui definissent l'objet comme publie. |
@@ -286,74 +286,74 @@ discard block |
||
| 286 | 286 | champstatut est alors le champ statut sur la tablen |
| 287 | 287 | dans les jointures, clen peut etre un tableau pour une jointure complexe : array('id_objet','id_article','objet','article') |
| 288 | 288 | */ |
| 289 | - $id_table = $boucle->id_table; |
|
| 290 | - $show = $boucle->show; |
|
| 291 | - if (isset($show['statut']) and $show['statut']) { |
|
| 292 | - foreach ($show['statut'] as $k => $s) { |
|
| 293 | - // Restreindre aux elements publies si pas de {statut} ou autre dans les criteres |
|
| 294 | - $filtrer = true; |
|
| 295 | - if (isset($s['exception'])) { |
|
| 296 | - foreach (is_array($s['exception']) ? $s['exception'] : [$s['exception']] as $m) { |
|
| 297 | - if (isset($boucle->modificateur[$m]) or isset($boucle->modificateur['criteres'][$m])) { |
|
| 298 | - $filtrer = false; |
|
| 299 | - break; |
|
| 300 | - } |
|
| 301 | - } |
|
| 302 | - } |
|
| 303 | - |
|
| 304 | - if ($filtrer) { |
|
| 305 | - if (is_array($s['champ'])) { |
|
| 306 | - $statut = preg_replace(',\W,', '', array_pop($s['champ'])); // securite |
|
| 307 | - $jointures = []; |
|
| 308 | - // indiquer la description de chaque table dans le tableau de jointures, |
|
| 309 | - // ce qui permet d'eviter certains GROUP BY inutiles. |
|
| 310 | - $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 311 | - foreach ($s['champ'] as $j) { |
|
| 312 | - $id = reset($j); |
|
| 313 | - $def = $trouver_table($id); |
|
| 314 | - $jointures[] = ['', [$id, $def], end($j)]; |
|
| 315 | - } |
|
| 316 | - $jointures[0][0] = $id_table; |
|
| 317 | - if (!array_search($id, $boucle->from)) { |
|
| 318 | - include_spip('public/jointures'); |
|
| 319 | - fabrique_jointures($boucle, $jointures, true, $boucle->show, $id_table, '', $echapper); |
|
| 320 | - } |
|
| 321 | - // trouver l'alias de la table d'arrivee qui porte le statut |
|
| 322 | - $id = array_search($id, $boucle->from); |
|
| 323 | - } else { |
|
| 324 | - $id = $id_table; |
|
| 325 | - $statut = preg_replace(',\W,', '', $s['champ']); // securite |
|
| 326 | - } |
|
| 327 | - $mstatut = $id . '.' . $statut; |
|
| 328 | - |
|
| 329 | - $arg_ignore_previsu = ($ignore_previsu ? ',true' : ''); |
|
| 330 | - include_spip('public/quete'); |
|
| 331 | - if ( |
|
| 332 | - isset($s['post_date']) and $s['post_date'] |
|
| 333 | - and $GLOBALS['meta']['post_dates'] == 'non' |
|
| 334 | - ) { |
|
| 335 | - $date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite |
|
| 336 | - array_unshift( |
|
| 337 | - $boucle->where, |
|
| 338 | - $echapper ? |
|
| 339 | - "\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)" |
|
| 340 | - : |
|
| 341 | - quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu) |
|
| 342 | - ); |
|
| 343 | - } |
|
| 344 | - array_unshift( |
|
| 345 | - $boucle->where, |
|
| 346 | - $echapper ? |
|
| 347 | - "\nquete_condition_statut('$mstatut'," |
|
| 348 | - . _q($s['previsu']) . ',' |
|
| 349 | - . _q($s['publie']) . ',' |
|
| 350 | - . _q($boucle->sql_serveur) . "$arg_ignore_previsu)" |
|
| 351 | - : |
|
| 352 | - quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu) |
|
| 353 | - ); |
|
| 354 | - } |
|
| 355 | - } |
|
| 356 | - } |
|
| 289 | + $id_table = $boucle->id_table; |
|
| 290 | + $show = $boucle->show; |
|
| 291 | + if (isset($show['statut']) and $show['statut']) { |
|
| 292 | + foreach ($show['statut'] as $k => $s) { |
|
| 293 | + // Restreindre aux elements publies si pas de {statut} ou autre dans les criteres |
|
| 294 | + $filtrer = true; |
|
| 295 | + if (isset($s['exception'])) { |
|
| 296 | + foreach (is_array($s['exception']) ? $s['exception'] : [$s['exception']] as $m) { |
|
| 297 | + if (isset($boucle->modificateur[$m]) or isset($boucle->modificateur['criteres'][$m])) { |
|
| 298 | + $filtrer = false; |
|
| 299 | + break; |
|
| 300 | + } |
|
| 301 | + } |
|
| 302 | + } |
|
| 303 | + |
|
| 304 | + if ($filtrer) { |
|
| 305 | + if (is_array($s['champ'])) { |
|
| 306 | + $statut = preg_replace(',\W,', '', array_pop($s['champ'])); // securite |
|
| 307 | + $jointures = []; |
|
| 308 | + // indiquer la description de chaque table dans le tableau de jointures, |
|
| 309 | + // ce qui permet d'eviter certains GROUP BY inutiles. |
|
| 310 | + $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 311 | + foreach ($s['champ'] as $j) { |
|
| 312 | + $id = reset($j); |
|
| 313 | + $def = $trouver_table($id); |
|
| 314 | + $jointures[] = ['', [$id, $def], end($j)]; |
|
| 315 | + } |
|
| 316 | + $jointures[0][0] = $id_table; |
|
| 317 | + if (!array_search($id, $boucle->from)) { |
|
| 318 | + include_spip('public/jointures'); |
|
| 319 | + fabrique_jointures($boucle, $jointures, true, $boucle->show, $id_table, '', $echapper); |
|
| 320 | + } |
|
| 321 | + // trouver l'alias de la table d'arrivee qui porte le statut |
|
| 322 | + $id = array_search($id, $boucle->from); |
|
| 323 | + } else { |
|
| 324 | + $id = $id_table; |
|
| 325 | + $statut = preg_replace(',\W,', '', $s['champ']); // securite |
|
| 326 | + } |
|
| 327 | + $mstatut = $id . '.' . $statut; |
|
| 328 | + |
|
| 329 | + $arg_ignore_previsu = ($ignore_previsu ? ',true' : ''); |
|
| 330 | + include_spip('public/quete'); |
|
| 331 | + if ( |
|
| 332 | + isset($s['post_date']) and $s['post_date'] |
|
| 333 | + and $GLOBALS['meta']['post_dates'] == 'non' |
|
| 334 | + ) { |
|
| 335 | + $date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite |
|
| 336 | + array_unshift( |
|
| 337 | + $boucle->where, |
|
| 338 | + $echapper ? |
|
| 339 | + "\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)" |
|
| 340 | + : |
|
| 341 | + quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu) |
|
| 342 | + ); |
|
| 343 | + } |
|
| 344 | + array_unshift( |
|
| 345 | + $boucle->where, |
|
| 346 | + $echapper ? |
|
| 347 | + "\nquete_condition_statut('$mstatut'," |
|
| 348 | + . _q($s['previsu']) . ',' |
|
| 349 | + . _q($s['publie']) . ',' |
|
| 350 | + . _q($boucle->sql_serveur) . "$arg_ignore_previsu)" |
|
| 351 | + : |
|
| 352 | + quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu) |
|
| 353 | + ); |
|
| 354 | + } |
|
| 355 | + } |
|
| 356 | + } |
|
| 357 | 357 | } |
| 358 | 358 | |
| 359 | 359 | /** |
@@ -372,29 +372,29 @@ discard block |
||
| 372 | 372 | */ |
| 373 | 373 | function calculer_boucle($id_boucle, &$boucles) { |
| 374 | 374 | |
| 375 | - $boucle = &$boucles[$id_boucle]; |
|
| 376 | - instituer_boucle($boucle); |
|
| 377 | - $boucles[$id_boucle] = pipeline('post_boucle', $boucles[$id_boucle]); |
|
| 378 | - |
|
| 379 | - // en mode debug memoriser les premiers passages dans la boucle, |
|
| 380 | - // mais pas tous, sinon ca pete. |
|
| 381 | - if (_request('var_mode_affiche') != 'resultat') { |
|
| 382 | - $trace = ''; |
|
| 383 | - } else { |
|
| 384 | - $_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle; |
|
| 385 | - $_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']"; |
|
| 386 | - $trace = " |
|
| 375 | + $boucle = &$boucles[$id_boucle]; |
|
| 376 | + instituer_boucle($boucle); |
|
| 377 | + $boucles[$id_boucle] = pipeline('post_boucle', $boucles[$id_boucle]); |
|
| 378 | + |
|
| 379 | + // en mode debug memoriser les premiers passages dans la boucle, |
|
| 380 | + // mais pas tous, sinon ca pete. |
|
| 381 | + if (_request('var_mode_affiche') != 'resultat') { |
|
| 382 | + $trace = ''; |
|
| 383 | + } else { |
|
| 384 | + $_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle; |
|
| 385 | + $_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']"; |
|
| 386 | + $trace = " |
|
| 387 | 387 | if (empty($_trace)) { |
| 388 | 388 | $_trace = []; |
| 389 | 389 | } |
| 390 | 390 | if (count($_trace) < 3) { |
| 391 | 391 | $_trace" . '[] = $t0; |
| 392 | 392 | }'; |
| 393 | - } |
|
| 393 | + } |
|
| 394 | 394 | |
| 395 | - return ($boucles[$id_boucle]->type_requete == TYPE_RECURSIF) |
|
| 396 | - ? calculer_boucle_rec($id_boucle, $boucles, $trace) |
|
| 397 | - : calculer_boucle_nonrec($id_boucle, $boucles, $trace); |
|
| 395 | + return ($boucles[$id_boucle]->type_requete == TYPE_RECURSIF) |
|
| 396 | + ? calculer_boucle_rec($id_boucle, $boucles, $trace) |
|
| 397 | + : calculer_boucle_nonrec($id_boucle, $boucles, $trace); |
|
| 398 | 398 | } |
| 399 | 399 | |
| 400 | 400 | |
@@ -417,15 +417,15 @@ discard block |
||
| 417 | 417 | * Code PHP compilé de la boucle récursive |
| 418 | 418 | **/ |
| 419 | 419 | function calculer_boucle_rec($id_boucle, &$boucles, $trace) { |
| 420 | - $nom = $boucles[$id_boucle]->param[0]; |
|
| 421 | - |
|
| 422 | - return |
|
| 423 | - // Numrows[$nom] peut ne pas être encore defini |
|
| 424 | - "\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());" |
|
| 425 | - . "\n\t\$t0 = " . $boucles[$id_boucle]->return . ';' |
|
| 426 | - . "\n\t\$Numrows['$nom'] = (\$save_numrows);" |
|
| 427 | - . $trace |
|
| 428 | - . "\n\treturn \$t0;"; |
|
| 420 | + $nom = $boucles[$id_boucle]->param[0]; |
|
| 421 | + |
|
| 422 | + return |
|
| 423 | + // Numrows[$nom] peut ne pas être encore defini |
|
| 424 | + "\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());" |
|
| 425 | + . "\n\t\$t0 = " . $boucles[$id_boucle]->return . ';' |
|
| 426 | + . "\n\t\$Numrows['$nom'] = (\$save_numrows);" |
|
| 427 | + . $trace |
|
| 428 | + . "\n\treturn \$t0;"; |
|
| 429 | 429 | } |
| 430 | 430 | |
| 431 | 431 | /** |
@@ -478,174 +478,174 @@ discard block |
||
| 478 | 478 | **/ |
| 479 | 479 | function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) { |
| 480 | 480 | |
| 481 | - $code_sep = null; |
|
| 482 | - $boucle = &$boucles[$id_boucle]; |
|
| 483 | - $return = $boucle->return; |
|
| 484 | - $type_boucle = $boucle->type_requete; |
|
| 485 | - $primary = $boucle->primary; |
|
| 486 | - $constant = preg_match(CODE_MONOTONE, str_replace("\\'", '', $return)); |
|
| 487 | - $flag_cpt = $boucle->mode_partie || $boucle->cptrows; |
|
| 488 | - $corps = ''; |
|
| 489 | - |
|
| 490 | - // faudrait expanser le foreach a la compil, car y en a souvent qu'un |
|
| 491 | - // et puis faire un [] plutot qu'un "','." |
|
| 492 | - if ($boucle->doublons) { |
|
| 493 | - $corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' . |
|
| 494 | - index_pile($id_boucle, $primary, $boucles) |
|
| 495 | - . "; // doublons\n"; |
|
| 496 | - } |
|
| 497 | - |
|
| 498 | - // La boucle doit-elle selectionner la langue ? |
|
| 499 | - // - par defaut, les boucles suivantes le font |
|
| 500 | - // (sauf si forcer_lang==true ou si le titre contient <multi>). |
|
| 501 | - // - a moins d'une demande explicite via {!lang_select} |
|
| 502 | - if ( |
|
| 503 | - !$constant && $boucle->lang_select != 'non' && |
|
| 504 | - (($boucle->lang_select == 'oui') || |
|
| 505 | - in_array($type_boucle, [ |
|
| 506 | - 'articles', |
|
| 507 | - 'rubriques', |
|
| 508 | - 'hierarchie', |
|
| 509 | - 'breves' |
|
| 510 | - ])) |
|
| 511 | - ) { |
|
| 512 | - // Memoriser la langue avant la boucle et la restituer apres |
|
| 513 | - // afin que le corps de boucle affecte la globale directement |
|
| 514 | - $init_lang = "lang_select(\$GLOBALS['spip_lang']);\n\t"; |
|
| 515 | - $fin_lang = "lang_select();\n\t"; |
|
| 516 | - $fin_lang_select_public = "\n\t\tlang_select();"; |
|
| 517 | - |
|
| 518 | - $corps .= |
|
| 519 | - "\n\t\tlang_select_public(" |
|
| 520 | - . index_pile($id_boucle, 'lang', $boucles) |
|
| 521 | - . ", '" . $boucle->lang_select . "'" |
|
| 522 | - . (in_array($type_boucle, [ |
|
| 523 | - 'articles', |
|
| 524 | - 'rubriques', |
|
| 525 | - 'hierarchie', |
|
| 526 | - 'breves' |
|
| 527 | - ]) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '') |
|
| 528 | - . ');'; |
|
| 529 | - } else { |
|
| 530 | - $init_lang = ''; |
|
| 531 | - $fin_lang = ''; |
|
| 532 | - $fin_lang_select_public = ''; |
|
| 533 | - // sortir les appels au traducteur (invariants de boucle) |
|
| 534 | - if ( |
|
| 535 | - strpos($return, '?php') === false |
|
| 536 | - and preg_match_all("/\W(_T[(]'[^']*'[)])/", $return, $r) |
|
| 537 | - ) { |
|
| 538 | - $i = 1; |
|
| 539 | - foreach ($r[1] as $t) { |
|
| 540 | - $init_lang .= "\n\t\$l$i = $t;"; |
|
| 541 | - $return = str_replace($t, "\$l$i", $return); |
|
| 542 | - $i++; |
|
| 543 | - } |
|
| 544 | - } |
|
| 545 | - } |
|
| 546 | - |
|
| 547 | - // gestion optimale des separateurs et des boucles constantes |
|
| 548 | - if (is_countable($boucle->separateur) ? count($boucle->separateur) : 0) { |
|
| 549 | - $code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'"); |
|
| 550 | - } |
|
| 551 | - |
|
| 552 | - $corps .= |
|
| 553 | - ((!$boucle->separateur) ? |
|
| 554 | - (($constant && !$corps && !$flag_cpt) ? $return : |
|
| 555 | - (($return === "''") ? '' : |
|
| 556 | - ("\n\t\t" . '$t0 .= ' . $return . ';'))) : |
|
| 557 | - ("\n\t\t\$t1 " . |
|
| 558 | - ((strpos($return, '$t1.') === 0) ? |
|
| 559 | - ('.=' . substr($return, 4)) : |
|
| 560 | - ('= ' . $return)) . |
|
| 561 | - ";\n\t\t" . |
|
| 562 | - '$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;")); |
|
| 563 | - |
|
| 564 | - // Calculer les invalideurs si c'est une boucle non constante et si on |
|
| 565 | - // souhaite invalider ces elements |
|
| 566 | - if (!$constant and $primary) { |
|
| 567 | - include_spip('inc/invalideur'); |
|
| 568 | - $corps = calcul_invalideurs($corps, $primary, $boucles, $id_boucle); |
|
| 569 | - } |
|
| 570 | - |
|
| 571 | - // gerer le compteur de boucle |
|
| 572 | - // avec ou sans son utilisation par les criteres {1/3} {1,4} {n-2,1}... |
|
| 573 | - |
|
| 574 | - if ($boucle->partie or $boucle->cptrows) { |
|
| 575 | - $corps = "\n\t\t\$Numrows['$id_boucle']['compteur_boucle']++;" |
|
| 576 | - . $boucle->partie |
|
| 577 | - . $corps; |
|
| 578 | - } |
|
| 579 | - |
|
| 580 | - // depiler la lang de la boucle si besoin |
|
| 581 | - $corps .= $fin_lang_select_public; |
|
| 582 | - |
|
| 583 | - // si le corps est une constante, ne pas appeler le serveur N fois! |
|
| 584 | - |
|
| 585 | - if (preg_match(CODE_MONOTONE, str_replace("\\'", '', $corps), $r)) { |
|
| 586 | - if (!isset($r[2]) or (!$r[2])) { |
|
| 587 | - if (!$boucle->numrows) { |
|
| 588 | - return "\n\t\$t0 = '';"; |
|
| 589 | - } else { |
|
| 590 | - $corps = ''; |
|
| 591 | - } |
|
| 592 | - } else { |
|
| 593 | - $boucle->numrows = true; |
|
| 594 | - $corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);"; |
|
| 595 | - } |
|
| 596 | - } else { |
|
| 597 | - $corps = "while (\$Pile[\$SP]=\$iter->fetch()) {\n$corps\n }"; |
|
| 598 | - } |
|
| 599 | - |
|
| 600 | - $count = ''; |
|
| 601 | - if (!$boucle->select) { |
|
| 602 | - if (!$boucle->numrows or $boucle->limit or $boucle->mode_partie or $boucle->group) { |
|
| 603 | - $count = '1'; |
|
| 604 | - } else { |
|
| 605 | - $count = 'count(*)'; |
|
| 606 | - } |
|
| 607 | - $boucles[$id_boucle]->select[] = $count; |
|
| 608 | - } |
|
| 609 | - |
|
| 610 | - if ($flag_cpt) { |
|
| 611 | - $nums = "\n\t// COMPTEUR\n\t" |
|
| 612 | - . "\$Numrows['$id_boucle']['compteur_boucle'] = 0;\n\t"; |
|
| 613 | - } else { |
|
| 614 | - $nums = ''; |
|
| 615 | - } |
|
| 616 | - |
|
| 617 | - if ($boucle->numrows or $boucle->mode_partie) { |
|
| 618 | - $nums .= "\$Numrows['$id_boucle']['command'] = \$command;\n\t" |
|
| 619 | - . "\$Numrows['$id_boucle']['total'] = @intval(\$iter->count());" |
|
| 620 | - . $boucle->mode_partie |
|
| 621 | - . "\n\t"; |
|
| 622 | - } |
|
| 623 | - |
|
| 624 | - // Ne calculer la requete que maintenant |
|
| 625 | - // car ce qui precede appelle index_pile qui influe dessus |
|
| 626 | - |
|
| 627 | - $init = (($init = $boucles[$id_boucle]->doublons) |
|
| 628 | - ? ("\n\t$init = array();") : '') |
|
| 629 | - . calculer_requete_sql($boucles[$id_boucle]); |
|
| 630 | - |
|
| 631 | - $contexte = memoriser_contexte_compil($boucle); |
|
| 632 | - |
|
| 633 | - $a = sprintf( |
|
| 634 | - CODE_CORPS_BOUCLE, |
|
| 635 | - $init, |
|
| 636 | - $boucle->iterateur, |
|
| 637 | - '$command', |
|
| 638 | - $contexte, |
|
| 639 | - $nums, |
|
| 640 | - $init_lang, |
|
| 641 | - $corps, |
|
| 642 | - $fin_lang, |
|
| 643 | - $trace, |
|
| 644 | - 'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile']) |
|
| 645 | - ); |
|
| 481 | + $code_sep = null; |
|
| 482 | + $boucle = &$boucles[$id_boucle]; |
|
| 483 | + $return = $boucle->return; |
|
| 484 | + $type_boucle = $boucle->type_requete; |
|
| 485 | + $primary = $boucle->primary; |
|
| 486 | + $constant = preg_match(CODE_MONOTONE, str_replace("\\'", '', $return)); |
|
| 487 | + $flag_cpt = $boucle->mode_partie || $boucle->cptrows; |
|
| 488 | + $corps = ''; |
|
| 489 | + |
|
| 490 | + // faudrait expanser le foreach a la compil, car y en a souvent qu'un |
|
| 491 | + // et puis faire un [] plutot qu'un "','." |
|
| 492 | + if ($boucle->doublons) { |
|
| 493 | + $corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' . |
|
| 494 | + index_pile($id_boucle, $primary, $boucles) |
|
| 495 | + . "; // doublons\n"; |
|
| 496 | + } |
|
| 497 | + |
|
| 498 | + // La boucle doit-elle selectionner la langue ? |
|
| 499 | + // - par defaut, les boucles suivantes le font |
|
| 500 | + // (sauf si forcer_lang==true ou si le titre contient <multi>). |
|
| 501 | + // - a moins d'une demande explicite via {!lang_select} |
|
| 502 | + if ( |
|
| 503 | + !$constant && $boucle->lang_select != 'non' && |
|
| 504 | + (($boucle->lang_select == 'oui') || |
|
| 505 | + in_array($type_boucle, [ |
|
| 506 | + 'articles', |
|
| 507 | + 'rubriques', |
|
| 508 | + 'hierarchie', |
|
| 509 | + 'breves' |
|
| 510 | + ])) |
|
| 511 | + ) { |
|
| 512 | + // Memoriser la langue avant la boucle et la restituer apres |
|
| 513 | + // afin que le corps de boucle affecte la globale directement |
|
| 514 | + $init_lang = "lang_select(\$GLOBALS['spip_lang']);\n\t"; |
|
| 515 | + $fin_lang = "lang_select();\n\t"; |
|
| 516 | + $fin_lang_select_public = "\n\t\tlang_select();"; |
|
| 517 | + |
|
| 518 | + $corps .= |
|
| 519 | + "\n\t\tlang_select_public(" |
|
| 520 | + . index_pile($id_boucle, 'lang', $boucles) |
|
| 521 | + . ", '" . $boucle->lang_select . "'" |
|
| 522 | + . (in_array($type_boucle, [ |
|
| 523 | + 'articles', |
|
| 524 | + 'rubriques', |
|
| 525 | + 'hierarchie', |
|
| 526 | + 'breves' |
|
| 527 | + ]) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '') |
|
| 528 | + . ');'; |
|
| 529 | + } else { |
|
| 530 | + $init_lang = ''; |
|
| 531 | + $fin_lang = ''; |
|
| 532 | + $fin_lang_select_public = ''; |
|
| 533 | + // sortir les appels au traducteur (invariants de boucle) |
|
| 534 | + if ( |
|
| 535 | + strpos($return, '?php') === false |
|
| 536 | + and preg_match_all("/\W(_T[(]'[^']*'[)])/", $return, $r) |
|
| 537 | + ) { |
|
| 538 | + $i = 1; |
|
| 539 | + foreach ($r[1] as $t) { |
|
| 540 | + $init_lang .= "\n\t\$l$i = $t;"; |
|
| 541 | + $return = str_replace($t, "\$l$i", $return); |
|
| 542 | + $i++; |
|
| 543 | + } |
|
| 544 | + } |
|
| 545 | + } |
|
| 546 | + |
|
| 547 | + // gestion optimale des separateurs et des boucles constantes |
|
| 548 | + if (is_countable($boucle->separateur) ? count($boucle->separateur) : 0) { |
|
| 549 | + $code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'"); |
|
| 550 | + } |
|
| 551 | + |
|
| 552 | + $corps .= |
|
| 553 | + ((!$boucle->separateur) ? |
|
| 554 | + (($constant && !$corps && !$flag_cpt) ? $return : |
|
| 555 | + (($return === "''") ? '' : |
|
| 556 | + ("\n\t\t" . '$t0 .= ' . $return . ';'))) : |
|
| 557 | + ("\n\t\t\$t1 " . |
|
| 558 | + ((strpos($return, '$t1.') === 0) ? |
|
| 559 | + ('.=' . substr($return, 4)) : |
|
| 560 | + ('= ' . $return)) . |
|
| 561 | + ";\n\t\t" . |
|
| 562 | + '$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;")); |
|
| 563 | + |
|
| 564 | + // Calculer les invalideurs si c'est une boucle non constante et si on |
|
| 565 | + // souhaite invalider ces elements |
|
| 566 | + if (!$constant and $primary) { |
|
| 567 | + include_spip('inc/invalideur'); |
|
| 568 | + $corps = calcul_invalideurs($corps, $primary, $boucles, $id_boucle); |
|
| 569 | + } |
|
| 570 | + |
|
| 571 | + // gerer le compteur de boucle |
|
| 572 | + // avec ou sans son utilisation par les criteres {1/3} {1,4} {n-2,1}... |
|
| 573 | + |
|
| 574 | + if ($boucle->partie or $boucle->cptrows) { |
|
| 575 | + $corps = "\n\t\t\$Numrows['$id_boucle']['compteur_boucle']++;" |
|
| 576 | + . $boucle->partie |
|
| 577 | + . $corps; |
|
| 578 | + } |
|
| 579 | + |
|
| 580 | + // depiler la lang de la boucle si besoin |
|
| 581 | + $corps .= $fin_lang_select_public; |
|
| 582 | + |
|
| 583 | + // si le corps est une constante, ne pas appeler le serveur N fois! |
|
| 584 | + |
|
| 585 | + if (preg_match(CODE_MONOTONE, str_replace("\\'", '', $corps), $r)) { |
|
| 586 | + if (!isset($r[2]) or (!$r[2])) { |
|
| 587 | + if (!$boucle->numrows) { |
|
| 588 | + return "\n\t\$t0 = '';"; |
|
| 589 | + } else { |
|
| 590 | + $corps = ''; |
|
| 591 | + } |
|
| 592 | + } else { |
|
| 593 | + $boucle->numrows = true; |
|
| 594 | + $corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);"; |
|
| 595 | + } |
|
| 596 | + } else { |
|
| 597 | + $corps = "while (\$Pile[\$SP]=\$iter->fetch()) {\n$corps\n }"; |
|
| 598 | + } |
|
| 599 | + |
|
| 600 | + $count = ''; |
|
| 601 | + if (!$boucle->select) { |
|
| 602 | + if (!$boucle->numrows or $boucle->limit or $boucle->mode_partie or $boucle->group) { |
|
| 603 | + $count = '1'; |
|
| 604 | + } else { |
|
| 605 | + $count = 'count(*)'; |
|
| 606 | + } |
|
| 607 | + $boucles[$id_boucle]->select[] = $count; |
|
| 608 | + } |
|
| 609 | + |
|
| 610 | + if ($flag_cpt) { |
|
| 611 | + $nums = "\n\t// COMPTEUR\n\t" |
|
| 612 | + . "\$Numrows['$id_boucle']['compteur_boucle'] = 0;\n\t"; |
|
| 613 | + } else { |
|
| 614 | + $nums = ''; |
|
| 615 | + } |
|
| 616 | + |
|
| 617 | + if ($boucle->numrows or $boucle->mode_partie) { |
|
| 618 | + $nums .= "\$Numrows['$id_boucle']['command'] = \$command;\n\t" |
|
| 619 | + . "\$Numrows['$id_boucle']['total'] = @intval(\$iter->count());" |
|
| 620 | + . $boucle->mode_partie |
|
| 621 | + . "\n\t"; |
|
| 622 | + } |
|
| 623 | + |
|
| 624 | + // Ne calculer la requete que maintenant |
|
| 625 | + // car ce qui precede appelle index_pile qui influe dessus |
|
| 626 | + |
|
| 627 | + $init = (($init = $boucles[$id_boucle]->doublons) |
|
| 628 | + ? ("\n\t$init = array();") : '') |
|
| 629 | + . calculer_requete_sql($boucles[$id_boucle]); |
|
| 630 | + |
|
| 631 | + $contexte = memoriser_contexte_compil($boucle); |
|
| 632 | + |
|
| 633 | + $a = sprintf( |
|
| 634 | + CODE_CORPS_BOUCLE, |
|
| 635 | + $init, |
|
| 636 | + $boucle->iterateur, |
|
| 637 | + '$command', |
|
| 638 | + $contexte, |
|
| 639 | + $nums, |
|
| 640 | + $init_lang, |
|
| 641 | + $corps, |
|
| 642 | + $fin_lang, |
|
| 643 | + $trace, |
|
| 644 | + 'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile']) |
|
| 645 | + ); |
|
| 646 | 646 | |
| 647 | 647 | # var_dump($a);exit; |
| 648 | - return $a; |
|
| 648 | + return $a; |
|
| 649 | 649 | } |
| 650 | 650 | |
| 651 | 651 | |
@@ -661,48 +661,48 @@ discard block |
||
| 661 | 661 | * Code PHP compilé définissant les informations de requête |
| 662 | 662 | **/ |
| 663 | 663 | function calculer_requete_sql($boucle) { |
| 664 | - $init = []; |
|
| 665 | - $init[] = calculer_dec('table', "'" . $boucle->id_table . "'"); |
|
| 666 | - $init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'"); |
|
| 667 | - # En absence de champ c'est un decompte : |
|
| 668 | - $init[] = calculer_dec('from', calculer_from($boucle)); |
|
| 669 | - $init[] = calculer_dec('type', calculer_from_type($boucle)); |
|
| 670 | - $init[] = calculer_dec( |
|
| 671 | - 'groupby', |
|
| 672 | - 'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ')' |
|
| 673 | - ); |
|
| 674 | - $init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . '")'); |
|
| 675 | - $init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ')'); |
|
| 676 | - $init[] = calculer_dec('where', calculer_dump_array($boucle->where)); |
|
| 677 | - $init[] = calculer_dec('join', calculer_dump_join($boucle->join)); |
|
| 678 | - $init[] = calculer_dec( |
|
| 679 | - 'limit', |
|
| 680 | - ( |
|
| 681 | - strpos($boucle->limit, 'intval') === false ? |
|
| 682 | - "'" . ($boucle->limit) . "'" : |
|
| 683 | - $boucle->limit |
|
| 684 | - ) |
|
| 685 | - ); |
|
| 686 | - $init[] = calculer_dec('having', calculer_dump_array($boucle->having)); |
|
| 687 | - $s = $d = ''; |
|
| 688 | - // l'index 0 de $i indique si l'affectation est statique (contenu) |
|
| 689 | - // ou recalculée à chaque passage (vide) |
|
| 690 | - foreach ($init as $i) { |
|
| 691 | - if (reset($i)) { |
|
| 692 | - $s .= "\n\t\t" . end($i); |
|
| 693 | - } # statique |
|
| 694 | - else { |
|
| 695 | - $d .= "\n\t" . end($i); |
|
| 696 | - } # dynamique |
|
| 697 | - } |
|
| 698 | - |
|
| 699 | - return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '') |
|
| 700 | - . $boucle->in |
|
| 701 | - . $boucle->hash |
|
| 702 | - . "\n\t" . 'if (!isset($command[\'table\'])) {' |
|
| 703 | - . $s |
|
| 704 | - . "\n\t}" |
|
| 705 | - . $d; |
|
| 664 | + $init = []; |
|
| 665 | + $init[] = calculer_dec('table', "'" . $boucle->id_table . "'"); |
|
| 666 | + $init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'"); |
|
| 667 | + # En absence de champ c'est un decompte : |
|
| 668 | + $init[] = calculer_dec('from', calculer_from($boucle)); |
|
| 669 | + $init[] = calculer_dec('type', calculer_from_type($boucle)); |
|
| 670 | + $init[] = calculer_dec( |
|
| 671 | + 'groupby', |
|
| 672 | + 'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ')' |
|
| 673 | + ); |
|
| 674 | + $init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . '")'); |
|
| 675 | + $init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ')'); |
|
| 676 | + $init[] = calculer_dec('where', calculer_dump_array($boucle->where)); |
|
| 677 | + $init[] = calculer_dec('join', calculer_dump_join($boucle->join)); |
|
| 678 | + $init[] = calculer_dec( |
|
| 679 | + 'limit', |
|
| 680 | + ( |
|
| 681 | + strpos($boucle->limit, 'intval') === false ? |
|
| 682 | + "'" . ($boucle->limit) . "'" : |
|
| 683 | + $boucle->limit |
|
| 684 | + ) |
|
| 685 | + ); |
|
| 686 | + $init[] = calculer_dec('having', calculer_dump_array($boucle->having)); |
|
| 687 | + $s = $d = ''; |
|
| 688 | + // l'index 0 de $i indique si l'affectation est statique (contenu) |
|
| 689 | + // ou recalculée à chaque passage (vide) |
|
| 690 | + foreach ($init as $i) { |
|
| 691 | + if (reset($i)) { |
|
| 692 | + $s .= "\n\t\t" . end($i); |
|
| 693 | + } # statique |
|
| 694 | + else { |
|
| 695 | + $d .= "\n\t" . end($i); |
|
| 696 | + } # dynamique |
|
| 697 | + } |
|
| 698 | + |
|
| 699 | + return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '') |
|
| 700 | + . $boucle->in |
|
| 701 | + . $boucle->hash |
|
| 702 | + . "\n\t" . 'if (!isset($command[\'table\'])) {' |
|
| 703 | + . $s |
|
| 704 | + . "\n\t}" |
|
| 705 | + . $d; |
|
| 706 | 706 | } |
| 707 | 707 | |
| 708 | 708 | /** |
@@ -720,13 +720,13 @@ discard block |
||
| 720 | 720 | * qui peut être utilisé pour la production d'un tableau array() |
| 721 | 721 | **/ |
| 722 | 722 | function memoriser_contexte_compil($p) { |
| 723 | - return join(',', [ |
|
| 724 | - _q($p->descr['sourcefile'] ?? ''), |
|
| 725 | - _q($p->descr['nom'] ?? ''), |
|
| 726 | - _q($p->id_boucle ?? ''), |
|
| 727 | - intval($p->ligne), |
|
| 728 | - '$GLOBALS[\'spip_lang\']' |
|
| 729 | - ]); |
|
| 723 | + return join(',', [ |
|
| 724 | + _q($p->descr['sourcefile'] ?? ''), |
|
| 725 | + _q($p->descr['nom'] ?? ''), |
|
| 726 | + _q($p->id_boucle ?? ''), |
|
| 727 | + intval($p->ligne), |
|
| 728 | + '$GLOBALS[\'spip_lang\']' |
|
| 729 | + ]); |
|
| 730 | 730 | } |
| 731 | 731 | |
| 732 | 732 | /** |
@@ -744,19 +744,19 @@ discard block |
||
| 744 | 744 | * Objet Contexte |
| 745 | 745 | **/ |
| 746 | 746 | function reconstruire_contexte_compil($context_compil) { |
| 747 | - if (!is_array($context_compil)) { |
|
| 748 | - return $context_compil; |
|
| 749 | - } |
|
| 750 | - $p = new Contexte(); |
|
| 751 | - $p->descr = [ |
|
| 752 | - 'sourcefile' => $context_compil[0] ?? '', |
|
| 753 | - 'nom' => $context_compil[1] ?? '', |
|
| 754 | - ]; |
|
| 755 | - $p->id_boucle = $context_compil[2] ?? ''; |
|
| 756 | - $p->ligne = $context_compil[3] ?? ''; |
|
| 757 | - $p->lang = $context_compil[4] ?? ''; |
|
| 758 | - |
|
| 759 | - return $p; |
|
| 747 | + if (!is_array($context_compil)) { |
|
| 748 | + return $context_compil; |
|
| 749 | + } |
|
| 750 | + $p = new Contexte(); |
|
| 751 | + $p->descr = [ |
|
| 752 | + 'sourcefile' => $context_compil[0] ?? '', |
|
| 753 | + 'nom' => $context_compil[1] ?? '', |
|
| 754 | + ]; |
|
| 755 | + $p->id_boucle = $context_compil[2] ?? ''; |
|
| 756 | + $p->ligne = $context_compil[3] ?? ''; |
|
| 757 | + $p->lang = $context_compil[4] ?? ''; |
|
| 758 | + |
|
| 759 | + return $p; |
|
| 760 | 760 | } |
| 761 | 761 | |
| 762 | 762 | /** |
@@ -782,12 +782,12 @@ discard block |
||
| 782 | 782 | * - index 1 : Code de l'affectation |
| 783 | 783 | **/ |
| 784 | 784 | function calculer_dec($nom, $val) { |
| 785 | - $static = 'if (!isset($command[\'' . $nom . '\'])) '; |
|
| 786 | - // si une variable apparait dans le calcul de la clause |
|
| 787 | - // il faut la re-evaluer a chaque passage |
|
| 788 | - if ( |
|
| 789 | - strpos($val, '$') !== false |
|
| 790 | - /* |
|
| 785 | + $static = 'if (!isset($command[\'' . $nom . '\'])) '; |
|
| 786 | + // si une variable apparait dans le calcul de la clause |
|
| 787 | + // il faut la re-evaluer a chaque passage |
|
| 788 | + if ( |
|
| 789 | + strpos($val, '$') !== false |
|
| 790 | + /* |
|
| 791 | 791 | OR strpos($val, 'sql_') !== false |
| 792 | 792 | OR ( |
| 793 | 793 | $test = str_replace(array("array(",'\"',"\'"),array("","",""),$val) // supprimer les array( et les echappements de guillemets |
@@ -795,11 +795,11 @@ discard block |
||
| 795 | 795 | AND $test = preg_replace(",'[^']*',UimsS","",$test) // supprimer les chaines qui peuvent contenir des fonctions SQL qui ne genent pas |
| 796 | 796 | AND preg_match(",\w+\s*\(,UimsS",$test,$regs) // tester la presence de fonctions restantes |
| 797 | 797 | )*/ |
| 798 | - ) { |
|
| 799 | - $static = ''; |
|
| 800 | - } |
|
| 798 | + ) { |
|
| 799 | + $static = ''; |
|
| 800 | + } |
|
| 801 | 801 | |
| 802 | - return [$static, '$command[\'' . $nom . '\'] = ' . $val . ';']; |
|
| 802 | + return [$static, '$command[\'' . $nom . '\'] = ' . $val . ';']; |
|
| 803 | 803 | } |
| 804 | 804 | |
| 805 | 805 | /** |
@@ -819,32 +819,32 @@ discard block |
||
| 819 | 819 | * Expression PHP décrivant un texte ou un tableau |
| 820 | 820 | **/ |
| 821 | 821 | function calculer_dump_array($a) { |
| 822 | - if (!is_array($a)) { |
|
| 823 | - return $a; |
|
| 824 | - } |
|
| 825 | - $res = ''; |
|
| 826 | - if ($a and $a[0] == "'?'") { |
|
| 827 | - return ('(' . calculer_dump_array($a[1]) . |
|
| 828 | - ' ? ' . calculer_dump_array($a[2]) . |
|
| 829 | - ' : ' . calculer_dump_array($a[3]) . |
|
| 830 | - ')'); |
|
| 831 | - } else { |
|
| 832 | - foreach ($a as $k => $v) { |
|
| 833 | - $showk = (is_numeric($k) ? '' : sql_quote($k) . ' => '); |
|
| 834 | - $res .= ', ' . $showk . calculer_dump_array($v); |
|
| 835 | - } |
|
| 836 | - |
|
| 837 | - return "\n\t\t\tarray(" . substr($res, 2) . ')'; |
|
| 838 | - } |
|
| 822 | + if (!is_array($a)) { |
|
| 823 | + return $a; |
|
| 824 | + } |
|
| 825 | + $res = ''; |
|
| 826 | + if ($a and $a[0] == "'?'") { |
|
| 827 | + return ('(' . calculer_dump_array($a[1]) . |
|
| 828 | + ' ? ' . calculer_dump_array($a[2]) . |
|
| 829 | + ' : ' . calculer_dump_array($a[3]) . |
|
| 830 | + ')'); |
|
| 831 | + } else { |
|
| 832 | + foreach ($a as $k => $v) { |
|
| 833 | + $showk = (is_numeric($k) ? '' : sql_quote($k) . ' => '); |
|
| 834 | + $res .= ', ' . $showk . calculer_dump_array($v); |
|
| 835 | + } |
|
| 836 | + |
|
| 837 | + return "\n\t\t\tarray(" . substr($res, 2) . ')'; |
|
| 838 | + } |
|
| 839 | 839 | } |
| 840 | 840 | |
| 841 | 841 | function calculer_dump_join($a) { |
| 842 | - $res = ''; |
|
| 843 | - foreach ($a as $k => $v) { |
|
| 844 | - $res .= ", '$k' => array(" . implode(',', $v) . ')'; |
|
| 845 | - } |
|
| 842 | + $res = ''; |
|
| 843 | + foreach ($a as $k => $v) { |
|
| 844 | + $res .= ", '$k' => array(" . implode(',', $v) . ')'; |
|
| 845 | + } |
|
| 846 | 846 | |
| 847 | - return 'array(' . substr($res, 2) . ')'; |
|
| 847 | + return 'array(' . substr($res, 2) . ')'; |
|
| 848 | 848 | } |
| 849 | 849 | |
| 850 | 850 | /** |
@@ -856,12 +856,12 @@ discard block |
||
| 856 | 856 | * Code PHP construisant un tableau des alias et noms des tables du FROM |
| 857 | 857 | **/ |
| 858 | 858 | function calculer_from(&$boucle) { |
| 859 | - $res = ''; |
|
| 860 | - foreach ($boucle->from as $k => $v) { |
|
| 861 | - $res .= ",'$k' => '$v'"; |
|
| 862 | - } |
|
| 859 | + $res = ''; |
|
| 860 | + foreach ($boucle->from as $k => $v) { |
|
| 861 | + $res .= ",'$k' => '$v'"; |
|
| 862 | + } |
|
| 863 | 863 | |
| 864 | - return 'array(' . substr($res, 1) . ')'; |
|
| 864 | + return 'array(' . substr($res, 1) . ')'; |
|
| 865 | 865 | } |
| 866 | 866 | |
| 867 | 867 | /** |
@@ -874,30 +874,30 @@ discard block |
||
| 874 | 874 | * Code PHP construisant un tableau des alias et type de jointure du FROM |
| 875 | 875 | **/ |
| 876 | 876 | function calculer_from_type(&$boucle) { |
| 877 | - $res = ''; |
|
| 878 | - foreach ($boucle->from_type as $k => $v) { |
|
| 879 | - $res .= ",'$k' => '$v'"; |
|
| 880 | - } |
|
| 877 | + $res = ''; |
|
| 878 | + foreach ($boucle->from_type as $k => $v) { |
|
| 879 | + $res .= ",'$k' => '$v'"; |
|
| 880 | + } |
|
| 881 | 881 | |
| 882 | - return 'array(' . substr($res, 1) . ')'; |
|
| 882 | + return 'array(' . substr($res, 1) . ')'; |
|
| 883 | 883 | } |
| 884 | 884 | |
| 885 | 885 | function calculer_order(&$boucle) { |
| 886 | - if ( |
|
| 887 | - !$order = $boucle->order |
|
| 888 | - and !$order = $boucle->default_order |
|
| 889 | - ) { |
|
| 890 | - $order = []; |
|
| 891 | - } |
|
| 892 | - |
|
| 893 | - /*if (isset($boucle->modificateur['collate'])){ |
|
| 886 | + if ( |
|
| 887 | + !$order = $boucle->order |
|
| 888 | + and !$order = $boucle->default_order |
|
| 889 | + ) { |
|
| 890 | + $order = []; |
|
| 891 | + } |
|
| 892 | + |
|
| 893 | + /*if (isset($boucle->modificateur['collate'])){ |
|
| 894 | 894 | $col = "." . $boucle->modificateur['collate']; |
| 895 | 895 | foreach($order as $k=>$o) |
| 896 | 896 | if (strpos($order[$k],'COLLATE')===false) |
| 897 | 897 | $order[$k].= $col; |
| 898 | 898 | }*/ |
| 899 | 899 | |
| 900 | - return join(', ', $order); |
|
| 900 | + return join(', ', $order); |
|
| 901 | 901 | } |
| 902 | 902 | |
| 903 | 903 | // Production du code PHP a partir de la sequence livree par le phraseur |
@@ -906,62 +906,62 @@ discard block |
||
| 906 | 906 | // (qui sera argument d'un Return ou la partie droite d'une affectation). |
| 907 | 907 | |
| 908 | 908 | function calculer_liste($tableau, $descr, &$boucles, $id_boucle = '') { |
| 909 | - if (!$tableau) { |
|
| 910 | - return "''"; |
|
| 911 | - } |
|
| 912 | - if (is_string($descr)) { |
|
| 913 | - if (isset($boucles[$descr])) { |
|
| 914 | - $idb = $descr; |
|
| 915 | - $descr = []; |
|
| 916 | - if (isset($boucles[$idb]->descr['id_mere_contexte'])) { |
|
| 917 | - $descr['id_mere'] = $boucles[$idb]->descr['id_mere_contexte']; |
|
| 918 | - } |
|
| 919 | - if (isset($boucles[$idb]->descr['sourcefile'])) { |
|
| 920 | - $descr['sourcefile'] = $boucles[$idb]->descr['sourcefile']; |
|
| 921 | - } |
|
| 922 | - } |
|
| 923 | - else { |
|
| 924 | - $descr = []; |
|
| 925 | - } |
|
| 926 | - } |
|
| 927 | - if (!isset($descr['niv'])) { |
|
| 928 | - $descr['niv'] = 0; |
|
| 929 | - } |
|
| 930 | - $codes = compile_cas($tableau, $descr, $boucles, $id_boucle); |
|
| 931 | - if ($codes === false) { |
|
| 932 | - return false; |
|
| 933 | - } |
|
| 934 | - $n = is_countable($codes) ? count($codes) : 0; |
|
| 935 | - if (!$n) { |
|
| 936 | - return "''"; |
|
| 937 | - } |
|
| 938 | - $tab = str_repeat("\t", $descr['niv']); |
|
| 939 | - if (_request('var_mode_affiche') != 'validation') { |
|
| 940 | - if ($n == 1) { |
|
| 941 | - return $codes[0]; |
|
| 942 | - } else { |
|
| 943 | - $res = ''; |
|
| 944 | - foreach ($codes as $code) { |
|
| 945 | - if ( |
|
| 946 | - !preg_match("/^'[^']*'$/", $code) |
|
| 947 | - or substr($res, -1, 1) !== "'" |
|
| 948 | - ) { |
|
| 949 | - $res .= " .\n$tab$code"; |
|
| 950 | - } else { |
|
| 951 | - $res = substr($res, 0, -1) . substr($code, 1); |
|
| 952 | - } |
|
| 953 | - } |
|
| 954 | - |
|
| 955 | - return '(' . substr($res, 2 + $descr['niv']) . ')'; |
|
| 956 | - } |
|
| 957 | - } else { |
|
| 958 | - $nom = $descr['nom'] . $id_boucle . ($descr['niv'] ?: ''); |
|
| 959 | - |
|
| 960 | - return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join( |
|
| 961 | - " ,\n$tab", |
|
| 962 | - $codes |
|
| 963 | - ) . ')))'; |
|
| 964 | - } |
|
| 909 | + if (!$tableau) { |
|
| 910 | + return "''"; |
|
| 911 | + } |
|
| 912 | + if (is_string($descr)) { |
|
| 913 | + if (isset($boucles[$descr])) { |
|
| 914 | + $idb = $descr; |
|
| 915 | + $descr = []; |
|
| 916 | + if (isset($boucles[$idb]->descr['id_mere_contexte'])) { |
|
| 917 | + $descr['id_mere'] = $boucles[$idb]->descr['id_mere_contexte']; |
|
| 918 | + } |
|
| 919 | + if (isset($boucles[$idb]->descr['sourcefile'])) { |
|
| 920 | + $descr['sourcefile'] = $boucles[$idb]->descr['sourcefile']; |
|
| 921 | + } |
|
| 922 | + } |
|
| 923 | + else { |
|
| 924 | + $descr = []; |
|
| 925 | + } |
|
| 926 | + } |
|
| 927 | + if (!isset($descr['niv'])) { |
|
| 928 | + $descr['niv'] = 0; |
|
| 929 | + } |
|
| 930 | + $codes = compile_cas($tableau, $descr, $boucles, $id_boucle); |
|
| 931 | + if ($codes === false) { |
|
| 932 | + return false; |
|
| 933 | + } |
|
| 934 | + $n = is_countable($codes) ? count($codes) : 0; |
|
| 935 | + if (!$n) { |
|
| 936 | + return "''"; |
|
| 937 | + } |
|
| 938 | + $tab = str_repeat("\t", $descr['niv']); |
|
| 939 | + if (_request('var_mode_affiche') != 'validation') { |
|
| 940 | + if ($n == 1) { |
|
| 941 | + return $codes[0]; |
|
| 942 | + } else { |
|
| 943 | + $res = ''; |
|
| 944 | + foreach ($codes as $code) { |
|
| 945 | + if ( |
|
| 946 | + !preg_match("/^'[^']*'$/", $code) |
|
| 947 | + or substr($res, -1, 1) !== "'" |
|
| 948 | + ) { |
|
| 949 | + $res .= " .\n$tab$code"; |
|
| 950 | + } else { |
|
| 951 | + $res = substr($res, 0, -1) . substr($code, 1); |
|
| 952 | + } |
|
| 953 | + } |
|
| 954 | + |
|
| 955 | + return '(' . substr($res, 2 + $descr['niv']) . ')'; |
|
| 956 | + } |
|
| 957 | + } else { |
|
| 958 | + $nom = $descr['nom'] . $id_boucle . ($descr['niv'] ?: ''); |
|
| 959 | + |
|
| 960 | + return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join( |
|
| 961 | + " ,\n$tab", |
|
| 962 | + $codes |
|
| 963 | + ) . ')))'; |
|
| 964 | + } |
|
| 965 | 965 | } |
| 966 | 966 | |
| 967 | 967 | |
@@ -971,213 +971,213 @@ discard block |
||
| 971 | 971 | |
| 972 | 972 | function compile_cas($tableau, $descr, &$boucles, $id_boucle) { |
| 973 | 973 | |
| 974 | - $codes = []; |
|
| 975 | - // cas de la boucle recursive |
|
| 976 | - if (is_array($id_boucle)) { |
|
| 977 | - $id_boucle = $id_boucle[0]; |
|
| 978 | - } |
|
| 979 | - $type = !$id_boucle ? '' : $boucles[$id_boucle]->type_requete; |
|
| 980 | - $tab = str_repeat("\t", ++$descr['niv']); |
|
| 981 | - $mode = _request('var_mode_affiche'); |
|
| 982 | - $err_e_c = ''; |
|
| 983 | - // chaque commentaire introduit dans le code doit commencer |
|
| 984 | - // par un caractere distinguant le cas, pour exploitation par debug. |
|
| 985 | - foreach ($tableau as $p) { |
|
| 986 | - switch ($p->type) { |
|
| 987 | - // texte seul |
|
| 988 | - case 'texte': |
|
| 989 | - $code = sandbox_composer_texte($p->texte, $p); |
|
| 990 | - $commentaire = strlen($p->texte) . ' signes'; |
|
| 991 | - $avant = ''; |
|
| 992 | - $apres = ''; |
|
| 993 | - $altern = "''"; |
|
| 994 | - break; |
|
| 995 | - |
|
| 996 | - case 'polyglotte': |
|
| 997 | - $code = ''; |
|
| 998 | - foreach ($p->traductions as $k => $v) { |
|
| 999 | - $code .= ",'" . |
|
| 1000 | - str_replace(['\\', "'"], ['\\\\', "\\'"], $k) . |
|
| 1001 | - "' => '" . |
|
| 1002 | - str_replace(['\\', "'"], ['\\\\', "\\'"], $v) . |
|
| 1003 | - "'"; |
|
| 1004 | - } |
|
| 1005 | - $code = 'choisir_traduction(array(' . |
|
| 1006 | - substr($code, 1) . |
|
| 1007 | - '))'; |
|
| 1008 | - $commentaire = '&'; |
|
| 1009 | - $avant = ''; |
|
| 1010 | - $apres = ''; |
|
| 1011 | - $altern = "''"; |
|
| 1012 | - break; |
|
| 1013 | - |
|
| 1014 | - // inclure |
|
| 1015 | - case 'include': |
|
| 1016 | - $p->descr = $descr; |
|
| 1017 | - $code = calculer_inclure($p, $boucles, $id_boucle); |
|
| 1018 | - if ($code === false) { |
|
| 1019 | - $err_e_c = true; |
|
| 1020 | - $code = "''"; |
|
| 1021 | - } else { |
|
| 1022 | - $commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>'; |
|
| 1023 | - $avant = ''; |
|
| 1024 | - $apres = ''; |
|
| 1025 | - $altern = "''"; |
|
| 1026 | - } |
|
| 1027 | - break; |
|
| 1028 | - |
|
| 1029 | - // boucle |
|
| 1030 | - case TYPE_RECURSIF: |
|
| 1031 | - $nom = $p->id_boucle; |
|
| 1032 | - $newdescr = $descr; |
|
| 1033 | - $newdescr['id_mere'] = $nom; |
|
| 1034 | - $newdescr['niv']++; |
|
| 1035 | - $preaff = calculer_liste($p->preaff, $newdescr, $boucles, $id_boucle); |
|
| 1036 | - $avant = calculer_liste($p->avant, $newdescr, $boucles, $id_boucle); |
|
| 1037 | - $apres = calculer_liste($p->apres, $newdescr, $boucles, $id_boucle); |
|
| 1038 | - $postaff = calculer_liste($p->postaff, $newdescr, $boucles, $id_boucle); |
|
| 1039 | - $newdescr['niv']--; |
|
| 1040 | - $altern = calculer_liste($p->altern, $newdescr, $boucles, $id_boucle); |
|
| 1041 | - if ( |
|
| 1042 | - $preaff === false |
|
| 1043 | - or $avant === false |
|
| 1044 | - or $apres === false |
|
| 1045 | - or $altern === false |
|
| 1046 | - or $postaff === false |
|
| 1047 | - ) { |
|
| 1048 | - $err_e_c = true; |
|
| 1049 | - $code = "''"; |
|
| 1050 | - } else { |
|
| 1051 | - $code = 'BOUCLE' . |
|
| 1052 | - str_replace('-', '_', $nom) . $descr['nom'] . |
|
| 1053 | - '($Cache, $Pile, $doublons, $Numrows, $SP)'; |
|
| 1054 | - $commentaire = "?$nom"; |
|
| 1055 | - if ( |
|
| 1056 | - !$boucles[$nom]->milieu |
|
| 1057 | - and $boucles[$nom]->type_requete <> TYPE_RECURSIF |
|
| 1058 | - ) { |
|
| 1059 | - if ($preaff != "''") { |
|
| 1060 | - $code .= "\n. $preaff"; |
|
| 1061 | - } |
|
| 1062 | - if ($altern != "''") { |
|
| 1063 | - $code .= "\n. $altern"; |
|
| 1064 | - } |
|
| 1065 | - if ($postaff != "''") { |
|
| 1066 | - $code .= "\n. $postaff"; |
|
| 1067 | - } |
|
| 1068 | - if ($avant <> "''" or $apres <> "''") { |
|
| 1069 | - spip_log("boucle $nom toujours vide, code superflu dans $descr[sourcefile]"); |
|
| 1070 | - } |
|
| 1071 | - $avant = $apres = $altern = "''"; |
|
| 1072 | - } else { |
|
| 1073 | - if ($preaff != "''") { |
|
| 1074 | - $avant = compile_concatene_parties_codes($preaff, $avant); |
|
| 1075 | - $altern = compile_concatene_parties_codes($preaff, $altern); |
|
| 1076 | - } |
|
| 1077 | - if ($postaff != "''") { |
|
| 1078 | - $apres = compile_concatene_parties_codes($apres, $postaff); |
|
| 1079 | - $altern = compile_concatene_parties_codes($altern, $postaff); |
|
| 1080 | - } |
|
| 1081 | - if ($altern != "''") { |
|
| 1082 | - $altern = "($altern)"; |
|
| 1083 | - } |
|
| 1084 | - } |
|
| 1085 | - } |
|
| 1086 | - break; |
|
| 1087 | - |
|
| 1088 | - case 'idiome': |
|
| 1089 | - $l = []; |
|
| 1090 | - $code = ''; |
|
| 1091 | - foreach ($p->arg as $k => $v) { |
|
| 1092 | - $_v = calculer_liste($v, $descr, $boucles, $id_boucle); |
|
| 1093 | - if ($k) { |
|
| 1094 | - $l[] = _q($k) . ' => ' . $_v; |
|
| 1095 | - } else { |
|
| 1096 | - $code = $_v; |
|
| 1097 | - } |
|
| 1098 | - } |
|
| 1099 | - // Si le module n'est pas fourni, l'expliciter sauf si calculé |
|
| 1100 | - if ($p->module) { |
|
| 1101 | - $m = $p->module . ':' . $p->nom_champ; |
|
| 1102 | - } elseif ($p->nom_champ) { |
|
| 1103 | - $m = MODULES_IDIOMES . ':' . $p->nom_champ; |
|
| 1104 | - } else { |
|
| 1105 | - $m = ''; |
|
| 1106 | - } |
|
| 1107 | - |
|
| 1108 | - $code = (!$code ? "'$m'" : |
|
| 1109 | - ($m ? "'$m' . $code" : |
|
| 1110 | - ("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))"))) |
|
| 1111 | - . (!$l ? '' : (', array(' . implode(",\n", $l) . ')')); |
|
| 1112 | - $code = "_T($code)"; |
|
| 1113 | - if ($p->param) { |
|
| 1114 | - $p->id_boucle = $id_boucle; |
|
| 1115 | - $p->boucles = &$boucles; |
|
| 1116 | - $code = compose_filtres($p, $code); |
|
| 1117 | - } |
|
| 1118 | - $commentaire = ':'; |
|
| 1119 | - $avant = ''; |
|
| 1120 | - $apres = ''; |
|
| 1121 | - $altern = "''"; |
|
| 1122 | - break; |
|
| 1123 | - |
|
| 1124 | - case 'champ': |
|
| 1125 | - // cette structure pourrait etre completee des le phrase' (a faire) |
|
| 1126 | - $p->id_boucle = $id_boucle; |
|
| 1127 | - $p->boucles = &$boucles; |
|
| 1128 | - $p->descr = $descr; |
|
| 1129 | - #$p->interdire_scripts = true; |
|
| 1130 | - $p->type_requete = $type; |
|
| 1131 | - |
|
| 1132 | - $code = calculer_champ($p); |
|
| 1133 | - $commentaire = '#' . $p->nom_champ . $p->etoile; |
|
| 1134 | - $avant = calculer_liste( |
|
| 1135 | - $p->avant, |
|
| 1136 | - $descr, |
|
| 1137 | - $boucles, |
|
| 1138 | - $id_boucle |
|
| 1139 | - ); |
|
| 1140 | - $apres = calculer_liste( |
|
| 1141 | - $p->apres, |
|
| 1142 | - $descr, |
|
| 1143 | - $boucles, |
|
| 1144 | - $id_boucle |
|
| 1145 | - ); |
|
| 1146 | - $altern = "''"; |
|
| 1147 | - // Si la valeur est destinee a une comparaison a '' |
|
| 1148 | - // forcer la conversion en une chaine par strval |
|
| 1149 | - // si ca peut etre autre chose qu'une chaine |
|
| 1150 | - if ( |
|
| 1151 | - ($avant != "''" or $apres != "''") |
|
| 1152 | - and $code[0] != "'" |
|
| 974 | + $codes = []; |
|
| 975 | + // cas de la boucle recursive |
|
| 976 | + if (is_array($id_boucle)) { |
|
| 977 | + $id_boucle = $id_boucle[0]; |
|
| 978 | + } |
|
| 979 | + $type = !$id_boucle ? '' : $boucles[$id_boucle]->type_requete; |
|
| 980 | + $tab = str_repeat("\t", ++$descr['niv']); |
|
| 981 | + $mode = _request('var_mode_affiche'); |
|
| 982 | + $err_e_c = ''; |
|
| 983 | + // chaque commentaire introduit dans le code doit commencer |
|
| 984 | + // par un caractere distinguant le cas, pour exploitation par debug. |
|
| 985 | + foreach ($tableau as $p) { |
|
| 986 | + switch ($p->type) { |
|
| 987 | + // texte seul |
|
| 988 | + case 'texte': |
|
| 989 | + $code = sandbox_composer_texte($p->texte, $p); |
|
| 990 | + $commentaire = strlen($p->texte) . ' signes'; |
|
| 991 | + $avant = ''; |
|
| 992 | + $apres = ''; |
|
| 993 | + $altern = "''"; |
|
| 994 | + break; |
|
| 995 | + |
|
| 996 | + case 'polyglotte': |
|
| 997 | + $code = ''; |
|
| 998 | + foreach ($p->traductions as $k => $v) { |
|
| 999 | + $code .= ",'" . |
|
| 1000 | + str_replace(['\\', "'"], ['\\\\', "\\'"], $k) . |
|
| 1001 | + "' => '" . |
|
| 1002 | + str_replace(['\\', "'"], ['\\\\', "\\'"], $v) . |
|
| 1003 | + "'"; |
|
| 1004 | + } |
|
| 1005 | + $code = 'choisir_traduction(array(' . |
|
| 1006 | + substr($code, 1) . |
|
| 1007 | + '))'; |
|
| 1008 | + $commentaire = '&'; |
|
| 1009 | + $avant = ''; |
|
| 1010 | + $apres = ''; |
|
| 1011 | + $altern = "''"; |
|
| 1012 | + break; |
|
| 1013 | + |
|
| 1014 | + // inclure |
|
| 1015 | + case 'include': |
|
| 1016 | + $p->descr = $descr; |
|
| 1017 | + $code = calculer_inclure($p, $boucles, $id_boucle); |
|
| 1018 | + if ($code === false) { |
|
| 1019 | + $err_e_c = true; |
|
| 1020 | + $code = "''"; |
|
| 1021 | + } else { |
|
| 1022 | + $commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>'; |
|
| 1023 | + $avant = ''; |
|
| 1024 | + $apres = ''; |
|
| 1025 | + $altern = "''"; |
|
| 1026 | + } |
|
| 1027 | + break; |
|
| 1028 | + |
|
| 1029 | + // boucle |
|
| 1030 | + case TYPE_RECURSIF: |
|
| 1031 | + $nom = $p->id_boucle; |
|
| 1032 | + $newdescr = $descr; |
|
| 1033 | + $newdescr['id_mere'] = $nom; |
|
| 1034 | + $newdescr['niv']++; |
|
| 1035 | + $preaff = calculer_liste($p->preaff, $newdescr, $boucles, $id_boucle); |
|
| 1036 | + $avant = calculer_liste($p->avant, $newdescr, $boucles, $id_boucle); |
|
| 1037 | + $apres = calculer_liste($p->apres, $newdescr, $boucles, $id_boucle); |
|
| 1038 | + $postaff = calculer_liste($p->postaff, $newdescr, $boucles, $id_boucle); |
|
| 1039 | + $newdescr['niv']--; |
|
| 1040 | + $altern = calculer_liste($p->altern, $newdescr, $boucles, $id_boucle); |
|
| 1041 | + if ( |
|
| 1042 | + $preaff === false |
|
| 1043 | + or $avant === false |
|
| 1044 | + or $apres === false |
|
| 1045 | + or $altern === false |
|
| 1046 | + or $postaff === false |
|
| 1047 | + ) { |
|
| 1048 | + $err_e_c = true; |
|
| 1049 | + $code = "''"; |
|
| 1050 | + } else { |
|
| 1051 | + $code = 'BOUCLE' . |
|
| 1052 | + str_replace('-', '_', $nom) . $descr['nom'] . |
|
| 1053 | + '($Cache, $Pile, $doublons, $Numrows, $SP)'; |
|
| 1054 | + $commentaire = "?$nom"; |
|
| 1055 | + if ( |
|
| 1056 | + !$boucles[$nom]->milieu |
|
| 1057 | + and $boucles[$nom]->type_requete <> TYPE_RECURSIF |
|
| 1058 | + ) { |
|
| 1059 | + if ($preaff != "''") { |
|
| 1060 | + $code .= "\n. $preaff"; |
|
| 1061 | + } |
|
| 1062 | + if ($altern != "''") { |
|
| 1063 | + $code .= "\n. $altern"; |
|
| 1064 | + } |
|
| 1065 | + if ($postaff != "''") { |
|
| 1066 | + $code .= "\n. $postaff"; |
|
| 1067 | + } |
|
| 1068 | + if ($avant <> "''" or $apres <> "''") { |
|
| 1069 | + spip_log("boucle $nom toujours vide, code superflu dans $descr[sourcefile]"); |
|
| 1070 | + } |
|
| 1071 | + $avant = $apres = $altern = "''"; |
|
| 1072 | + } else { |
|
| 1073 | + if ($preaff != "''") { |
|
| 1074 | + $avant = compile_concatene_parties_codes($preaff, $avant); |
|
| 1075 | + $altern = compile_concatene_parties_codes($preaff, $altern); |
|
| 1076 | + } |
|
| 1077 | + if ($postaff != "''") { |
|
| 1078 | + $apres = compile_concatene_parties_codes($apres, $postaff); |
|
| 1079 | + $altern = compile_concatene_parties_codes($altern, $postaff); |
|
| 1080 | + } |
|
| 1081 | + if ($altern != "''") { |
|
| 1082 | + $altern = "($altern)"; |
|
| 1083 | + } |
|
| 1084 | + } |
|
| 1085 | + } |
|
| 1086 | + break; |
|
| 1087 | + |
|
| 1088 | + case 'idiome': |
|
| 1089 | + $l = []; |
|
| 1090 | + $code = ''; |
|
| 1091 | + foreach ($p->arg as $k => $v) { |
|
| 1092 | + $_v = calculer_liste($v, $descr, $boucles, $id_boucle); |
|
| 1093 | + if ($k) { |
|
| 1094 | + $l[] = _q($k) . ' => ' . $_v; |
|
| 1095 | + } else { |
|
| 1096 | + $code = $_v; |
|
| 1097 | + } |
|
| 1098 | + } |
|
| 1099 | + // Si le module n'est pas fourni, l'expliciter sauf si calculé |
|
| 1100 | + if ($p->module) { |
|
| 1101 | + $m = $p->module . ':' . $p->nom_champ; |
|
| 1102 | + } elseif ($p->nom_champ) { |
|
| 1103 | + $m = MODULES_IDIOMES . ':' . $p->nom_champ; |
|
| 1104 | + } else { |
|
| 1105 | + $m = ''; |
|
| 1106 | + } |
|
| 1107 | + |
|
| 1108 | + $code = (!$code ? "'$m'" : |
|
| 1109 | + ($m ? "'$m' . $code" : |
|
| 1110 | + ("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))"))) |
|
| 1111 | + . (!$l ? '' : (', array(' . implode(",\n", $l) . ')')); |
|
| 1112 | + $code = "_T($code)"; |
|
| 1113 | + if ($p->param) { |
|
| 1114 | + $p->id_boucle = $id_boucle; |
|
| 1115 | + $p->boucles = &$boucles; |
|
| 1116 | + $code = compose_filtres($p, $code); |
|
| 1117 | + } |
|
| 1118 | + $commentaire = ':'; |
|
| 1119 | + $avant = ''; |
|
| 1120 | + $apres = ''; |
|
| 1121 | + $altern = "''"; |
|
| 1122 | + break; |
|
| 1123 | + |
|
| 1124 | + case 'champ': |
|
| 1125 | + // cette structure pourrait etre completee des le phrase' (a faire) |
|
| 1126 | + $p->id_boucle = $id_boucle; |
|
| 1127 | + $p->boucles = &$boucles; |
|
| 1128 | + $p->descr = $descr; |
|
| 1129 | + #$p->interdire_scripts = true; |
|
| 1130 | + $p->type_requete = $type; |
|
| 1131 | + |
|
| 1132 | + $code = calculer_champ($p); |
|
| 1133 | + $commentaire = '#' . $p->nom_champ . $p->etoile; |
|
| 1134 | + $avant = calculer_liste( |
|
| 1135 | + $p->avant, |
|
| 1136 | + $descr, |
|
| 1137 | + $boucles, |
|
| 1138 | + $id_boucle |
|
| 1139 | + ); |
|
| 1140 | + $apres = calculer_liste( |
|
| 1141 | + $p->apres, |
|
| 1142 | + $descr, |
|
| 1143 | + $boucles, |
|
| 1144 | + $id_boucle |
|
| 1145 | + ); |
|
| 1146 | + $altern = "''"; |
|
| 1147 | + // Si la valeur est destinee a une comparaison a '' |
|
| 1148 | + // forcer la conversion en une chaine par strval |
|
| 1149 | + // si ca peut etre autre chose qu'une chaine |
|
| 1150 | + if ( |
|
| 1151 | + ($avant != "''" or $apres != "''") |
|
| 1152 | + and $code[0] != "'" |
|
| 1153 | 1153 | # AND (strpos($code,'interdire_scripts') !== 0) |
| 1154 | - and !preg_match(_REGEXP_COND_VIDE_NONVIDE, $code) |
|
| 1155 | - and !preg_match(_REGEXP_COND_NONVIDE_VIDE, $code) |
|
| 1156 | - and !preg_match(_REGEXP_CONCAT_NON_VIDE, $code) |
|
| 1157 | - ) { |
|
| 1158 | - $code = "strval($code)"; |
|
| 1159 | - } |
|
| 1160 | - break; |
|
| 1161 | - |
|
| 1162 | - default: |
|
| 1163 | - // Erreur de construction de l'arbre de syntaxe abstraite |
|
| 1164 | - $code = "''"; |
|
| 1165 | - $p->descr = $descr; |
|
| 1166 | - $err_e_c = _T('zbug_erreur_compilation'); |
|
| 1167 | - erreur_squelette($err_e_c, $p); |
|
| 1168 | - } // switch |
|
| 1169 | - |
|
| 1170 | - if ($code != "''") { |
|
| 1171 | - $code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']); |
|
| 1172 | - $codes[] = (($mode == 'validation') ? |
|
| 1173 | - "array($code, '$commentaire', " . $p->ligne . ')' |
|
| 1174 | - : (($mode == 'code') ? |
|
| 1175 | - "\n// $commentaire\n$code" : |
|
| 1176 | - $code)); |
|
| 1177 | - } |
|
| 1178 | - } // foreach |
|
| 1179 | - |
|
| 1180 | - return $err_e_c ? false : $codes; |
|
| 1154 | + and !preg_match(_REGEXP_COND_VIDE_NONVIDE, $code) |
|
| 1155 | + and !preg_match(_REGEXP_COND_NONVIDE_VIDE, $code) |
|
| 1156 | + and !preg_match(_REGEXP_CONCAT_NON_VIDE, $code) |
|
| 1157 | + ) { |
|
| 1158 | + $code = "strval($code)"; |
|
| 1159 | + } |
|
| 1160 | + break; |
|
| 1161 | + |
|
| 1162 | + default: |
|
| 1163 | + // Erreur de construction de l'arbre de syntaxe abstraite |
|
| 1164 | + $code = "''"; |
|
| 1165 | + $p->descr = $descr; |
|
| 1166 | + $err_e_c = _T('zbug_erreur_compilation'); |
|
| 1167 | + erreur_squelette($err_e_c, $p); |
|
| 1168 | + } // switch |
|
| 1169 | + |
|
| 1170 | + if ($code != "''") { |
|
| 1171 | + $code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']); |
|
| 1172 | + $codes[] = (($mode == 'validation') ? |
|
| 1173 | + "array($code, '$commentaire', " . $p->ligne . ')' |
|
| 1174 | + : (($mode == 'code') ? |
|
| 1175 | + "\n// $commentaire\n$code" : |
|
| 1176 | + $code)); |
|
| 1177 | + } |
|
| 1178 | + } // foreach |
|
| 1179 | + |
|
| 1180 | + return $err_e_c ? false : $codes; |
|
| 1181 | 1181 | } |
| 1182 | 1182 | |
| 1183 | 1183 | /** |
@@ -1187,13 +1187,13 @@ discard block |
||
| 1187 | 1187 | * @return string |
| 1188 | 1188 | */ |
| 1189 | 1189 | function compile_concatene_parties_codes($partie1, $partie2) { |
| 1190 | - if ($partie1 === "''") { |
|
| 1191 | - return $partie2; |
|
| 1192 | - } |
|
| 1193 | - if ($partie2 === "''") { |
|
| 1194 | - return $partie1; |
|
| 1195 | - } |
|
| 1196 | - return "$partie1\n. $partie2"; |
|
| 1190 | + if ($partie1 === "''") { |
|
| 1191 | + return $partie2; |
|
| 1192 | + } |
|
| 1193 | + if ($partie2 === "''") { |
|
| 1194 | + return $partie1; |
|
| 1195 | + } |
|
| 1196 | + return "$partie1\n. $partie2"; |
|
| 1197 | 1197 | } |
| 1198 | 1198 | |
| 1199 | 1199 | |
@@ -1217,56 +1217,56 @@ discard block |
||
| 1217 | 1217 | * @return mixed|string |
| 1218 | 1218 | */ |
| 1219 | 1219 | function compile_retour($code, $avant, $apres, $altern, $tab, $n) { |
| 1220 | - if ($avant === "''") { |
|
| 1221 | - $avant = ''; |
|
| 1222 | - } |
|
| 1223 | - if ($apres === "''") { |
|
| 1224 | - $apres = ''; |
|
| 1225 | - } |
|
| 1226 | - if ($avant or $apres or ($altern !== "''")) { |
|
| 1227 | - if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)) { |
|
| 1228 | - $t = $code; |
|
| 1229 | - $cond = ''; |
|
| 1230 | - } elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) { |
|
| 1231 | - $t = $r[2]; |
|
| 1232 | - $cond = '!' . $r[1]; |
|
| 1233 | - } else { |
|
| 1234 | - if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)) { |
|
| 1235 | - $t = $r[2]; |
|
| 1236 | - $cond = $r[1]; |
|
| 1237 | - } else { |
|
| 1238 | - $t = '$t' . $n; |
|
| 1239 | - $cond = "($t = $code)!==''"; |
|
| 1240 | - } |
|
| 1241 | - } |
|
| 1242 | - |
|
| 1243 | - $res = (!$avant ? '' : "$avant . ") . |
|
| 1244 | - $t . |
|
| 1245 | - (!$apres ? '' : " . $apres"); |
|
| 1246 | - |
|
| 1247 | - if ($res !== $t) { |
|
| 1248 | - $res = "($res)"; |
|
| 1249 | - } |
|
| 1250 | - |
|
| 1251 | - $code = (!$cond ? $res : "($cond ?\n\t$tab$res :\n\t$tab$altern)"); |
|
| 1252 | - } |
|
| 1253 | - |
|
| 1254 | - return $code; |
|
| 1220 | + if ($avant === "''") { |
|
| 1221 | + $avant = ''; |
|
| 1222 | + } |
|
| 1223 | + if ($apres === "''") { |
|
| 1224 | + $apres = ''; |
|
| 1225 | + } |
|
| 1226 | + if ($avant or $apres or ($altern !== "''")) { |
|
| 1227 | + if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)) { |
|
| 1228 | + $t = $code; |
|
| 1229 | + $cond = ''; |
|
| 1230 | + } elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) { |
|
| 1231 | + $t = $r[2]; |
|
| 1232 | + $cond = '!' . $r[1]; |
|
| 1233 | + } else { |
|
| 1234 | + if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)) { |
|
| 1235 | + $t = $r[2]; |
|
| 1236 | + $cond = $r[1]; |
|
| 1237 | + } else { |
|
| 1238 | + $t = '$t' . $n; |
|
| 1239 | + $cond = "($t = $code)!==''"; |
|
| 1240 | + } |
|
| 1241 | + } |
|
| 1242 | + |
|
| 1243 | + $res = (!$avant ? '' : "$avant . ") . |
|
| 1244 | + $t . |
|
| 1245 | + (!$apres ? '' : " . $apres"); |
|
| 1246 | + |
|
| 1247 | + if ($res !== $t) { |
|
| 1248 | + $res = "($res)"; |
|
| 1249 | + } |
|
| 1250 | + |
|
| 1251 | + $code = (!$cond ? $res : "($cond ?\n\t$tab$res :\n\t$tab$altern)"); |
|
| 1252 | + } |
|
| 1253 | + |
|
| 1254 | + return $code; |
|
| 1255 | 1255 | } |
| 1256 | 1256 | |
| 1257 | 1257 | |
| 1258 | 1258 | function compile_inclure_doublons($lexemes) { |
| 1259 | - foreach ($lexemes as $v) { |
|
| 1260 | - if ($v->type === 'include' and $v->param) { |
|
| 1261 | - foreach ($v->param as $r) { |
|
| 1262 | - if (trim($r[0]) === 'doublons') { |
|
| 1263 | - return true; |
|
| 1264 | - } |
|
| 1265 | - } |
|
| 1266 | - } |
|
| 1267 | - } |
|
| 1268 | - |
|
| 1269 | - return false; |
|
| 1259 | + foreach ($lexemes as $v) { |
|
| 1260 | + if ($v->type === 'include' and $v->param) { |
|
| 1261 | + foreach ($v->param as $r) { |
|
| 1262 | + if (trim($r[0]) === 'doublons') { |
|
| 1263 | + return true; |
|
| 1264 | + } |
|
| 1265 | + } |
|
| 1266 | + } |
|
| 1267 | + } |
|
| 1268 | + |
|
| 1269 | + return false; |
|
| 1270 | 1270 | } |
| 1271 | 1271 | |
| 1272 | 1272 | // Prend en argument le texte d'un squelette, le nom de son fichier d'origine, |
@@ -1285,354 +1285,354 @@ discard block |
||
| 1285 | 1285 | // En cas d'erreur, elle retournera un tableau des 2 premiers elements seulement |
| 1286 | 1286 | |
| 1287 | 1287 | function public_compiler_dist($squelette, $nom, $gram, $sourcefile, string $connect = '') { |
| 1288 | - // Pre-traitement : reperer le charset du squelette, et le convertir |
|
| 1289 | - // Bonus : supprime le BOM |
|
| 1290 | - include_spip('inc/charsets'); |
|
| 1291 | - $squelette = transcoder_page($squelette); |
|
| 1292 | - |
|
| 1293 | - // rendre inertes les echappements de #[](){}<> |
|
| 1294 | - $i = 0; |
|
| 1295 | - while (false !== strpos($squelette, $inerte = '-INERTE' . $i)) { |
|
| 1296 | - $i++; |
|
| 1297 | - } |
|
| 1298 | - $squelette = preg_replace_callback( |
|
| 1299 | - ',\\\\([#[()\]{}<>]),', |
|
| 1300 | - fn($a) => "$inerte-" . ord($a[1]) . '-', |
|
| 1301 | - $squelette, |
|
| 1302 | - -1, |
|
| 1303 | - $esc |
|
| 1304 | - ); |
|
| 1305 | - |
|
| 1306 | - $descr = [ |
|
| 1307 | - 'nom' => $nom, |
|
| 1308 | - 'gram' => $gram, |
|
| 1309 | - 'sourcefile' => $sourcefile, |
|
| 1310 | - 'squelette' => $squelette |
|
| 1311 | - ]; |
|
| 1312 | - |
|
| 1313 | - // Phraser le squelette, selon sa grammaire |
|
| 1314 | - |
|
| 1315 | - $boucles = []; |
|
| 1316 | - $f = charger_fonction('phraser_' . $gram, 'public'); |
|
| 1317 | - |
|
| 1318 | - $squelette = $f($squelette, '', $boucles, $descr); |
|
| 1319 | - |
|
| 1320 | - $boucles = compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect); |
|
| 1321 | - |
|
| 1322 | - // restituer les echappements |
|
| 1323 | - if ($esc) { |
|
| 1324 | - foreach ($boucles as $i => $boucle) { |
|
| 1325 | - $boucles[$i]->return = preg_replace_callback( |
|
| 1326 | - ",$inerte-(\d+)-,", |
|
| 1327 | - fn($a) => chr($a[1]), |
|
| 1328 | - $boucle->return |
|
| 1329 | - ); |
|
| 1330 | - $boucles[$i]->descr['squelette'] = preg_replace_callback( |
|
| 1331 | - ",$inerte-(\d+)-,", |
|
| 1332 | - fn($a) => '\\\\' . chr($a[1]), |
|
| 1333 | - $boucle->descr['squelette'] |
|
| 1334 | - ); |
|
| 1335 | - } |
|
| 1336 | - } |
|
| 1337 | - |
|
| 1338 | - $debug = ($boucles and defined('_VAR_MODE') and _VAR_MODE == 'debug'); |
|
| 1339 | - if ($debug) { |
|
| 1340 | - include_spip('public/decompiler'); |
|
| 1341 | - foreach ($boucles as $id => $boucle) { |
|
| 1342 | - if ($id) { |
|
| 1343 | - $decomp = "\n/* BOUCLE " . |
|
| 1344 | - $boucle->type_requete . |
|
| 1345 | - ' ' . |
|
| 1346 | - str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) . |
|
| 1347 | - ($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') . |
|
| 1348 | - " */\n"; |
|
| 1349 | - } else { |
|
| 1350 | - $decomp = ("\n/*\n" . |
|
| 1351 | - str_replace('*/', '* /', public_decompiler($squelette, $gram)) |
|
| 1352 | - . "\n*/"); |
|
| 1353 | - } |
|
| 1354 | - $boucles[$id]->return = $decomp . $boucle->return; |
|
| 1355 | - $GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return; |
|
| 1356 | - } |
|
| 1357 | - } |
|
| 1358 | - |
|
| 1359 | - return $boucles; |
|
| 1288 | + // Pre-traitement : reperer le charset du squelette, et le convertir |
|
| 1289 | + // Bonus : supprime le BOM |
|
| 1290 | + include_spip('inc/charsets'); |
|
| 1291 | + $squelette = transcoder_page($squelette); |
|
| 1292 | + |
|
| 1293 | + // rendre inertes les echappements de #[](){}<> |
|
| 1294 | + $i = 0; |
|
| 1295 | + while (false !== strpos($squelette, $inerte = '-INERTE' . $i)) { |
|
| 1296 | + $i++; |
|
| 1297 | + } |
|
| 1298 | + $squelette = preg_replace_callback( |
|
| 1299 | + ',\\\\([#[()\]{}<>]),', |
|
| 1300 | + fn($a) => "$inerte-" . ord($a[1]) . '-', |
|
| 1301 | + $squelette, |
|
| 1302 | + -1, |
|
| 1303 | + $esc |
|
| 1304 | + ); |
|
| 1305 | + |
|
| 1306 | + $descr = [ |
|
| 1307 | + 'nom' => $nom, |
|
| 1308 | + 'gram' => $gram, |
|
| 1309 | + 'sourcefile' => $sourcefile, |
|
| 1310 | + 'squelette' => $squelette |
|
| 1311 | + ]; |
|
| 1312 | + |
|
| 1313 | + // Phraser le squelette, selon sa grammaire |
|
| 1314 | + |
|
| 1315 | + $boucles = []; |
|
| 1316 | + $f = charger_fonction('phraser_' . $gram, 'public'); |
|
| 1317 | + |
|
| 1318 | + $squelette = $f($squelette, '', $boucles, $descr); |
|
| 1319 | + |
|
| 1320 | + $boucles = compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect); |
|
| 1321 | + |
|
| 1322 | + // restituer les echappements |
|
| 1323 | + if ($esc) { |
|
| 1324 | + foreach ($boucles as $i => $boucle) { |
|
| 1325 | + $boucles[$i]->return = preg_replace_callback( |
|
| 1326 | + ",$inerte-(\d+)-,", |
|
| 1327 | + fn($a) => chr($a[1]), |
|
| 1328 | + $boucle->return |
|
| 1329 | + ); |
|
| 1330 | + $boucles[$i]->descr['squelette'] = preg_replace_callback( |
|
| 1331 | + ",$inerte-(\d+)-,", |
|
| 1332 | + fn($a) => '\\\\' . chr($a[1]), |
|
| 1333 | + $boucle->descr['squelette'] |
|
| 1334 | + ); |
|
| 1335 | + } |
|
| 1336 | + } |
|
| 1337 | + |
|
| 1338 | + $debug = ($boucles and defined('_VAR_MODE') and _VAR_MODE == 'debug'); |
|
| 1339 | + if ($debug) { |
|
| 1340 | + include_spip('public/decompiler'); |
|
| 1341 | + foreach ($boucles as $id => $boucle) { |
|
| 1342 | + if ($id) { |
|
| 1343 | + $decomp = "\n/* BOUCLE " . |
|
| 1344 | + $boucle->type_requete . |
|
| 1345 | + ' ' . |
|
| 1346 | + str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) . |
|
| 1347 | + ($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') . |
|
| 1348 | + " */\n"; |
|
| 1349 | + } else { |
|
| 1350 | + $decomp = ("\n/*\n" . |
|
| 1351 | + str_replace('*/', '* /', public_decompiler($squelette, $gram)) |
|
| 1352 | + . "\n*/"); |
|
| 1353 | + } |
|
| 1354 | + $boucles[$id]->return = $decomp . $boucle->return; |
|
| 1355 | + $GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return; |
|
| 1356 | + } |
|
| 1357 | + } |
|
| 1358 | + |
|
| 1359 | + return $boucles; |
|
| 1360 | 1360 | } |
| 1361 | 1361 | |
| 1362 | 1362 | // Point d'entree pour arbre de syntaxe abstraite fourni en premier argument |
| 1363 | 1363 | // Autres specifications comme ci-dessus |
| 1364 | 1364 | |
| 1365 | 1365 | function compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, string $connect = '') { |
| 1366 | - static $trouver_table; |
|
| 1367 | - spip_timer('calcul_skel'); |
|
| 1368 | - |
|
| 1369 | - if (defined('_VAR_MODE') and _VAR_MODE == 'debug') { |
|
| 1370 | - $GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette']; |
|
| 1371 | - $GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile; |
|
| 1372 | - |
|
| 1373 | - if (!isset($GLOBALS['debug_objets']['principal'])) { |
|
| 1374 | - $GLOBALS['debug_objets']['principal'] = $nom; |
|
| 1375 | - } |
|
| 1376 | - } |
|
| 1377 | - foreach ($boucles as $id => $boucle) { |
|
| 1378 | - $GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle; |
|
| 1379 | - } |
|
| 1380 | - $descr['documents'] = compile_inclure_doublons($squelette); |
|
| 1381 | - |
|
| 1382 | - // Demander la description des tables une fois pour toutes |
|
| 1383 | - if (!$trouver_table) { |
|
| 1384 | - $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 1385 | - } |
|
| 1386 | - |
|
| 1387 | - // reperer si les doublons sont demandes |
|
| 1388 | - // pour un inclure ou une boucle document |
|
| 1389 | - // c'est utile a la fonction champs_traitements |
|
| 1390 | - foreach ($boucles as $id => $boucle) { |
|
| 1391 | - if (!($type = $boucle->type_requete)) { |
|
| 1392 | - continue; |
|
| 1393 | - } |
|
| 1394 | - if ( |
|
| 1395 | - !$descr['documents'] and ( |
|
| 1396 | - (($type == 'documents') and $boucle->doublons) or |
|
| 1397 | - compile_inclure_doublons($boucle->avant) or |
|
| 1398 | - compile_inclure_doublons($boucle->apres) or |
|
| 1399 | - compile_inclure_doublons($boucle->milieu) or |
|
| 1400 | - compile_inclure_doublons($boucle->altern)) |
|
| 1401 | - ) { |
|
| 1402 | - $descr['documents'] = true; |
|
| 1403 | - } |
|
| 1404 | - if ($type != TYPE_RECURSIF) { |
|
| 1405 | - if (!$boucles[$id]->sql_serveur and $connect) { |
|
| 1406 | - $boucles[$id]->sql_serveur = $connect; |
|
| 1407 | - } |
|
| 1408 | - |
|
| 1409 | - // chercher dans les iterateurs du repertoire iterateur/ |
|
| 1410 | - if ( |
|
| 1411 | - $g = charger_fonction( |
|
| 1412 | - preg_replace('/\W/', '_', $boucle->type_requete), |
|
| 1413 | - 'iterateur', |
|
| 1414 | - true |
|
| 1415 | - ) |
|
| 1416 | - ) { |
|
| 1417 | - $boucles[$id] = $g($boucle); |
|
| 1418 | - |
|
| 1419 | - // sinon, en cas de requeteur d'un type predefini, |
|
| 1420 | - // utiliser les informations donnees par le requeteur |
|
| 1421 | - // cas "php:xx" et "data:xx". |
|
| 1422 | - } else { |
|
| 1423 | - if ($boucle->sql_serveur and $requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true)) { |
|
| 1424 | - $requeteur($boucles, $boucle, $id); |
|
| 1425 | - |
|
| 1426 | - // utiliser la description des champs transmis |
|
| 1427 | - } else { |
|
| 1428 | - $show = $trouver_table($type, $boucles[$id]->sql_serveur); |
|
| 1429 | - // si la table n'existe pas avec le connecteur par defaut, |
|
| 1430 | - // c'est peut etre une table qui necessite son connecteur dedie fourni |
|
| 1431 | - // permet une ecriture allegee (GEO) -> (geo:GEO) |
|
| 1432 | - if ( |
|
| 1433 | - !$show |
|
| 1434 | - and $show = $trouver_table($type, strtolower($type)) |
|
| 1435 | - ) { |
|
| 1436 | - $boucles[$id]->sql_serveur = strtolower($type); |
|
| 1437 | - } |
|
| 1438 | - if ($show) { |
|
| 1439 | - $boucles[$id]->show = $show; |
|
| 1440 | - // recopie les infos les plus importantes |
|
| 1441 | - $boucles[$id]->primary = $show['key']['PRIMARY KEY'] ?? ''; |
|
| 1442 | - $boucles[$id]->id_table = $x = preg_replace(',^spip_,', '', $show['id_table']); |
|
| 1443 | - $boucles[$id]->from[$x] = $nom_table = $show['table']; |
|
| 1444 | - $boucles[$id]->iterateur = 'SQL'; |
|
| 1445 | - |
|
| 1446 | - if (empty($boucles[$id]->descr)) { |
|
| 1447 | - $boucles[$id]->descr = &$descr; |
|
| 1448 | - } |
|
| 1449 | - if ( |
|
| 1450 | - (!$boucles[$id]->jointures) |
|
| 1451 | - and is_array($show['tables_jointures']) |
|
| 1452 | - and count($x = $show['tables_jointures']) |
|
| 1453 | - ) { |
|
| 1454 | - $boucles[$id]->jointures = $x; |
|
| 1455 | - } |
|
| 1456 | - if ($boucles[$id]->jointures_explicites) { |
|
| 1457 | - $jointures = preg_split('/\s+/', $boucles[$id]->jointures_explicites); |
|
| 1458 | - while ($j = array_pop($jointures)) { |
|
| 1459 | - array_unshift($boucles[$id]->jointures, $j); |
|
| 1460 | - } |
|
| 1461 | - } |
|
| 1462 | - } else { |
|
| 1463 | - // Pas une erreur si la table est optionnelle |
|
| 1464 | - if ($boucles[$id]->table_optionnelle) { |
|
| 1465 | - $boucles[$id]->type_requete = ''; |
|
| 1466 | - } else { |
|
| 1467 | - $boucles[$id]->type_requete = false; |
|
| 1468 | - $boucle = $boucles[$id]; |
|
| 1469 | - $x = (!$boucle->sql_serveur ? '' : |
|
| 1470 | - ($boucle->sql_serveur . ':')) . |
|
| 1471 | - $type; |
|
| 1472 | - $msg = [ |
|
| 1473 | - 'zbug_table_inconnue', |
|
| 1474 | - ['table' => $x] |
|
| 1475 | - ]; |
|
| 1476 | - erreur_squelette($msg, $boucle); |
|
| 1477 | - } |
|
| 1478 | - } |
|
| 1479 | - } |
|
| 1480 | - } |
|
| 1481 | - } |
|
| 1482 | - } |
|
| 1483 | - |
|
| 1484 | - // Commencer par reperer les boucles appelees explicitement |
|
| 1485 | - // car elles indexent les arguments de maniere derogatoire |
|
| 1486 | - foreach ($boucles as $id => $boucle) { |
|
| 1487 | - if ($boucle->type_requete == TYPE_RECURSIF and $boucle->param) { |
|
| 1488 | - $boucles[$id]->descr = &$descr; |
|
| 1489 | - $rec = &$boucles[$boucle->param[0]]; |
|
| 1490 | - if (!$rec) { |
|
| 1491 | - $msg = [ |
|
| 1492 | - 'zbug_boucle_recursive_undef', |
|
| 1493 | - ['nom' => $boucle->param[0]] |
|
| 1494 | - ]; |
|
| 1495 | - erreur_squelette($msg, $boucle); |
|
| 1496 | - $boucles[$id]->type_requete = false; |
|
| 1497 | - } else { |
|
| 1498 | - $rec->externe = $id; |
|
| 1499 | - $descr['id_mere'] = $id; |
|
| 1500 | - $boucles[$id]->return = |
|
| 1501 | - calculer_liste( |
|
| 1502 | - [$rec], |
|
| 1503 | - $descr, |
|
| 1504 | - $boucles, |
|
| 1505 | - $boucle->param |
|
| 1506 | - ); |
|
| 1507 | - } |
|
| 1508 | - } |
|
| 1509 | - } |
|
| 1510 | - foreach ($boucles as $id => $boucle) { |
|
| 1511 | - $id = strval($id); // attention au type dans index_pile |
|
| 1512 | - $type = $boucle->type_requete; |
|
| 1513 | - if ($type and $type != TYPE_RECURSIF) { |
|
| 1514 | - $res = ''; |
|
| 1515 | - if ($boucle->param) { |
|
| 1516 | - // retourne un tableau en cas d'erreur |
|
| 1517 | - $res = calculer_criteres($id, $boucles); |
|
| 1518 | - } |
|
| 1519 | - $descr['id_mere'] = $id; |
|
| 1520 | - $boucles[$id]->return = |
|
| 1521 | - calculer_liste( |
|
| 1522 | - $boucle->milieu, |
|
| 1523 | - $descr, |
|
| 1524 | - $boucles, |
|
| 1525 | - $id |
|
| 1526 | - ); |
|
| 1527 | - // Si les criteres se sont mal compiles |
|
| 1528 | - // ne pas tenter d'assembler le code final |
|
| 1529 | - // (mais compiler le corps pour detection d'erreurs) |
|
| 1530 | - if (is_array($res)) { |
|
| 1531 | - $boucles[$id]->type_requete = false; |
|
| 1532 | - } |
|
| 1533 | - } |
|
| 1534 | - } |
|
| 1535 | - |
|
| 1536 | - // idem pour la racine |
|
| 1537 | - $descr['id_mere'] = ''; |
|
| 1538 | - $corps = calculer_liste($squelette, $descr, $boucles); |
|
| 1539 | - |
|
| 1540 | - |
|
| 1541 | - // Calcul du corps de toutes les fonctions PHP, |
|
| 1542 | - // en particulier les requetes SQL et TOTAL_BOUCLE |
|
| 1543 | - // de'terminables seulement maintenant |
|
| 1544 | - |
|
| 1545 | - foreach ($boucles as $id => $boucle) { |
|
| 1546 | - $boucle = $boucles[$id] = pipeline('pre_boucle', $boucle); |
|
| 1547 | - if ($boucle->return === false) { |
|
| 1548 | - $corps = false; |
|
| 1549 | - continue; |
|
| 1550 | - } |
|
| 1551 | - // appeler la fonction de definition de la boucle |
|
| 1552 | - |
|
| 1553 | - if ($req = $boucle->type_requete) { |
|
| 1554 | - // boucle personnalisée ? |
|
| 1555 | - $table = strtoupper($boucle->type_requete); |
|
| 1556 | - $serveur = strtolower($boucle->sql_serveur); |
|
| 1557 | - if ( |
|
| 1558 | - // fonction de boucle avec serveur & table |
|
| 1559 | - (!$serveur or |
|
| 1560 | - ((!function_exists($f = 'boucle_' . $serveur . '_' . $table)) |
|
| 1561 | - and (!function_exists($f = $f . '_dist')) |
|
| 1562 | - ) |
|
| 1563 | - ) |
|
| 1564 | - // fonction de boucle avec table |
|
| 1565 | - and (!function_exists($f = 'boucle_' . $table)) |
|
| 1566 | - and (!function_exists($f = $f . '_dist')) |
|
| 1567 | - ) { |
|
| 1568 | - // fonction de boucle standard |
|
| 1569 | - if (!function_exists($f = 'boucle_DEFAUT')) { |
|
| 1570 | - $f = 'boucle_DEFAUT_dist'; |
|
| 1571 | - } |
|
| 1572 | - } |
|
| 1573 | - |
|
| 1574 | - $req = "\n\n\tstatic \$command = array();\n\t" . |
|
| 1575 | - "static \$connect;\n\t" . |
|
| 1576 | - "\$command['connect'] = \$connect = " . |
|
| 1577 | - _q($boucle->sql_serveur) . |
|
| 1578 | - ';' . |
|
| 1579 | - $f($id, $boucles); |
|
| 1580 | - } else { |
|
| 1581 | - $req = ("\n\treturn '';"); |
|
| 1582 | - } |
|
| 1583 | - |
|
| 1584 | - $boucles[$id]->return = |
|
| 1585 | - "\n\nfunction BOUCLE" . strtr($id, '-', '_') . $nom . |
|
| 1586 | - '(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' . |
|
| 1587 | - $req . |
|
| 1588 | - "\n}\n"; |
|
| 1589 | - } |
|
| 1590 | - |
|
| 1591 | - // Au final, si le corps ou un critere au moins s'est mal compile |
|
| 1592 | - // retourner False, sinon inserer leur decompilation |
|
| 1593 | - if (is_bool($corps)) { |
|
| 1594 | - return false; |
|
| 1595 | - } |
|
| 1596 | - |
|
| 1597 | - $principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) { |
|
| 1366 | + static $trouver_table; |
|
| 1367 | + spip_timer('calcul_skel'); |
|
| 1368 | + |
|
| 1369 | + if (defined('_VAR_MODE') and _VAR_MODE == 'debug') { |
|
| 1370 | + $GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette']; |
|
| 1371 | + $GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile; |
|
| 1372 | + |
|
| 1373 | + if (!isset($GLOBALS['debug_objets']['principal'])) { |
|
| 1374 | + $GLOBALS['debug_objets']['principal'] = $nom; |
|
| 1375 | + } |
|
| 1376 | + } |
|
| 1377 | + foreach ($boucles as $id => $boucle) { |
|
| 1378 | + $GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle; |
|
| 1379 | + } |
|
| 1380 | + $descr['documents'] = compile_inclure_doublons($squelette); |
|
| 1381 | + |
|
| 1382 | + // Demander la description des tables une fois pour toutes |
|
| 1383 | + if (!$trouver_table) { |
|
| 1384 | + $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 1385 | + } |
|
| 1386 | + |
|
| 1387 | + // reperer si les doublons sont demandes |
|
| 1388 | + // pour un inclure ou une boucle document |
|
| 1389 | + // c'est utile a la fonction champs_traitements |
|
| 1390 | + foreach ($boucles as $id => $boucle) { |
|
| 1391 | + if (!($type = $boucle->type_requete)) { |
|
| 1392 | + continue; |
|
| 1393 | + } |
|
| 1394 | + if ( |
|
| 1395 | + !$descr['documents'] and ( |
|
| 1396 | + (($type == 'documents') and $boucle->doublons) or |
|
| 1397 | + compile_inclure_doublons($boucle->avant) or |
|
| 1398 | + compile_inclure_doublons($boucle->apres) or |
|
| 1399 | + compile_inclure_doublons($boucle->milieu) or |
|
| 1400 | + compile_inclure_doublons($boucle->altern)) |
|
| 1401 | + ) { |
|
| 1402 | + $descr['documents'] = true; |
|
| 1403 | + } |
|
| 1404 | + if ($type != TYPE_RECURSIF) { |
|
| 1405 | + if (!$boucles[$id]->sql_serveur and $connect) { |
|
| 1406 | + $boucles[$id]->sql_serveur = $connect; |
|
| 1407 | + } |
|
| 1408 | + |
|
| 1409 | + // chercher dans les iterateurs du repertoire iterateur/ |
|
| 1410 | + if ( |
|
| 1411 | + $g = charger_fonction( |
|
| 1412 | + preg_replace('/\W/', '_', $boucle->type_requete), |
|
| 1413 | + 'iterateur', |
|
| 1414 | + true |
|
| 1415 | + ) |
|
| 1416 | + ) { |
|
| 1417 | + $boucles[$id] = $g($boucle); |
|
| 1418 | + |
|
| 1419 | + // sinon, en cas de requeteur d'un type predefini, |
|
| 1420 | + // utiliser les informations donnees par le requeteur |
|
| 1421 | + // cas "php:xx" et "data:xx". |
|
| 1422 | + } else { |
|
| 1423 | + if ($boucle->sql_serveur and $requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true)) { |
|
| 1424 | + $requeteur($boucles, $boucle, $id); |
|
| 1425 | + |
|
| 1426 | + // utiliser la description des champs transmis |
|
| 1427 | + } else { |
|
| 1428 | + $show = $trouver_table($type, $boucles[$id]->sql_serveur); |
|
| 1429 | + // si la table n'existe pas avec le connecteur par defaut, |
|
| 1430 | + // c'est peut etre une table qui necessite son connecteur dedie fourni |
|
| 1431 | + // permet une ecriture allegee (GEO) -> (geo:GEO) |
|
| 1432 | + if ( |
|
| 1433 | + !$show |
|
| 1434 | + and $show = $trouver_table($type, strtolower($type)) |
|
| 1435 | + ) { |
|
| 1436 | + $boucles[$id]->sql_serveur = strtolower($type); |
|
| 1437 | + } |
|
| 1438 | + if ($show) { |
|
| 1439 | + $boucles[$id]->show = $show; |
|
| 1440 | + // recopie les infos les plus importantes |
|
| 1441 | + $boucles[$id]->primary = $show['key']['PRIMARY KEY'] ?? ''; |
|
| 1442 | + $boucles[$id]->id_table = $x = preg_replace(',^spip_,', '', $show['id_table']); |
|
| 1443 | + $boucles[$id]->from[$x] = $nom_table = $show['table']; |
|
| 1444 | + $boucles[$id]->iterateur = 'SQL'; |
|
| 1445 | + |
|
| 1446 | + if (empty($boucles[$id]->descr)) { |
|
| 1447 | + $boucles[$id]->descr = &$descr; |
|
| 1448 | + } |
|
| 1449 | + if ( |
|
| 1450 | + (!$boucles[$id]->jointures) |
|
| 1451 | + and is_array($show['tables_jointures']) |
|
| 1452 | + and count($x = $show['tables_jointures']) |
|
| 1453 | + ) { |
|
| 1454 | + $boucles[$id]->jointures = $x; |
|
| 1455 | + } |
|
| 1456 | + if ($boucles[$id]->jointures_explicites) { |
|
| 1457 | + $jointures = preg_split('/\s+/', $boucles[$id]->jointures_explicites); |
|
| 1458 | + while ($j = array_pop($jointures)) { |
|
| 1459 | + array_unshift($boucles[$id]->jointures, $j); |
|
| 1460 | + } |
|
| 1461 | + } |
|
| 1462 | + } else { |
|
| 1463 | + // Pas une erreur si la table est optionnelle |
|
| 1464 | + if ($boucles[$id]->table_optionnelle) { |
|
| 1465 | + $boucles[$id]->type_requete = ''; |
|
| 1466 | + } else { |
|
| 1467 | + $boucles[$id]->type_requete = false; |
|
| 1468 | + $boucle = $boucles[$id]; |
|
| 1469 | + $x = (!$boucle->sql_serveur ? '' : |
|
| 1470 | + ($boucle->sql_serveur . ':')) . |
|
| 1471 | + $type; |
|
| 1472 | + $msg = [ |
|
| 1473 | + 'zbug_table_inconnue', |
|
| 1474 | + ['table' => $x] |
|
| 1475 | + ]; |
|
| 1476 | + erreur_squelette($msg, $boucle); |
|
| 1477 | + } |
|
| 1478 | + } |
|
| 1479 | + } |
|
| 1480 | + } |
|
| 1481 | + } |
|
| 1482 | + } |
|
| 1483 | + |
|
| 1484 | + // Commencer par reperer les boucles appelees explicitement |
|
| 1485 | + // car elles indexent les arguments de maniere derogatoire |
|
| 1486 | + foreach ($boucles as $id => $boucle) { |
|
| 1487 | + if ($boucle->type_requete == TYPE_RECURSIF and $boucle->param) { |
|
| 1488 | + $boucles[$id]->descr = &$descr; |
|
| 1489 | + $rec = &$boucles[$boucle->param[0]]; |
|
| 1490 | + if (!$rec) { |
|
| 1491 | + $msg = [ |
|
| 1492 | + 'zbug_boucle_recursive_undef', |
|
| 1493 | + ['nom' => $boucle->param[0]] |
|
| 1494 | + ]; |
|
| 1495 | + erreur_squelette($msg, $boucle); |
|
| 1496 | + $boucles[$id]->type_requete = false; |
|
| 1497 | + } else { |
|
| 1498 | + $rec->externe = $id; |
|
| 1499 | + $descr['id_mere'] = $id; |
|
| 1500 | + $boucles[$id]->return = |
|
| 1501 | + calculer_liste( |
|
| 1502 | + [$rec], |
|
| 1503 | + $descr, |
|
| 1504 | + $boucles, |
|
| 1505 | + $boucle->param |
|
| 1506 | + ); |
|
| 1507 | + } |
|
| 1508 | + } |
|
| 1509 | + } |
|
| 1510 | + foreach ($boucles as $id => $boucle) { |
|
| 1511 | + $id = strval($id); // attention au type dans index_pile |
|
| 1512 | + $type = $boucle->type_requete; |
|
| 1513 | + if ($type and $type != TYPE_RECURSIF) { |
|
| 1514 | + $res = ''; |
|
| 1515 | + if ($boucle->param) { |
|
| 1516 | + // retourne un tableau en cas d'erreur |
|
| 1517 | + $res = calculer_criteres($id, $boucles); |
|
| 1518 | + } |
|
| 1519 | + $descr['id_mere'] = $id; |
|
| 1520 | + $boucles[$id]->return = |
|
| 1521 | + calculer_liste( |
|
| 1522 | + $boucle->milieu, |
|
| 1523 | + $descr, |
|
| 1524 | + $boucles, |
|
| 1525 | + $id |
|
| 1526 | + ); |
|
| 1527 | + // Si les criteres se sont mal compiles |
|
| 1528 | + // ne pas tenter d'assembler le code final |
|
| 1529 | + // (mais compiler le corps pour detection d'erreurs) |
|
| 1530 | + if (is_array($res)) { |
|
| 1531 | + $boucles[$id]->type_requete = false; |
|
| 1532 | + } |
|
| 1533 | + } |
|
| 1534 | + } |
|
| 1535 | + |
|
| 1536 | + // idem pour la racine |
|
| 1537 | + $descr['id_mere'] = ''; |
|
| 1538 | + $corps = calculer_liste($squelette, $descr, $boucles); |
|
| 1539 | + |
|
| 1540 | + |
|
| 1541 | + // Calcul du corps de toutes les fonctions PHP, |
|
| 1542 | + // en particulier les requetes SQL et TOTAL_BOUCLE |
|
| 1543 | + // de'terminables seulement maintenant |
|
| 1544 | + |
|
| 1545 | + foreach ($boucles as $id => $boucle) { |
|
| 1546 | + $boucle = $boucles[$id] = pipeline('pre_boucle', $boucle); |
|
| 1547 | + if ($boucle->return === false) { |
|
| 1548 | + $corps = false; |
|
| 1549 | + continue; |
|
| 1550 | + } |
|
| 1551 | + // appeler la fonction de definition de la boucle |
|
| 1552 | + |
|
| 1553 | + if ($req = $boucle->type_requete) { |
|
| 1554 | + // boucle personnalisée ? |
|
| 1555 | + $table = strtoupper($boucle->type_requete); |
|
| 1556 | + $serveur = strtolower($boucle->sql_serveur); |
|
| 1557 | + if ( |
|
| 1558 | + // fonction de boucle avec serveur & table |
|
| 1559 | + (!$serveur or |
|
| 1560 | + ((!function_exists($f = 'boucle_' . $serveur . '_' . $table)) |
|
| 1561 | + and (!function_exists($f = $f . '_dist')) |
|
| 1562 | + ) |
|
| 1563 | + ) |
|
| 1564 | + // fonction de boucle avec table |
|
| 1565 | + and (!function_exists($f = 'boucle_' . $table)) |
|
| 1566 | + and (!function_exists($f = $f . '_dist')) |
|
| 1567 | + ) { |
|
| 1568 | + // fonction de boucle standard |
|
| 1569 | + if (!function_exists($f = 'boucle_DEFAUT')) { |
|
| 1570 | + $f = 'boucle_DEFAUT_dist'; |
|
| 1571 | + } |
|
| 1572 | + } |
|
| 1573 | + |
|
| 1574 | + $req = "\n\n\tstatic \$command = array();\n\t" . |
|
| 1575 | + "static \$connect;\n\t" . |
|
| 1576 | + "\$command['connect'] = \$connect = " . |
|
| 1577 | + _q($boucle->sql_serveur) . |
|
| 1578 | + ';' . |
|
| 1579 | + $f($id, $boucles); |
|
| 1580 | + } else { |
|
| 1581 | + $req = ("\n\treturn '';"); |
|
| 1582 | + } |
|
| 1583 | + |
|
| 1584 | + $boucles[$id]->return = |
|
| 1585 | + "\n\nfunction BOUCLE" . strtr($id, '-', '_') . $nom . |
|
| 1586 | + '(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' . |
|
| 1587 | + $req . |
|
| 1588 | + "\n}\n"; |
|
| 1589 | + } |
|
| 1590 | + |
|
| 1591 | + // Au final, si le corps ou un critere au moins s'est mal compile |
|
| 1592 | + // retourner False, sinon inserer leur decompilation |
|
| 1593 | + if (is_bool($corps)) { |
|
| 1594 | + return false; |
|
| 1595 | + } |
|
| 1596 | + |
|
| 1597 | + $principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) { |
|
| 1598 | 1598 | ' |
| 1599 | - // reporter de maniere securisee les doublons inclus |
|
| 1600 | - . ' |
|
| 1599 | + // reporter de maniere securisee les doublons inclus |
|
| 1600 | + . ' |
|
| 1601 | 1601 | if (isset($Pile[0]["doublons"]) AND is_array($Pile[0]["doublons"])) |
| 1602 | 1602 | $doublons = nettoyer_env_doublons($Pile[0]["doublons"]); |
| 1603 | 1603 | |
| 1604 | 1604 | $connect = ' . |
| 1605 | - _q($connect) . '; |
|
| 1605 | + _q($connect) . '; |
|
| 1606 | 1606 | $page = ' . |
| 1607 | - // ATTENTION, le calcul de l'expression $corps affectera $Cache |
|
| 1608 | - // c'est pourquoi on l'affecte a la variable auxiliaire $page. |
|
| 1609 | - // avant de referencer $Cache |
|
| 1610 | - $corps . '; |
|
| 1607 | + // ATTENTION, le calcul de l'expression $corps affectera $Cache |
|
| 1608 | + // c'est pourquoi on l'affecte a la variable auxiliaire $page. |
|
| 1609 | + // avant de referencer $Cache |
|
| 1610 | + $corps . '; |
|
| 1611 | 1611 | |
| 1612 | 1612 | return analyse_resultat_skel(' . var_export($nom, true) |
| 1613 | - . ', $Cache, $page, ' . var_export($sourcefile, true) . '); |
|
| 1613 | + . ', $Cache, $page, ' . var_export($sourcefile, true) . '); |
|
| 1614 | 1614 | }'; |
| 1615 | 1615 | |
| 1616 | - $secondes = spip_timer('calcul_skel'); |
|
| 1617 | - spip_log("COMPIL ($secondes) [$sourcefile] $nom.php"); |
|
| 1618 | - // $connect n'est pas sûr : on nettoie |
|
| 1619 | - $connect = preg_replace(',[^\w],', '', $connect); |
|
| 1616 | + $secondes = spip_timer('calcul_skel'); |
|
| 1617 | + spip_log("COMPIL ($secondes) [$sourcefile] $nom.php"); |
|
| 1618 | + // $connect n'est pas sûr : on nettoie |
|
| 1619 | + $connect = preg_replace(',[^\w],', '', $connect); |
|
| 1620 | 1620 | |
| 1621 | - // Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple |
|
| 1622 | - $code = new Boucle(); |
|
| 1623 | - $code->descr = $descr; |
|
| 1624 | - $code->return = ' |
|
| 1621 | + // Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple |
|
| 1622 | + $code = new Boucle(); |
|
| 1623 | + $code->descr = $descr; |
|
| 1624 | + $code->return = ' |
|
| 1625 | 1625 | // |
| 1626 | 1626 | // Fonction principale du squelette ' . |
| 1627 | - $sourcefile . |
|
| 1628 | - ($connect ? " pour $connect" : '') . |
|
| 1629 | - (!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") . |
|
| 1630 | - "\n//\n" . |
|
| 1631 | - $principal; |
|
| 1627 | + $sourcefile . |
|
| 1628 | + ($connect ? " pour $connect" : '') . |
|
| 1629 | + (!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") . |
|
| 1630 | + "\n//\n" . |
|
| 1631 | + $principal; |
|
| 1632 | 1632 | |
| 1633 | - $boucles[''] = $code; |
|
| 1633 | + $boucles[''] = $code; |
|
| 1634 | 1634 | |
| 1635 | - return $boucles; |
|
| 1635 | + return $boucles; |
|
| 1636 | 1636 | } |
| 1637 | 1637 | |
| 1638 | 1638 | |
@@ -1649,18 +1649,18 @@ discard block |
||
| 1649 | 1649 | * |
| 1650 | 1650 | **/ |
| 1651 | 1651 | function requeteur_php_dist(&$boucles, &$boucle, &$id) { |
| 1652 | - if (class_exists($boucle->type_requete)) { |
|
| 1653 | - $g = charger_fonction('php', 'iterateur'); |
|
| 1654 | - $boucles[$id] = $g($boucle, $boucle->type_requete); |
|
| 1655 | - } else { |
|
| 1656 | - $x = $boucle->type_requete; |
|
| 1657 | - $boucle->type_requete = false; |
|
| 1658 | - $msg = [ |
|
| 1659 | - 'zbug_iterateur_inconnu', |
|
| 1660 | - ['iterateur' => $x] |
|
| 1661 | - ]; |
|
| 1662 | - erreur_squelette($msg, $boucle); |
|
| 1663 | - } |
|
| 1652 | + if (class_exists($boucle->type_requete)) { |
|
| 1653 | + $g = charger_fonction('php', 'iterateur'); |
|
| 1654 | + $boucles[$id] = $g($boucle, $boucle->type_requete); |
|
| 1655 | + } else { |
|
| 1656 | + $x = $boucle->type_requete; |
|
| 1657 | + $boucle->type_requete = false; |
|
| 1658 | + $msg = [ |
|
| 1659 | + 'zbug_iterateur_inconnu', |
|
| 1660 | + ['iterateur' => $x] |
|
| 1661 | + ]; |
|
| 1662 | + erreur_squelette($msg, $boucle); |
|
| 1663 | + } |
|
| 1664 | 1664 | } |
| 1665 | 1665 | |
| 1666 | 1666 | |
@@ -1678,22 +1678,22 @@ discard block |
||
| 1678 | 1678 | * |
| 1679 | 1679 | **/ |
| 1680 | 1680 | function requeteur_data_dist(&$boucles, &$boucle, &$id) { |
| 1681 | - include_spip('iterateur/data'); |
|
| 1682 | - if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) { |
|
| 1683 | - $g = charger_fonction('data', 'iterateur'); |
|
| 1684 | - $boucles[$id] = $g($boucle); |
|
| 1685 | - // from[0] stocke le type de data (rss, yql, ...) |
|
| 1686 | - $boucles[$id]->from[] = $boucle->type_requete; |
|
| 1687 | - } else { |
|
| 1688 | - $x = $boucle->type_requete; |
|
| 1689 | - $boucle->type_requete = false; |
|
| 1690 | - $msg = [ |
|
| 1691 | - 'zbug_requeteur_inconnu', |
|
| 1692 | - [ |
|
| 1693 | - 'requeteur' => 'data', |
|
| 1694 | - 'type' => $x |
|
| 1695 | - ] |
|
| 1696 | - ]; |
|
| 1697 | - erreur_squelette($msg, $boucle); |
|
| 1698 | - } |
|
| 1681 | + include_spip('iterateur/data'); |
|
| 1682 | + if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) { |
|
| 1683 | + $g = charger_fonction('data', 'iterateur'); |
|
| 1684 | + $boucles[$id] = $g($boucle); |
|
| 1685 | + // from[0] stocke le type de data (rss, yql, ...) |
|
| 1686 | + $boucles[$id]->from[] = $boucle->type_requete; |
|
| 1687 | + } else { |
|
| 1688 | + $x = $boucle->type_requete; |
|
| 1689 | + $boucle->type_requete = false; |
|
| 1690 | + $msg = [ |
|
| 1691 | + 'zbug_requeteur_inconnu', |
|
| 1692 | + [ |
|
| 1693 | + 'requeteur' => 'data', |
|
| 1694 | + 'type' => $x |
|
| 1695 | + ] |
|
| 1696 | + ]; |
|
| 1697 | + erreur_squelette($msg, $boucle); |
|
| 1698 | + } |
|
| 1699 | 1699 | } |
@@ -20,180 +20,180 @@ discard block |
||
| 20 | 20 | **/ |
| 21 | 21 | |
| 22 | 22 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 23 | - return; |
|
| 23 | + return; |
|
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | // En cas de modification, il faut aussi actualiser la regexp de nettoyer_uri_var() dans inc/utils.php |
| 27 | 27 | if (!defined('_CONTEXTE_IGNORE_VARIABLES')) { |
| 28 | - define('_CONTEXTE_IGNORE_VARIABLES', '/(^var_|^PHPSESSID$|^fbclid$|^utm_)/'); |
|
| 28 | + define('_CONTEXTE_IGNORE_VARIABLES', '/(^var_|^PHPSESSID$|^fbclid$|^utm_)/'); |
|
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | function assembler($fond, string $connect = '') { |
| 32 | 32 | |
| 33 | - $chemin_cache = null; |
|
| 34 | - $lastmodified = null; |
|
| 35 | - $res = null; |
|
| 36 | - // flag_preserver est modifie ici, et utilise en globale |
|
| 37 | - // use_cache sert a informer le bouton d'admin pr savoir s'il met un * |
|
| 38 | - // contexte est utilise en globale dans le formulaire d'admin |
|
| 39 | - |
|
| 40 | - $GLOBALS['contexte'] = calculer_contexte(); |
|
| 41 | - $page = ['contexte_implicite' => calculer_contexte_implicite()]; |
|
| 42 | - $page['contexte_implicite']['cache'] = $fond . preg_replace( |
|
| 43 | - ',\.[a-zA-Z0-9]*$,', |
|
| 44 | - '', |
|
| 45 | - preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI']) |
|
| 46 | - ); |
|
| 47 | - // Cette fonction est utilisee deux fois |
|
| 48 | - $cacher = charger_fonction('cacher', 'public', true); |
|
| 49 | - // Les quatre derniers parametres sont modifies par la fonction: |
|
| 50 | - // emplacement, validite, et, s'il est valide, contenu & age |
|
| 51 | - if ($cacher) { |
|
| 52 | - $res = $cacher($GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, $page, $lastmodified); |
|
| 53 | - } else { |
|
| 54 | - $GLOBALS['use_cache'] = -1; |
|
| 55 | - } |
|
| 56 | - // Si un resultat est retourne, c'est un message d'impossibilite |
|
| 57 | - if ($res) { |
|
| 58 | - return ['texte' => $res]; |
|
| 59 | - } |
|
| 60 | - |
|
| 61 | - if (!$chemin_cache || !$lastmodified) { |
|
| 62 | - $lastmodified = time(); |
|
| 63 | - } |
|
| 64 | - |
|
| 65 | - $headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD'); |
|
| 66 | - $calculer_page = true; |
|
| 67 | - |
|
| 68 | - // Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client}) |
|
| 69 | - // une perennite valide a meme reponse qu'une requete HEAD (par defaut les |
|
| 70 | - // pages sont dynamiques) |
|
| 71 | - if ( |
|
| 72 | - isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) |
|
| 73 | - and (!defined('_VAR_MODE') or !_VAR_MODE) |
|
| 74 | - and $chemin_cache |
|
| 75 | - and isset($page['entetes']) |
|
| 76 | - and isset($page['entetes']['Cache-Control']) |
|
| 77 | - and strstr($page['entetes']['Cache-Control'], 'max-age=') |
|
| 78 | - and !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/') |
|
| 79 | - ) { |
|
| 80 | - $since = preg_replace( |
|
| 81 | - '/;.*/', |
|
| 82 | - '', |
|
| 83 | - $_SERVER['HTTP_IF_MODIFIED_SINCE'] |
|
| 84 | - ); |
|
| 85 | - $since = str_replace('GMT', '', $since); |
|
| 86 | - if (trim($since) == gmdate('D, d M Y H:i:s', $lastmodified)) { |
|
| 87 | - $page['status'] = 304; |
|
| 88 | - $headers_only = true; |
|
| 89 | - $calculer_page = false; |
|
| 90 | - } |
|
| 91 | - } |
|
| 92 | - |
|
| 93 | - // Si requete HEAD ou Last-modified compatible, ignorer le texte |
|
| 94 | - // et pas de content-type (pour contrer le bouton admin de inc-public) |
|
| 95 | - if (!$calculer_page) { |
|
| 96 | - $page['texte'] = ''; |
|
| 97 | - } else { |
|
| 98 | - // si la page est prise dans le cache |
|
| 99 | - if (!$GLOBALS['use_cache']) { |
|
| 100 | - // Informer les boutons d'admin du contexte |
|
| 101 | - // (fourni par urls_decoder_url ci-dessous lors de la mise en cache) |
|
| 102 | - $GLOBALS['contexte'] = $page['contexte']; |
|
| 103 | - |
|
| 104 | - // vider les globales url propres qui ne doivent plus etre utilisees en cas |
|
| 105 | - // d'inversion url => objet |
|
| 106 | - // plus necessaire si on utilise bien la fonction urls_decoder_url |
|
| 107 | - #unset($_SERVER['REDIRECT_url_propre']); |
|
| 108 | - #unset($_ENV['url_propre']); |
|
| 109 | - } else { |
|
| 110 | - // Compat ascendante : |
|
| 111 | - // 1. $contexte est global |
|
| 112 | - // (a evacuer car urls_decoder_url gere ce probleme ?) |
|
| 113 | - // et calculer la page |
|
| 114 | - if (!test_espace_prive()) { |
|
| 115 | - include_spip('inc/urls'); |
|
| 116 | - [$fond, $GLOBALS['contexte'], $url_redirect] = urls_decoder_url( |
|
| 117 | - nettoyer_uri(), |
|
| 118 | - $fond, |
|
| 119 | - $GLOBALS['contexte'], |
|
| 120 | - true |
|
| 121 | - ); |
|
| 122 | - } |
|
| 123 | - // squelette par defaut |
|
| 124 | - if (!strlen($fond ?? '')) { |
|
| 125 | - $fond = 'sommaire'; |
|
| 126 | - } |
|
| 127 | - |
|
| 128 | - // produire la page : peut mettre a jour $lastmodified |
|
| 129 | - $produire_page = charger_fonction('produire_page', 'public'); |
|
| 130 | - $page = $produire_page( |
|
| 131 | - $fond, |
|
| 132 | - $GLOBALS['contexte'], |
|
| 133 | - $GLOBALS['use_cache'], |
|
| 134 | - $chemin_cache, |
|
| 135 | - null, |
|
| 136 | - $page, |
|
| 137 | - $lastmodified, |
|
| 138 | - $connect |
|
| 139 | - ); |
|
| 140 | - if ($page === '') { |
|
| 141 | - $erreur = _T( |
|
| 142 | - 'info_erreur_squelette2', |
|
| 143 | - ['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES] |
|
| 144 | - ); |
|
| 145 | - erreur_squelette($erreur); |
|
| 146 | - // eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4 |
|
| 147 | - $page = ['texte' => '', 'erreur' => $erreur]; |
|
| 148 | - } |
|
| 149 | - } |
|
| 150 | - |
|
| 151 | - if ($page and $chemin_cache) { |
|
| 152 | - $page['cache'] = $chemin_cache; |
|
| 153 | - } |
|
| 154 | - |
|
| 155 | - auto_content_type($page); |
|
| 156 | - |
|
| 157 | - $GLOBALS['flag_preserver'] |= headers_sent(); |
|
| 158 | - |
|
| 159 | - // Definir les entetes si ce n'est fait |
|
| 160 | - if (!$GLOBALS['flag_preserver']) { |
|
| 161 | - if ($GLOBALS['flag_ob']) { |
|
| 162 | - // Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions |
|
| 163 | - if ( |
|
| 164 | - trim($page['texte']) === '' |
|
| 165 | - and _VAR_MODE != 'debug' |
|
| 166 | - and !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur |
|
| 167 | - ) { |
|
| 168 | - $GLOBALS['contexte']['fond_erreur'] = $fond; |
|
| 169 | - $page = message_page_indisponible($page, $GLOBALS['contexte']); |
|
| 170 | - } |
|
| 171 | - // pas de cache client en mode 'observation' |
|
| 172 | - if (defined('_VAR_MODE') and _VAR_MODE) { |
|
| 173 | - $page['entetes']['Cache-Control'] = 'no-cache,must-revalidate'; |
|
| 174 | - $page['entetes']['Pragma'] = 'no-cache'; |
|
| 175 | - } |
|
| 176 | - } |
|
| 177 | - } |
|
| 178 | - } |
|
| 179 | - |
|
| 180 | - // Entete Last-Modified: |
|
| 181 | - // eviter d'etre incoherent en envoyant un lastmodified identique |
|
| 182 | - // a celui qu'on a refuse d'honorer plus haut (cf. #655) |
|
| 183 | - if ( |
|
| 184 | - $lastmodified |
|
| 185 | - and !isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) |
|
| 186 | - and !isset($page['entetes']['Last-Modified']) |
|
| 187 | - ) { |
|
| 188 | - $page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT'; |
|
| 189 | - } |
|
| 190 | - |
|
| 191 | - // fermer la connexion apres les headers si requete HEAD |
|
| 192 | - if ($headers_only) { |
|
| 193 | - $page['entetes']['Connection'] = 'close'; |
|
| 194 | - } |
|
| 195 | - |
|
| 196 | - return $page; |
|
| 33 | + $chemin_cache = null; |
|
| 34 | + $lastmodified = null; |
|
| 35 | + $res = null; |
|
| 36 | + // flag_preserver est modifie ici, et utilise en globale |
|
| 37 | + // use_cache sert a informer le bouton d'admin pr savoir s'il met un * |
|
| 38 | + // contexte est utilise en globale dans le formulaire d'admin |
|
| 39 | + |
|
| 40 | + $GLOBALS['contexte'] = calculer_contexte(); |
|
| 41 | + $page = ['contexte_implicite' => calculer_contexte_implicite()]; |
|
| 42 | + $page['contexte_implicite']['cache'] = $fond . preg_replace( |
|
| 43 | + ',\.[a-zA-Z0-9]*$,', |
|
| 44 | + '', |
|
| 45 | + preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI']) |
|
| 46 | + ); |
|
| 47 | + // Cette fonction est utilisee deux fois |
|
| 48 | + $cacher = charger_fonction('cacher', 'public', true); |
|
| 49 | + // Les quatre derniers parametres sont modifies par la fonction: |
|
| 50 | + // emplacement, validite, et, s'il est valide, contenu & age |
|
| 51 | + if ($cacher) { |
|
| 52 | + $res = $cacher($GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, $page, $lastmodified); |
|
| 53 | + } else { |
|
| 54 | + $GLOBALS['use_cache'] = -1; |
|
| 55 | + } |
|
| 56 | + // Si un resultat est retourne, c'est un message d'impossibilite |
|
| 57 | + if ($res) { |
|
| 58 | + return ['texte' => $res]; |
|
| 59 | + } |
|
| 60 | + |
|
| 61 | + if (!$chemin_cache || !$lastmodified) { |
|
| 62 | + $lastmodified = time(); |
|
| 63 | + } |
|
| 64 | + |
|
| 65 | + $headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD'); |
|
| 66 | + $calculer_page = true; |
|
| 67 | + |
|
| 68 | + // Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client}) |
|
| 69 | + // une perennite valide a meme reponse qu'une requete HEAD (par defaut les |
|
| 70 | + // pages sont dynamiques) |
|
| 71 | + if ( |
|
| 72 | + isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) |
|
| 73 | + and (!defined('_VAR_MODE') or !_VAR_MODE) |
|
| 74 | + and $chemin_cache |
|
| 75 | + and isset($page['entetes']) |
|
| 76 | + and isset($page['entetes']['Cache-Control']) |
|
| 77 | + and strstr($page['entetes']['Cache-Control'], 'max-age=') |
|
| 78 | + and !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/') |
|
| 79 | + ) { |
|
| 80 | + $since = preg_replace( |
|
| 81 | + '/;.*/', |
|
| 82 | + '', |
|
| 83 | + $_SERVER['HTTP_IF_MODIFIED_SINCE'] |
|
| 84 | + ); |
|
| 85 | + $since = str_replace('GMT', '', $since); |
|
| 86 | + if (trim($since) == gmdate('D, d M Y H:i:s', $lastmodified)) { |
|
| 87 | + $page['status'] = 304; |
|
| 88 | + $headers_only = true; |
|
| 89 | + $calculer_page = false; |
|
| 90 | + } |
|
| 91 | + } |
|
| 92 | + |
|
| 93 | + // Si requete HEAD ou Last-modified compatible, ignorer le texte |
|
| 94 | + // et pas de content-type (pour contrer le bouton admin de inc-public) |
|
| 95 | + if (!$calculer_page) { |
|
| 96 | + $page['texte'] = ''; |
|
| 97 | + } else { |
|
| 98 | + // si la page est prise dans le cache |
|
| 99 | + if (!$GLOBALS['use_cache']) { |
|
| 100 | + // Informer les boutons d'admin du contexte |
|
| 101 | + // (fourni par urls_decoder_url ci-dessous lors de la mise en cache) |
|
| 102 | + $GLOBALS['contexte'] = $page['contexte']; |
|
| 103 | + |
|
| 104 | + // vider les globales url propres qui ne doivent plus etre utilisees en cas |
|
| 105 | + // d'inversion url => objet |
|
| 106 | + // plus necessaire si on utilise bien la fonction urls_decoder_url |
|
| 107 | + #unset($_SERVER['REDIRECT_url_propre']); |
|
| 108 | + #unset($_ENV['url_propre']); |
|
| 109 | + } else { |
|
| 110 | + // Compat ascendante : |
|
| 111 | + // 1. $contexte est global |
|
| 112 | + // (a evacuer car urls_decoder_url gere ce probleme ?) |
|
| 113 | + // et calculer la page |
|
| 114 | + if (!test_espace_prive()) { |
|
| 115 | + include_spip('inc/urls'); |
|
| 116 | + [$fond, $GLOBALS['contexte'], $url_redirect] = urls_decoder_url( |
|
| 117 | + nettoyer_uri(), |
|
| 118 | + $fond, |
|
| 119 | + $GLOBALS['contexte'], |
|
| 120 | + true |
|
| 121 | + ); |
|
| 122 | + } |
|
| 123 | + // squelette par defaut |
|
| 124 | + if (!strlen($fond ?? '')) { |
|
| 125 | + $fond = 'sommaire'; |
|
| 126 | + } |
|
| 127 | + |
|
| 128 | + // produire la page : peut mettre a jour $lastmodified |
|
| 129 | + $produire_page = charger_fonction('produire_page', 'public'); |
|
| 130 | + $page = $produire_page( |
|
| 131 | + $fond, |
|
| 132 | + $GLOBALS['contexte'], |
|
| 133 | + $GLOBALS['use_cache'], |
|
| 134 | + $chemin_cache, |
|
| 135 | + null, |
|
| 136 | + $page, |
|
| 137 | + $lastmodified, |
|
| 138 | + $connect |
|
| 139 | + ); |
|
| 140 | + if ($page === '') { |
|
| 141 | + $erreur = _T( |
|
| 142 | + 'info_erreur_squelette2', |
|
| 143 | + ['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES] |
|
| 144 | + ); |
|
| 145 | + erreur_squelette($erreur); |
|
| 146 | + // eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4 |
|
| 147 | + $page = ['texte' => '', 'erreur' => $erreur]; |
|
| 148 | + } |
|
| 149 | + } |
|
| 150 | + |
|
| 151 | + if ($page and $chemin_cache) { |
|
| 152 | + $page['cache'] = $chemin_cache; |
|
| 153 | + } |
|
| 154 | + |
|
| 155 | + auto_content_type($page); |
|
| 156 | + |
|
| 157 | + $GLOBALS['flag_preserver'] |= headers_sent(); |
|
| 158 | + |
|
| 159 | + // Definir les entetes si ce n'est fait |
|
| 160 | + if (!$GLOBALS['flag_preserver']) { |
|
| 161 | + if ($GLOBALS['flag_ob']) { |
|
| 162 | + // Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions |
|
| 163 | + if ( |
|
| 164 | + trim($page['texte']) === '' |
|
| 165 | + and _VAR_MODE != 'debug' |
|
| 166 | + and !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur |
|
| 167 | + ) { |
|
| 168 | + $GLOBALS['contexte']['fond_erreur'] = $fond; |
|
| 169 | + $page = message_page_indisponible($page, $GLOBALS['contexte']); |
|
| 170 | + } |
|
| 171 | + // pas de cache client en mode 'observation' |
|
| 172 | + if (defined('_VAR_MODE') and _VAR_MODE) { |
|
| 173 | + $page['entetes']['Cache-Control'] = 'no-cache,must-revalidate'; |
|
| 174 | + $page['entetes']['Pragma'] = 'no-cache'; |
|
| 175 | + } |
|
| 176 | + } |
|
| 177 | + } |
|
| 178 | + } |
|
| 179 | + |
|
| 180 | + // Entete Last-Modified: |
|
| 181 | + // eviter d'etre incoherent en envoyant un lastmodified identique |
|
| 182 | + // a celui qu'on a refuse d'honorer plus haut (cf. #655) |
|
| 183 | + if ( |
|
| 184 | + $lastmodified |
|
| 185 | + and !isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) |
|
| 186 | + and !isset($page['entetes']['Last-Modified']) |
|
| 187 | + ) { |
|
| 188 | + $page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT'; |
|
| 189 | + } |
|
| 190 | + |
|
| 191 | + // fermer la connexion apres les headers si requete HEAD |
|
| 192 | + if ($headers_only) { |
|
| 193 | + $page['entetes']['Connection'] = 'close'; |
|
| 194 | + } |
|
| 195 | + |
|
| 196 | + return $page; |
|
| 197 | 197 | } |
| 198 | 198 | |
| 199 | 199 | /** |
@@ -210,19 +210,19 @@ discard block |
||
| 210 | 210 | */ |
| 211 | 211 | function calculer_contexte() { |
| 212 | 212 | |
| 213 | - $contexte = []; |
|
| 214 | - foreach ($_GET as $var => $val) { |
|
| 215 | - if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) { |
|
| 216 | - $contexte[$var] = $val; |
|
| 217 | - } |
|
| 218 | - } |
|
| 219 | - foreach ($_POST as $var => $val) { |
|
| 220 | - if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) { |
|
| 221 | - $contexte[$var] = $val; |
|
| 222 | - } |
|
| 223 | - } |
|
| 224 | - |
|
| 225 | - return $contexte; |
|
| 213 | + $contexte = []; |
|
| 214 | + foreach ($_GET as $var => $val) { |
|
| 215 | + if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) { |
|
| 216 | + $contexte[$var] = $val; |
|
| 217 | + } |
|
| 218 | + } |
|
| 219 | + foreach ($_POST as $var => $val) { |
|
| 220 | + if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) { |
|
| 221 | + $contexte[$var] = $val; |
|
| 222 | + } |
|
| 223 | + } |
|
| 224 | + |
|
| 225 | + return $contexte; |
|
| 226 | 226 | } |
| 227 | 227 | |
| 228 | 228 | /** |
@@ -233,25 +233,25 @@ discard block |
||
| 233 | 233 | * @return array |
| 234 | 234 | */ |
| 235 | 235 | function calculer_contexte_implicite() { |
| 236 | - static $notes = null; |
|
| 237 | - if (is_null($notes)) { |
|
| 238 | - $notes = charger_fonction('notes', 'inc', true); |
|
| 239 | - } |
|
| 240 | - $contexte_implicite = [ |
|
| 241 | - 'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ? |
|
| 242 | - 'host' => ($_SERVER['HTTP_HOST'] ?? null), |
|
| 243 | - 'https' => ($_SERVER['HTTPS'] ?? ''), |
|
| 244 | - 'espace' => test_espace_prive(), |
|
| 245 | - 'marqueur' => ($GLOBALS['marqueur'] ?? ''), |
|
| 246 | - 'marqueur_skel' => ($GLOBALS['marqueur_skel'] ?? ''), |
|
| 247 | - 'notes' => $notes ? $notes('', 'contexter_cache') : '', |
|
| 248 | - 'spip_version_code' => $GLOBALS['spip_version_code'], |
|
| 249 | - ]; |
|
| 250 | - if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { |
|
| 251 | - $contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST']; |
|
| 252 | - } |
|
| 253 | - |
|
| 254 | - return $contexte_implicite; |
|
| 236 | + static $notes = null; |
|
| 237 | + if (is_null($notes)) { |
|
| 238 | + $notes = charger_fonction('notes', 'inc', true); |
|
| 239 | + } |
|
| 240 | + $contexte_implicite = [ |
|
| 241 | + 'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ? |
|
| 242 | + 'host' => ($_SERVER['HTTP_HOST'] ?? null), |
|
| 243 | + 'https' => ($_SERVER['HTTPS'] ?? ''), |
|
| 244 | + 'espace' => test_espace_prive(), |
|
| 245 | + 'marqueur' => ($GLOBALS['marqueur'] ?? ''), |
|
| 246 | + 'marqueur_skel' => ($GLOBALS['marqueur_skel'] ?? ''), |
|
| 247 | + 'notes' => $notes ? $notes('', 'contexter_cache') : '', |
|
| 248 | + 'spip_version_code' => $GLOBALS['spip_version_code'], |
|
| 249 | + ]; |
|
| 250 | + if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { |
|
| 251 | + $contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST']; |
|
| 252 | + } |
|
| 253 | + |
|
| 254 | + return $contexte_implicite; |
|
| 255 | 255 | } |
| 256 | 256 | |
| 257 | 257 | // |
@@ -260,55 +260,55 @@ discard block |
||
| 260 | 260 | |
| 261 | 261 | function auto_content_type($page) { |
| 262 | 262 | |
| 263 | - if (!isset($GLOBALS['flag_preserver'])) { |
|
| 264 | - $GLOBALS['flag_preserver'] = ($page && preg_match( |
|
| 265 | - '/header\s*\(\s*.content\-type:/isx', |
|
| 266 | - $page['texte'] |
|
| 267 | - ) || (isset($page['entetes']['Content-Type']))); |
|
| 268 | - } |
|
| 263 | + if (!isset($GLOBALS['flag_preserver'])) { |
|
| 264 | + $GLOBALS['flag_preserver'] = ($page && preg_match( |
|
| 265 | + '/header\s*\(\s*.content\-type:/isx', |
|
| 266 | + $page['texte'] |
|
| 267 | + ) || (isset($page['entetes']['Content-Type']))); |
|
| 268 | + } |
|
| 269 | 269 | } |
| 270 | 270 | |
| 271 | 271 | function inclure_page($fond, $contexte, string $connect = '') { |
| 272 | - $use_cache = null; |
|
| 273 | - $chemin_cache = null; |
|
| 274 | - $lastinclude = null; |
|
| 275 | - $res = null; |
|
| 276 | - static $cacher, $produire_page; |
|
| 277 | - |
|
| 278 | - // enlever le fond de contexte inclus car sinon il prend la main |
|
| 279 | - // dans les sous inclusions -> boucle infinie d'inclusion identique |
|
| 280 | - // (cette precaution n'est probablement plus utile) |
|
| 281 | - unset($contexte['fond']); |
|
| 282 | - $page = ['contexte_implicite' => calculer_contexte_implicite()]; |
|
| 283 | - $page['contexte_implicite']['cache'] = $fond; |
|
| 284 | - if (is_null($cacher)) { |
|
| 285 | - $cacher = charger_fonction('cacher', 'public', true); |
|
| 286 | - } |
|
| 287 | - // Les quatre derniers parametres sont modifies par la fonction: |
|
| 288 | - // emplacement, validite, et, s'il est valide, contenu & age |
|
| 289 | - if ($cacher) { |
|
| 290 | - $res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude); |
|
| 291 | - } else { |
|
| 292 | - $use_cache = -1; |
|
| 293 | - } |
|
| 294 | - // $res = message d'erreur : on sort de la |
|
| 295 | - if ($res) { |
|
| 296 | - return ['texte' => $res]; |
|
| 297 | - } |
|
| 298 | - |
|
| 299 | - // Si use_cache ne vaut pas 0, la page doit etre calculee |
|
| 300 | - // produire la page : peut mettre a jour $lastinclude |
|
| 301 | - // le contexte_cache envoye a cacher() a ete conserve et est passe a produire |
|
| 302 | - if ($use_cache) { |
|
| 303 | - if (is_null($produire_page)) { |
|
| 304 | - $produire_page = charger_fonction('produire_page', 'public'); |
|
| 305 | - } |
|
| 306 | - $page = $produire_page($fond, $contexte, $use_cache, $chemin_cache, $contexte, $page, $lastinclude, $connect); |
|
| 307 | - } |
|
| 308 | - // dans tous les cas, mettre a jour $GLOBALS['lastmodified'] |
|
| 309 | - $GLOBALS['lastmodified'] = max(($GLOBALS['lastmodified'] ?? 0), $lastinclude); |
|
| 310 | - |
|
| 311 | - return $page; |
|
| 272 | + $use_cache = null; |
|
| 273 | + $chemin_cache = null; |
|
| 274 | + $lastinclude = null; |
|
| 275 | + $res = null; |
|
| 276 | + static $cacher, $produire_page; |
|
| 277 | + |
|
| 278 | + // enlever le fond de contexte inclus car sinon il prend la main |
|
| 279 | + // dans les sous inclusions -> boucle infinie d'inclusion identique |
|
| 280 | + // (cette precaution n'est probablement plus utile) |
|
| 281 | + unset($contexte['fond']); |
|
| 282 | + $page = ['contexte_implicite' => calculer_contexte_implicite()]; |
|
| 283 | + $page['contexte_implicite']['cache'] = $fond; |
|
| 284 | + if (is_null($cacher)) { |
|
| 285 | + $cacher = charger_fonction('cacher', 'public', true); |
|
| 286 | + } |
|
| 287 | + // Les quatre derniers parametres sont modifies par la fonction: |
|
| 288 | + // emplacement, validite, et, s'il est valide, contenu & age |
|
| 289 | + if ($cacher) { |
|
| 290 | + $res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude); |
|
| 291 | + } else { |
|
| 292 | + $use_cache = -1; |
|
| 293 | + } |
|
| 294 | + // $res = message d'erreur : on sort de la |
|
| 295 | + if ($res) { |
|
| 296 | + return ['texte' => $res]; |
|
| 297 | + } |
|
| 298 | + |
|
| 299 | + // Si use_cache ne vaut pas 0, la page doit etre calculee |
|
| 300 | + // produire la page : peut mettre a jour $lastinclude |
|
| 301 | + // le contexte_cache envoye a cacher() a ete conserve et est passe a produire |
|
| 302 | + if ($use_cache) { |
|
| 303 | + if (is_null($produire_page)) { |
|
| 304 | + $produire_page = charger_fonction('produire_page', 'public'); |
|
| 305 | + } |
|
| 306 | + $page = $produire_page($fond, $contexte, $use_cache, $chemin_cache, $contexte, $page, $lastinclude, $connect); |
|
| 307 | + } |
|
| 308 | + // dans tous les cas, mettre a jour $GLOBALS['lastmodified'] |
|
| 309 | + $GLOBALS['lastmodified'] = max(($GLOBALS['lastmodified'] ?? 0), $lastinclude); |
|
| 310 | + |
|
| 311 | + return $page; |
|
| 312 | 312 | } |
| 313 | 313 | |
| 314 | 314 | /** |
@@ -326,41 +326,41 @@ discard block |
||
| 326 | 326 | * @return array |
| 327 | 327 | */ |
| 328 | 328 | function public_produire_page_dist( |
| 329 | - $fond, |
|
| 330 | - $contexte, |
|
| 331 | - $use_cache, |
|
| 332 | - $chemin_cache, |
|
| 333 | - $contexte_cache, |
|
| 334 | - &$page, |
|
| 335 | - &$lastinclude, |
|
| 336 | - $connect = '' |
|
| 329 | + $fond, |
|
| 330 | + $contexte, |
|
| 331 | + $use_cache, |
|
| 332 | + $chemin_cache, |
|
| 333 | + $contexte_cache, |
|
| 334 | + &$page, |
|
| 335 | + &$lastinclude, |
|
| 336 | + $connect = '' |
|
| 337 | 337 | ) { |
| 338 | - static $parametrer, $cacher; |
|
| 339 | - if (!$parametrer) { |
|
| 340 | - $parametrer = charger_fonction('parametrer', 'public'); |
|
| 341 | - } |
|
| 342 | - $page = $parametrer($fond, $contexte, $chemin_cache, $connect); |
|
| 343 | - // et on l'enregistre sur le disque |
|
| 344 | - if ( |
|
| 345 | - $chemin_cache |
|
| 346 | - and $use_cache > -1 |
|
| 347 | - and is_array($page) |
|
| 348 | - and count($page) |
|
| 349 | - and isset($page['entetes']['X-Spip-Cache']) |
|
| 350 | - and $page['entetes']['X-Spip-Cache'] > 0 |
|
| 351 | - ) { |
|
| 352 | - if (is_null($cacher)) { |
|
| 353 | - $cacher = charger_fonction('cacher', 'public', true); |
|
| 354 | - } |
|
| 355 | - $lastinclude = time(); |
|
| 356 | - if ($cacher) { |
|
| 357 | - $cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude); |
|
| 358 | - } else { |
|
| 359 | - $use_cache = -1; |
|
| 360 | - } |
|
| 361 | - } |
|
| 362 | - |
|
| 363 | - return $page; |
|
| 338 | + static $parametrer, $cacher; |
|
| 339 | + if (!$parametrer) { |
|
| 340 | + $parametrer = charger_fonction('parametrer', 'public'); |
|
| 341 | + } |
|
| 342 | + $page = $parametrer($fond, $contexte, $chemin_cache, $connect); |
|
| 343 | + // et on l'enregistre sur le disque |
|
| 344 | + if ( |
|
| 345 | + $chemin_cache |
|
| 346 | + and $use_cache > -1 |
|
| 347 | + and is_array($page) |
|
| 348 | + and count($page) |
|
| 349 | + and isset($page['entetes']['X-Spip-Cache']) |
|
| 350 | + and $page['entetes']['X-Spip-Cache'] > 0 |
|
| 351 | + ) { |
|
| 352 | + if (is_null($cacher)) { |
|
| 353 | + $cacher = charger_fonction('cacher', 'public', true); |
|
| 354 | + } |
|
| 355 | + $lastinclude = time(); |
|
| 356 | + if ($cacher) { |
|
| 357 | + $cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude); |
|
| 358 | + } else { |
|
| 359 | + $use_cache = -1; |
|
| 360 | + } |
|
| 361 | + } |
|
| 362 | + |
|
| 363 | + return $page; |
|
| 364 | 364 | } |
| 365 | 365 | |
| 366 | 366 | // Fonction inseree par le compilateur dans le code compile. |
@@ -374,14 +374,14 @@ discard block |
||
| 374 | 374 | // 4: langue |
| 375 | 375 | |
| 376 | 376 | function inserer_balise_dynamique($contexte_exec, $contexte_compil) { |
| 377 | - arguments_balise_dyn_depuis_modele(null, 'reset'); |
|
| 378 | - |
|
| 379 | - if (!is_array($contexte_exec)) { |
|
| 380 | - echo $contexte_exec; |
|
| 381 | - } // message d'erreur etc |
|
| 382 | - else { |
|
| 383 | - inclure_balise_dynamique($contexte_exec, true, $contexte_compil); |
|
| 384 | - } |
|
| 377 | + arguments_balise_dyn_depuis_modele(null, 'reset'); |
|
| 378 | + |
|
| 379 | + if (!is_array($contexte_exec)) { |
|
| 380 | + echo $contexte_exec; |
|
| 381 | + } // message d'erreur etc |
|
| 382 | + else { |
|
| 383 | + inclure_balise_dynamique($contexte_exec, true, $contexte_compil); |
|
| 384 | + } |
|
| 385 | 385 | } |
| 386 | 386 | |
| 387 | 387 | /** |
@@ -394,101 +394,101 @@ discard block |
||
| 394 | 394 | * @return string |
| 395 | 395 | */ |
| 396 | 396 | function inclure_balise_dynamique($texte, $echo = true, $contexte_compil = []) { |
| 397 | - if (is_array($texte)) { |
|
| 398 | - [$fond, $delainc, $contexte_inclus] = $texte; |
|
| 399 | - |
|
| 400 | - // delais a l'ancienne, c'est pratiquement mort |
|
| 401 | - $d = $GLOBALS['delais'] ?? null; |
|
| 402 | - $GLOBALS['delais'] = $delainc; |
|
| 403 | - |
|
| 404 | - $page = recuperer_fond( |
|
| 405 | - $fond, |
|
| 406 | - $contexte_inclus, |
|
| 407 | - ['trim' => false, 'raw' => true, 'compil' => $contexte_compil] |
|
| 408 | - ); |
|
| 409 | - |
|
| 410 | - $texte = $page['texte']; |
|
| 411 | - |
|
| 412 | - $GLOBALS['delais'] = $d; |
|
| 413 | - // Faire remonter les entetes |
|
| 414 | - if ( |
|
| 415 | - isset($page['entetes']) |
|
| 416 | - and is_array($page['entetes']) |
|
| 417 | - ) { |
|
| 418 | - // mais pas toutes |
|
| 419 | - unset($page['entetes']['X-Spip-Cache']); |
|
| 420 | - unset($page['entetes']['Content-Type']); |
|
| 421 | - if (isset($GLOBALS['page']) and is_array($GLOBALS['page'])) { |
|
| 422 | - if (!is_array($GLOBALS['page']['entetes'])) { |
|
| 423 | - $GLOBALS['page']['entetes'] = []; |
|
| 424 | - } |
|
| 425 | - $GLOBALS['page']['entetes'] = |
|
| 426 | - array_merge($GLOBALS['page']['entetes'], $page['entetes']); |
|
| 427 | - } |
|
| 428 | - } |
|
| 429 | - // _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines |
|
| 430 | - if ( |
|
| 431 | - isset($page['contexte']['_pipelines']) |
|
| 432 | - and is_array($page['contexte']['_pipelines']) |
|
| 433 | - and count($page['contexte']['_pipelines']) |
|
| 434 | - ) { |
|
| 435 | - foreach ($page['contexte']['_pipelines'] as $pipe => $args) { |
|
| 436 | - $args['contexte'] = $page['contexte']; |
|
| 437 | - unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul |
|
| 438 | - $texte = pipeline( |
|
| 439 | - $pipe, |
|
| 440 | - [ |
|
| 441 | - 'data' => $texte, |
|
| 442 | - 'args' => $args |
|
| 443 | - ] |
|
| 444 | - ); |
|
| 445 | - } |
|
| 446 | - } |
|
| 447 | - } |
|
| 448 | - |
|
| 449 | - if (defined('_VAR_MODE') and _VAR_MODE == 'debug') { |
|
| 450 | - // compatibilite : avant on donnait le numero de ligne ou rien. |
|
| 451 | - $ligne = intval($contexte_compil[3] ?? $contexte_compil); |
|
| 452 | - $GLOBALS['debug_objets']['resultat'][$ligne] = $texte; |
|
| 453 | - } |
|
| 454 | - if ($echo) { |
|
| 455 | - echo $texte; |
|
| 456 | - } else { |
|
| 457 | - return $texte; |
|
| 458 | - } |
|
| 397 | + if (is_array($texte)) { |
|
| 398 | + [$fond, $delainc, $contexte_inclus] = $texte; |
|
| 399 | + |
|
| 400 | + // delais a l'ancienne, c'est pratiquement mort |
|
| 401 | + $d = $GLOBALS['delais'] ?? null; |
|
| 402 | + $GLOBALS['delais'] = $delainc; |
|
| 403 | + |
|
| 404 | + $page = recuperer_fond( |
|
| 405 | + $fond, |
|
| 406 | + $contexte_inclus, |
|
| 407 | + ['trim' => false, 'raw' => true, 'compil' => $contexte_compil] |
|
| 408 | + ); |
|
| 409 | + |
|
| 410 | + $texte = $page['texte']; |
|
| 411 | + |
|
| 412 | + $GLOBALS['delais'] = $d; |
|
| 413 | + // Faire remonter les entetes |
|
| 414 | + if ( |
|
| 415 | + isset($page['entetes']) |
|
| 416 | + and is_array($page['entetes']) |
|
| 417 | + ) { |
|
| 418 | + // mais pas toutes |
|
| 419 | + unset($page['entetes']['X-Spip-Cache']); |
|
| 420 | + unset($page['entetes']['Content-Type']); |
|
| 421 | + if (isset($GLOBALS['page']) and is_array($GLOBALS['page'])) { |
|
| 422 | + if (!is_array($GLOBALS['page']['entetes'])) { |
|
| 423 | + $GLOBALS['page']['entetes'] = []; |
|
| 424 | + } |
|
| 425 | + $GLOBALS['page']['entetes'] = |
|
| 426 | + array_merge($GLOBALS['page']['entetes'], $page['entetes']); |
|
| 427 | + } |
|
| 428 | + } |
|
| 429 | + // _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines |
|
| 430 | + if ( |
|
| 431 | + isset($page['contexte']['_pipelines']) |
|
| 432 | + and is_array($page['contexte']['_pipelines']) |
|
| 433 | + and count($page['contexte']['_pipelines']) |
|
| 434 | + ) { |
|
| 435 | + foreach ($page['contexte']['_pipelines'] as $pipe => $args) { |
|
| 436 | + $args['contexte'] = $page['contexte']; |
|
| 437 | + unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul |
|
| 438 | + $texte = pipeline( |
|
| 439 | + $pipe, |
|
| 440 | + [ |
|
| 441 | + 'data' => $texte, |
|
| 442 | + 'args' => $args |
|
| 443 | + ] |
|
| 444 | + ); |
|
| 445 | + } |
|
| 446 | + } |
|
| 447 | + } |
|
| 448 | + |
|
| 449 | + if (defined('_VAR_MODE') and _VAR_MODE == 'debug') { |
|
| 450 | + // compatibilite : avant on donnait le numero de ligne ou rien. |
|
| 451 | + $ligne = intval($contexte_compil[3] ?? $contexte_compil); |
|
| 452 | + $GLOBALS['debug_objets']['resultat'][$ligne] = $texte; |
|
| 453 | + } |
|
| 454 | + if ($echo) { |
|
| 455 | + echo $texte; |
|
| 456 | + } else { |
|
| 457 | + return $texte; |
|
| 458 | + } |
|
| 459 | 459 | } |
| 460 | 460 | |
| 461 | 461 | function message_page_indisponible($page, $contexte) { |
| 462 | - static $deja = false; |
|
| 463 | - if ($deja) { |
|
| 464 | - return 'erreur'; |
|
| 465 | - } |
|
| 466 | - $codes = [ |
|
| 467 | - '404' => '404 Not Found', |
|
| 468 | - '503' => '503 Service Unavailable', |
|
| 469 | - ]; |
|
| 470 | - |
|
| 471 | - $contexte['status'] = ($page !== false) ? '404' : '503'; |
|
| 472 | - $contexte['code'] = $codes[$contexte['status']]; |
|
| 473 | - $contexte['fond'] = '404'; // gere les 2 erreurs |
|
| 474 | - if (!isset($contexte['lang'])) { |
|
| 475 | - include_spip('inc/lang'); |
|
| 476 | - $contexte['lang'] = $GLOBALS['spip_lang']; |
|
| 477 | - } |
|
| 478 | - |
|
| 479 | - $deja = true; |
|
| 480 | - // passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent |
|
| 481 | - // ex restriction d'acces => 401 |
|
| 482 | - $contexte = pipeline('page_indisponible', $contexte); |
|
| 483 | - |
|
| 484 | - // produire la page d'erreur |
|
| 485 | - $page = inclure_page($contexte['fond'], $contexte); |
|
| 486 | - if (!$page) { |
|
| 487 | - $page = inclure_page('404', $contexte); |
|
| 488 | - } |
|
| 489 | - $page['status'] = $contexte['status']; |
|
| 490 | - |
|
| 491 | - return $page; |
|
| 462 | + static $deja = false; |
|
| 463 | + if ($deja) { |
|
| 464 | + return 'erreur'; |
|
| 465 | + } |
|
| 466 | + $codes = [ |
|
| 467 | + '404' => '404 Not Found', |
|
| 468 | + '503' => '503 Service Unavailable', |
|
| 469 | + ]; |
|
| 470 | + |
|
| 471 | + $contexte['status'] = ($page !== false) ? '404' : '503'; |
|
| 472 | + $contexte['code'] = $codes[$contexte['status']]; |
|
| 473 | + $contexte['fond'] = '404'; // gere les 2 erreurs |
|
| 474 | + if (!isset($contexte['lang'])) { |
|
| 475 | + include_spip('inc/lang'); |
|
| 476 | + $contexte['lang'] = $GLOBALS['spip_lang']; |
|
| 477 | + } |
|
| 478 | + |
|
| 479 | + $deja = true; |
|
| 480 | + // passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent |
|
| 481 | + // ex restriction d'acces => 401 |
|
| 482 | + $contexte = pipeline('page_indisponible', $contexte); |
|
| 483 | + |
|
| 484 | + // produire la page d'erreur |
|
| 485 | + $page = inclure_page($contexte['fond'], $contexte); |
|
| 486 | + if (!$page) { |
|
| 487 | + $page = inclure_page('404', $contexte); |
|
| 488 | + } |
|
| 489 | + $page['status'] = $contexte['status']; |
|
| 490 | + |
|
| 491 | + return $page; |
|
| 492 | 492 | } |
| 493 | 493 | |
| 494 | 494 | /** |
@@ -500,44 +500,44 @@ discard block |
||
| 500 | 500 | * @return mixed |
| 501 | 501 | */ |
| 502 | 502 | function arguments_balise_dyn_depuis_modele($arg, $operation = 'set') { |
| 503 | - static $balise_dyn_appellee_par_modele = null; |
|
| 504 | - switch ($operation) { |
|
| 505 | - case 'read': |
|
| 506 | - return $balise_dyn_appellee_par_modele; |
|
| 507 | - case 'reset': |
|
| 508 | - $balise_dyn_appellee_par_modele = null; |
|
| 509 | - return null; |
|
| 510 | - case 'set': |
|
| 511 | - default: |
|
| 512 | - $balise_dyn_appellee_par_modele = $arg; |
|
| 513 | - return $arg; |
|
| 514 | - } |
|
| 503 | + static $balise_dyn_appellee_par_modele = null; |
|
| 504 | + switch ($operation) { |
|
| 505 | + case 'read': |
|
| 506 | + return $balise_dyn_appellee_par_modele; |
|
| 507 | + case 'reset': |
|
| 508 | + $balise_dyn_appellee_par_modele = null; |
|
| 509 | + return null; |
|
| 510 | + case 'set': |
|
| 511 | + default: |
|
| 512 | + $balise_dyn_appellee_par_modele = $arg; |
|
| 513 | + return $arg; |
|
| 514 | + } |
|
| 515 | 515 | } |
| 516 | 516 | |
| 517 | 517 | // temporairement ici : a mettre dans le futur inc/modeles |
| 518 | 518 | // creer_contexte_de_modele('left', 'autostart=true', ...) renvoie un array() |
| 519 | 519 | function creer_contexte_de_modele($args) { |
| 520 | - $contexte = []; |
|
| 521 | - foreach ($args as $var => $val) { |
|
| 522 | - if (is_int($var)) { // argument pas formate |
|
| 523 | - if (in_array($val, ['left', 'right', 'center'])) { |
|
| 524 | - $var = 'align'; |
|
| 525 | - $contexte[$var] = $val; |
|
| 526 | - } else { |
|
| 527 | - $args = explode('=', $val); |
|
| 528 | - if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args |
|
| 529 | - $contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1); |
|
| 530 | - } else // notation abregee |
|
| 531 | - { |
|
| 532 | - $contexte[trim($val)] = trim($val); |
|
| 533 | - } |
|
| 534 | - } |
|
| 535 | - } else { |
|
| 536 | - $contexte[$var] = $val; |
|
| 537 | - } |
|
| 538 | - } |
|
| 539 | - |
|
| 540 | - return $contexte; |
|
| 520 | + $contexte = []; |
|
| 521 | + foreach ($args as $var => $val) { |
|
| 522 | + if (is_int($var)) { // argument pas formate |
|
| 523 | + if (in_array($val, ['left', 'right', 'center'])) { |
|
| 524 | + $var = 'align'; |
|
| 525 | + $contexte[$var] = $val; |
|
| 526 | + } else { |
|
| 527 | + $args = explode('=', $val); |
|
| 528 | + if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args |
|
| 529 | + $contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1); |
|
| 530 | + } else // notation abregee |
|
| 531 | + { |
|
| 532 | + $contexte[trim($val)] = trim($val); |
|
| 533 | + } |
|
| 534 | + } |
|
| 535 | + } else { |
|
| 536 | + $contexte[$var] = $val; |
|
| 537 | + } |
|
| 538 | + } |
|
| 539 | + |
|
| 540 | + return $contexte; |
|
| 541 | 541 | } |
| 542 | 542 | |
| 543 | 543 | /** |
@@ -552,43 +552,43 @@ discard block |
||
| 552 | 552 | * @return string |
| 553 | 553 | */ |
| 554 | 554 | function styliser_modele($modele, $id, $contexte = null) { |
| 555 | - static $styliseurs = null; |
|
| 556 | - if (is_null($styliseurs)) { |
|
| 557 | - $tables_objet = lister_tables_objets_sql(); |
|
| 558 | - foreach ($tables_objet as $table => $desc) { |
|
| 559 | - if ( |
|
| 560 | - isset($desc['modeles']) and $desc['modeles'] |
|
| 561 | - and isset($desc['modeles_styliser']) and $desc['modeles_styliser'] |
|
| 562 | - and function_exists($desc['modeles_styliser']) |
|
| 563 | - ) { |
|
| 564 | - $primary = id_table_objet($table); |
|
| 565 | - foreach ($desc['modeles'] as $m) { |
|
| 566 | - $styliseurs[$m] = ['primary' => $primary, 'callback' => $desc['modeles_styliser']]; |
|
| 567 | - } |
|
| 568 | - } |
|
| 569 | - } |
|
| 570 | - } |
|
| 571 | - |
|
| 572 | - if (isset($styliseurs[$modele])) { |
|
| 573 | - $styliseur = $styliseurs[$modele]['callback']; |
|
| 574 | - $primary = $styliseurs[$modele]['primary']; |
|
| 575 | - if (is_null($id) and $contexte) { |
|
| 576 | - if (isset($contexte['id'])) { |
|
| 577 | - $id = $contexte['id']; |
|
| 578 | - } elseif (isset($contexte[$primary])) { |
|
| 579 | - $id = $contexte[$primary]; |
|
| 580 | - } |
|
| 581 | - } |
|
| 582 | - if (is_null($id)) { |
|
| 583 | - $msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]); |
|
| 584 | - erreur_squelette($msg); |
|
| 585 | - // on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant |
|
| 586 | - $id = 0; |
|
| 587 | - } |
|
| 588 | - $modele = $styliseur($modele, $id); |
|
| 589 | - } |
|
| 590 | - |
|
| 591 | - return $modele; |
|
| 555 | + static $styliseurs = null; |
|
| 556 | + if (is_null($styliseurs)) { |
|
| 557 | + $tables_objet = lister_tables_objets_sql(); |
|
| 558 | + foreach ($tables_objet as $table => $desc) { |
|
| 559 | + if ( |
|
| 560 | + isset($desc['modeles']) and $desc['modeles'] |
|
| 561 | + and isset($desc['modeles_styliser']) and $desc['modeles_styliser'] |
|
| 562 | + and function_exists($desc['modeles_styliser']) |
|
| 563 | + ) { |
|
| 564 | + $primary = id_table_objet($table); |
|
| 565 | + foreach ($desc['modeles'] as $m) { |
|
| 566 | + $styliseurs[$m] = ['primary' => $primary, 'callback' => $desc['modeles_styliser']]; |
|
| 567 | + } |
|
| 568 | + } |
|
| 569 | + } |
|
| 570 | + } |
|
| 571 | + |
|
| 572 | + if (isset($styliseurs[$modele])) { |
|
| 573 | + $styliseur = $styliseurs[$modele]['callback']; |
|
| 574 | + $primary = $styliseurs[$modele]['primary']; |
|
| 575 | + if (is_null($id) and $contexte) { |
|
| 576 | + if (isset($contexte['id'])) { |
|
| 577 | + $id = $contexte['id']; |
|
| 578 | + } elseif (isset($contexte[$primary])) { |
|
| 579 | + $id = $contexte[$primary]; |
|
| 580 | + } |
|
| 581 | + } |
|
| 582 | + if (is_null($id)) { |
|
| 583 | + $msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]); |
|
| 584 | + erreur_squelette($msg); |
|
| 585 | + // on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant |
|
| 586 | + $id = 0; |
|
| 587 | + } |
|
| 588 | + $modele = $styliseur($modele, $id); |
|
| 589 | + } |
|
| 590 | + |
|
| 591 | + return $modele; |
|
| 592 | 592 | } |
| 593 | 593 | |
| 594 | 594 | /** |
@@ -605,102 +605,102 @@ discard block |
||
| 605 | 605 | */ |
| 606 | 606 | function inclure_modele($type, $id, $params, $lien, string $connect = '', $env = []) { |
| 607 | 607 | |
| 608 | - static $compteur; |
|
| 609 | - if (++$compteur > 10) { |
|
| 610 | - return ''; |
|
| 611 | - } # ne pas boucler indefiniment |
|
| 612 | - |
|
| 613 | - $type = strtolower($type); |
|
| 614 | - $type = styliser_modele($type, $id); |
|
| 615 | - |
|
| 616 | - $fond = $class = ''; |
|
| 617 | - |
|
| 618 | - $params = array_filter(explode('|', $params)); |
|
| 619 | - if ($params) { |
|
| 620 | - $soustype = current($params); |
|
| 621 | - $soustype = strtolower(trim($soustype)); |
|
| 622 | - if (in_array($soustype, ['left', 'right', 'center', 'ajax'])) { |
|
| 623 | - $soustype = next($params); |
|
| 624 | - $soustype = strtolower($soustype); |
|
| 625 | - } |
|
| 626 | - |
|
| 627 | - if (preg_match(',^[a-z0-9_]+$,', $soustype)) { |
|
| 628 | - if (!trouve_modele($fond = ($type . '_' . $soustype))) { |
|
| 629 | - $fond = ''; |
|
| 630 | - $class = $soustype; |
|
| 631 | - } |
|
| 632 | - // enlever le sous type des params |
|
| 633 | - $params = array_diff($params, [$soustype]); |
|
| 634 | - } |
|
| 635 | - } |
|
| 636 | - |
|
| 637 | - // Si ca marche pas en precisant le sous-type, prendre le type |
|
| 638 | - if (!$fond and !trouve_modele($fond = $type)) { |
|
| 639 | - spip_log("Modele $type introuvable", _LOG_INFO_IMPORTANTE); |
|
| 640 | - |
|
| 641 | - return false; |
|
| 642 | - } |
|
| 643 | - $fond = 'modeles/' . $fond; |
|
| 644 | - // Creer le contexte |
|
| 645 | - $contexte = $env; |
|
| 646 | - $contexte['dir_racine'] = _DIR_RACINE; # eviter de mixer un cache racine et un cache ecrire (meme si pour l'instant les modeles ne sont pas caches, le resultat etant different il faut que le contexte en tienne compte |
|
| 647 | - |
|
| 648 | - // Le numero du modele est mis dans l'environnement |
|
| 649 | - // d'une part sous l'identifiant "id" |
|
| 650 | - // et d'autre part sous l'identifiant de la cle primaire |
|
| 651 | - // par la fonction id_table_objet, |
|
| 652 | - // (<article1> =>> article =>> id_article =>> id_article=1) |
|
| 653 | - $_id = id_table_objet($type); |
|
| 654 | - $contexte['id'] = $contexte[$_id] = $id; |
|
| 655 | - |
|
| 656 | - if (isset($class)) { |
|
| 657 | - $contexte['class'] = $class; |
|
| 658 | - } |
|
| 659 | - |
|
| 660 | - // Si un lien a ete passe en parametre, ex: [<modele1>->url] ou [<modele1|title_du_lien{hreflang}->url] |
|
| 661 | - if ($lien) { |
|
| 662 | - # un eventuel guillemet (") sera reechappe par #ENV |
|
| 663 | - $contexte['lien'] = str_replace('"', '"', $lien['href']); |
|
| 664 | - $contexte['lien_class'] = $lien['class']; |
|
| 665 | - $contexte['lien_mime'] = $lien['mime']; |
|
| 666 | - $contexte['lien_title'] = $lien['title']; |
|
| 667 | - $contexte['lien_hreflang'] = $lien['hreflang']; |
|
| 668 | - } |
|
| 669 | - |
|
| 670 | - // Traiter les parametres |
|
| 671 | - // par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en> |
|
| 672 | - $arg_list = creer_contexte_de_modele($params); |
|
| 673 | - $contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args |
|
| 674 | - $contexte = array_merge($contexte, $arg_list); |
|
| 675 | - |
|
| 676 | - // Appliquer le modele avec le contexte |
|
| 677 | - $retour = recuperer_fond($fond, $contexte, [], $connect); |
|
| 678 | - |
|
| 679 | - // Regarder si le modele tient compte des liens (il *doit* alors indiquer |
|
| 680 | - // spip_lien_ok dans les classes de son conteneur de premier niveau ; |
|
| 681 | - // sinon, s'il y a un lien, on l'ajoute classiquement |
|
| 682 | - if ( |
|
| 683 | - strstr( |
|
| 684 | - ' ' . ($classes = extraire_attribut($retour, 'class')) . ' ', |
|
| 685 | - 'spip_lien_ok' |
|
| 686 | - ) |
|
| 687 | - ) { |
|
| 688 | - $retour = inserer_attribut( |
|
| 689 | - $retour, |
|
| 690 | - 'class', |
|
| 691 | - trim(str_replace(' spip_lien_ok ', ' ', " $classes ")) |
|
| 692 | - ); |
|
| 693 | - } else { |
|
| 694 | - if ($lien) { |
|
| 695 | - $retour = "<a href='" . $lien['href'] . "' class='" . $lien['class'] . "'>" . $retour . '</a>'; |
|
| 696 | - } |
|
| 697 | - } |
|
| 698 | - |
|
| 699 | - $compteur--; |
|
| 700 | - |
|
| 701 | - return (isset($arg_list['ajax']) and $arg_list['ajax'] == 'ajax') |
|
| 702 | - ? encoder_contexte_ajax($contexte, '', $retour) |
|
| 703 | - : $retour; |
|
| 608 | + static $compteur; |
|
| 609 | + if (++$compteur > 10) { |
|
| 610 | + return ''; |
|
| 611 | + } # ne pas boucler indefiniment |
|
| 612 | + |
|
| 613 | + $type = strtolower($type); |
|
| 614 | + $type = styliser_modele($type, $id); |
|
| 615 | + |
|
| 616 | + $fond = $class = ''; |
|
| 617 | + |
|
| 618 | + $params = array_filter(explode('|', $params)); |
|
| 619 | + if ($params) { |
|
| 620 | + $soustype = current($params); |
|
| 621 | + $soustype = strtolower(trim($soustype)); |
|
| 622 | + if (in_array($soustype, ['left', 'right', 'center', 'ajax'])) { |
|
| 623 | + $soustype = next($params); |
|
| 624 | + $soustype = strtolower($soustype); |
|
| 625 | + } |
|
| 626 | + |
|
| 627 | + if (preg_match(',^[a-z0-9_]+$,', $soustype)) { |
|
| 628 | + if (!trouve_modele($fond = ($type . '_' . $soustype))) { |
|
| 629 | + $fond = ''; |
|
| 630 | + $class = $soustype; |
|
| 631 | + } |
|
| 632 | + // enlever le sous type des params |
|
| 633 | + $params = array_diff($params, [$soustype]); |
|
| 634 | + } |
|
| 635 | + } |
|
| 636 | + |
|
| 637 | + // Si ca marche pas en precisant le sous-type, prendre le type |
|
| 638 | + if (!$fond and !trouve_modele($fond = $type)) { |
|
| 639 | + spip_log("Modele $type introuvable", _LOG_INFO_IMPORTANTE); |
|
| 640 | + |
|
| 641 | + return false; |
|
| 642 | + } |
|
| 643 | + $fond = 'modeles/' . $fond; |
|
| 644 | + // Creer le contexte |
|
| 645 | + $contexte = $env; |
|
| 646 | + $contexte['dir_racine'] = _DIR_RACINE; # eviter de mixer un cache racine et un cache ecrire (meme si pour l'instant les modeles ne sont pas caches, le resultat etant different il faut que le contexte en tienne compte |
|
| 647 | + |
|
| 648 | + // Le numero du modele est mis dans l'environnement |
|
| 649 | + // d'une part sous l'identifiant "id" |
|
| 650 | + // et d'autre part sous l'identifiant de la cle primaire |
|
| 651 | + // par la fonction id_table_objet, |
|
| 652 | + // (<article1> =>> article =>> id_article =>> id_article=1) |
|
| 653 | + $_id = id_table_objet($type); |
|
| 654 | + $contexte['id'] = $contexte[$_id] = $id; |
|
| 655 | + |
|
| 656 | + if (isset($class)) { |
|
| 657 | + $contexte['class'] = $class; |
|
| 658 | + } |
|
| 659 | + |
|
| 660 | + // Si un lien a ete passe en parametre, ex: [<modele1>->url] ou [<modele1|title_du_lien{hreflang}->url] |
|
| 661 | + if ($lien) { |
|
| 662 | + # un eventuel guillemet (") sera reechappe par #ENV |
|
| 663 | + $contexte['lien'] = str_replace('"', '"', $lien['href']); |
|
| 664 | + $contexte['lien_class'] = $lien['class']; |
|
| 665 | + $contexte['lien_mime'] = $lien['mime']; |
|
| 666 | + $contexte['lien_title'] = $lien['title']; |
|
| 667 | + $contexte['lien_hreflang'] = $lien['hreflang']; |
|
| 668 | + } |
|
| 669 | + |
|
| 670 | + // Traiter les parametres |
|
| 671 | + // par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en> |
|
| 672 | + $arg_list = creer_contexte_de_modele($params); |
|
| 673 | + $contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args |
|
| 674 | + $contexte = array_merge($contexte, $arg_list); |
|
| 675 | + |
|
| 676 | + // Appliquer le modele avec le contexte |
|
| 677 | + $retour = recuperer_fond($fond, $contexte, [], $connect); |
|
| 678 | + |
|
| 679 | + // Regarder si le modele tient compte des liens (il *doit* alors indiquer |
|
| 680 | + // spip_lien_ok dans les classes de son conteneur de premier niveau ; |
|
| 681 | + // sinon, s'il y a un lien, on l'ajoute classiquement |
|
| 682 | + if ( |
|
| 683 | + strstr( |
|
| 684 | + ' ' . ($classes = extraire_attribut($retour, 'class')) . ' ', |
|
| 685 | + 'spip_lien_ok' |
|
| 686 | + ) |
|
| 687 | + ) { |
|
| 688 | + $retour = inserer_attribut( |
|
| 689 | + $retour, |
|
| 690 | + 'class', |
|
| 691 | + trim(str_replace(' spip_lien_ok ', ' ', " $classes ")) |
|
| 692 | + ); |
|
| 693 | + } else { |
|
| 694 | + if ($lien) { |
|
| 695 | + $retour = "<a href='" . $lien['href'] . "' class='" . $lien['class'] . "'>" . $retour . '</a>'; |
|
| 696 | + } |
|
| 697 | + } |
|
| 698 | + |
|
| 699 | + $compteur--; |
|
| 700 | + |
|
| 701 | + return (isset($arg_list['ajax']) and $arg_list['ajax'] == 'ajax') |
|
| 702 | + ? encoder_contexte_ajax($contexte, '', $retour) |
|
| 703 | + : $retour; |
|
| 704 | 704 | } |
| 705 | 705 | |
| 706 | 706 | // Un inclure_page qui marche aussi pour l'espace prive |
@@ -709,105 +709,105 @@ discard block |
||
| 709 | 709 | // recuperer_fond($fond,$contexte,array('raw'=>true)) |
| 710 | 710 | function evaluer_fond($fond, $contexte = [], string $connect = '') { |
| 711 | 711 | |
| 712 | - $page = inclure_page($fond, $contexte, $connect); |
|
| 713 | - |
|
| 714 | - if (!$page) { |
|
| 715 | - return $page; |
|
| 716 | - } |
|
| 717 | - // eval $page et affecte $res |
|
| 718 | - include _ROOT_RESTREINT . 'public/evaluer_page.php'; |
|
| 719 | - |
|
| 720 | - // Lever un drapeau (global) si le fond utilise #SESSION |
|
| 721 | - // a destination de public/parametrer |
|
| 722 | - // pour remonter vers les inclusions appelantes |
|
| 723 | - // il faut bien lever ce drapeau apres avoir evalue le fond |
|
| 724 | - // pour ne pas faire descendre le flag vers les inclusions appelees |
|
| 725 | - if ( |
|
| 726 | - isset($page['invalideurs']) |
|
| 727 | - and isset($page['invalideurs']['session']) |
|
| 728 | - ) { |
|
| 729 | - $GLOBALS['cache_utilise_session'] = $page['invalideurs']['session']; |
|
| 730 | - } |
|
| 731 | - |
|
| 732 | - return $page; |
|
| 712 | + $page = inclure_page($fond, $contexte, $connect); |
|
| 713 | + |
|
| 714 | + if (!$page) { |
|
| 715 | + return $page; |
|
| 716 | + } |
|
| 717 | + // eval $page et affecte $res |
|
| 718 | + include _ROOT_RESTREINT . 'public/evaluer_page.php'; |
|
| 719 | + |
|
| 720 | + // Lever un drapeau (global) si le fond utilise #SESSION |
|
| 721 | + // a destination de public/parametrer |
|
| 722 | + // pour remonter vers les inclusions appelantes |
|
| 723 | + // il faut bien lever ce drapeau apres avoir evalue le fond |
|
| 724 | + // pour ne pas faire descendre le flag vers les inclusions appelees |
|
| 725 | + if ( |
|
| 726 | + isset($page['invalideurs']) |
|
| 727 | + and isset($page['invalideurs']['session']) |
|
| 728 | + ) { |
|
| 729 | + $GLOBALS['cache_utilise_session'] = $page['invalideurs']['session']; |
|
| 730 | + } |
|
| 731 | + |
|
| 732 | + return $page; |
|
| 733 | 733 | } |
| 734 | 734 | |
| 735 | 735 | |
| 736 | 736 | function page_base_href(&$texte) { |
| 737 | - static $set_html_base = null; |
|
| 738 | - if (is_null($set_html_base)) { |
|
| 739 | - if (!defined('_SET_HTML_BASE')) { |
|
| 740 | - // si la profondeur est superieure a 1 |
|
| 741 | - // est que ce n'est pas une url page ni une url action |
|
| 742 | - // activer par defaut |
|
| 743 | - $set_html_base = (( |
|
| 744 | - $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2) |
|
| 745 | - and _request(_SPIP_PAGE) !== 'login' |
|
| 746 | - and !_request('action')) ? true : false); |
|
| 747 | - } else { |
|
| 748 | - $set_html_base = _SET_HTML_BASE; |
|
| 749 | - } |
|
| 750 | - } |
|
| 751 | - |
|
| 752 | - if ( |
|
| 753 | - $set_html_base |
|
| 754 | - and isset($GLOBALS['html']) and $GLOBALS['html'] |
|
| 755 | - and $GLOBALS['profondeur_url'] > 0 |
|
| 756 | - and ($poshead = strpos($texte, '</head>')) !== false |
|
| 757 | - ) { |
|
| 758 | - $head = substr($texte, 0, $poshead); |
|
| 759 | - $insert = false; |
|
| 760 | - $href_base = false; |
|
| 761 | - if (strpos($head, '<base') === false) { |
|
| 762 | - $insert = true; |
|
| 763 | - } else { |
|
| 764 | - // si aucun <base ...> n'a de href il faut en inserer un |
|
| 765 | - // sinon juste re-ecrire les ancres si besoin |
|
| 766 | - $insert = true; |
|
| 767 | - include_spip('inc/filtres'); |
|
| 768 | - $bases = extraire_balises($head, 'base'); |
|
| 769 | - foreach ($bases as $base) { |
|
| 770 | - if ($href_base = extraire_attribut($base, 'href')) { |
|
| 771 | - $insert = false; |
|
| 772 | - break; |
|
| 773 | - } |
|
| 774 | - } |
|
| 775 | - } |
|
| 776 | - |
|
| 777 | - if ($insert) { |
|
| 778 | - include_spip('inc/filtres_mini'); |
|
| 779 | - // ajouter un base qui reglera tous les liens relatifs |
|
| 780 | - $href_base = url_absolue('./'); |
|
| 781 | - $base = "\n<base href=\"$href_base\" />"; |
|
| 782 | - if (($pos = strpos($head, '<head>')) !== false) { |
|
| 783 | - $head = substr_replace($head, $base, $pos + 6, 0); |
|
| 784 | - } elseif (preg_match(',<head[^>]*>,i', $head, $r)) { |
|
| 785 | - $head = str_replace($r[0], $r[0] . $base, $head); |
|
| 786 | - } |
|
| 787 | - $texte = $head . substr($texte, $poshead); |
|
| 788 | - } |
|
| 789 | - if ($href_base) { |
|
| 790 | - // gerer les ancres |
|
| 791 | - $base = $_SERVER['REQUEST_URI']; |
|
| 792 | - // pas de guillemets ni < dans l'URL qu'on insere dans le HTML |
|
| 793 | - if (strpos($base, "'") or strpos($base, '"') or strpos($base, '<')) { |
|
| 794 | - $base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base); |
|
| 795 | - } |
|
| 796 | - if (strpos($texte, "href='#") !== false) { |
|
| 797 | - $texte = str_replace("href='#", "href='$base#", $texte); |
|
| 798 | - } |
|
| 799 | - if (strpos($texte, 'href="#') !== false) { |
|
| 800 | - $texte = str_replace('href="#', "href=\"$base#", $texte); |
|
| 801 | - } |
|
| 802 | - } |
|
| 803 | - } |
|
| 737 | + static $set_html_base = null; |
|
| 738 | + if (is_null($set_html_base)) { |
|
| 739 | + if (!defined('_SET_HTML_BASE')) { |
|
| 740 | + // si la profondeur est superieure a 1 |
|
| 741 | + // est que ce n'est pas une url page ni une url action |
|
| 742 | + // activer par defaut |
|
| 743 | + $set_html_base = (( |
|
| 744 | + $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2) |
|
| 745 | + and _request(_SPIP_PAGE) !== 'login' |
|
| 746 | + and !_request('action')) ? true : false); |
|
| 747 | + } else { |
|
| 748 | + $set_html_base = _SET_HTML_BASE; |
|
| 749 | + } |
|
| 750 | + } |
|
| 751 | + |
|
| 752 | + if ( |
|
| 753 | + $set_html_base |
|
| 754 | + and isset($GLOBALS['html']) and $GLOBALS['html'] |
|
| 755 | + and $GLOBALS['profondeur_url'] > 0 |
|
| 756 | + and ($poshead = strpos($texte, '</head>')) !== false |
|
| 757 | + ) { |
|
| 758 | + $head = substr($texte, 0, $poshead); |
|
| 759 | + $insert = false; |
|
| 760 | + $href_base = false; |
|
| 761 | + if (strpos($head, '<base') === false) { |
|
| 762 | + $insert = true; |
|
| 763 | + } else { |
|
| 764 | + // si aucun <base ...> n'a de href il faut en inserer un |
|
| 765 | + // sinon juste re-ecrire les ancres si besoin |
|
| 766 | + $insert = true; |
|
| 767 | + include_spip('inc/filtres'); |
|
| 768 | + $bases = extraire_balises($head, 'base'); |
|
| 769 | + foreach ($bases as $base) { |
|
| 770 | + if ($href_base = extraire_attribut($base, 'href')) { |
|
| 771 | + $insert = false; |
|
| 772 | + break; |
|
| 773 | + } |
|
| 774 | + } |
|
| 775 | + } |
|
| 776 | + |
|
| 777 | + if ($insert) { |
|
| 778 | + include_spip('inc/filtres_mini'); |
|
| 779 | + // ajouter un base qui reglera tous les liens relatifs |
|
| 780 | + $href_base = url_absolue('./'); |
|
| 781 | + $base = "\n<base href=\"$href_base\" />"; |
|
| 782 | + if (($pos = strpos($head, '<head>')) !== false) { |
|
| 783 | + $head = substr_replace($head, $base, $pos + 6, 0); |
|
| 784 | + } elseif (preg_match(',<head[^>]*>,i', $head, $r)) { |
|
| 785 | + $head = str_replace($r[0], $r[0] . $base, $head); |
|
| 786 | + } |
|
| 787 | + $texte = $head . substr($texte, $poshead); |
|
| 788 | + } |
|
| 789 | + if ($href_base) { |
|
| 790 | + // gerer les ancres |
|
| 791 | + $base = $_SERVER['REQUEST_URI']; |
|
| 792 | + // pas de guillemets ni < dans l'URL qu'on insere dans le HTML |
|
| 793 | + if (strpos($base, "'") or strpos($base, '"') or strpos($base, '<')) { |
|
| 794 | + $base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base); |
|
| 795 | + } |
|
| 796 | + if (strpos($texte, "href='#") !== false) { |
|
| 797 | + $texte = str_replace("href='#", "href='$base#", $texte); |
|
| 798 | + } |
|
| 799 | + if (strpos($texte, 'href="#') !== false) { |
|
| 800 | + $texte = str_replace('href="#', "href=\"$base#", $texte); |
|
| 801 | + } |
|
| 802 | + } |
|
| 803 | + } |
|
| 804 | 804 | } |
| 805 | 805 | |
| 806 | 806 | |
| 807 | 807 | // Envoyer les entetes, en retenant ceux qui sont a usage interne |
| 808 | 808 | // et demarrent par X-Spip-... |
| 809 | 809 | function envoyer_entetes($entetes) { |
| 810 | - foreach ($entetes as $k => $v) { # if (strncmp($k, 'X-Spip-', 7)) |
|
| 811 | - @header(strlen($v) ? "$k: $v" : $k); |
|
| 812 | - } |
|
| 810 | + foreach ($entetes as $k => $v) { # if (strncmp($k, 'X-Spip-', 7)) |
|
| 811 | + @header(strlen($v) ? "$k: $v" : $k); |
|
| 812 | + } |
|
| 813 | 813 | } |