@@ -11,58 +11,58 @@ discard block |
||
| 11 | 11 | \***************************************************************************/ |
| 12 | 12 | |
| 13 | 13 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 14 | - return; |
|
| 14 | + return; |
|
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | include_spip('xml/interfaces'); |
| 18 | 18 | |
| 19 | 19 | function charger_dtd($grammaire, $avail, $rotlvl) { |
| 20 | - $r = null; |
|
| 21 | - static $dtd = []; # cache bien utile pour le validateur en boucle |
|
| 22 | - |
|
| 23 | - if (isset($dtd[$grammaire])) { |
|
| 24 | - return $dtd[$grammaire]; |
|
| 25 | - } |
|
| 26 | - |
|
| 27 | - if ($avail == 'SYSTEM') { |
|
| 28 | - $grammaire = find_in_path($grammaire); |
|
| 29 | - } |
|
| 30 | - |
|
| 31 | - $file = _DIR_CACHE_XML . preg_replace('/[^\w.]/', '_', $rotlvl) . '.gz'; |
|
| 32 | - |
|
| 33 | - if (lire_fichier($file, $r)) { |
|
| 34 | - if (!$grammaire) { |
|
| 35 | - return []; |
|
| 36 | - } |
|
| 37 | - if (($avail == 'SYSTEM') and filemtime($file) < filemtime($grammaire)) { |
|
| 38 | - $r = false; |
|
| 39 | - } |
|
| 40 | - } |
|
| 41 | - |
|
| 42 | - if ($r) { |
|
| 43 | - $dtc = unserialize($r); |
|
| 44 | - } else { |
|
| 45 | - spip_timer('dtd'); |
|
| 46 | - $dtc = new DTC(); |
|
| 47 | - // L'analyseur retourne un booleen de reussite et modifie $dtc. |
|
| 48 | - // Retourner vide en cas d'echec |
|
| 49 | - if (!analyser_dtd($grammaire, $avail, $dtc)) { |
|
| 50 | - $dtc = []; |
|
| 51 | - } else { |
|
| 52 | - // tri final pour presenter les suggestions de corrections |
|
| 53 | - foreach ($dtc->peres as $k => $v) { |
|
| 54 | - asort($v); |
|
| 55 | - $dtc->peres[$k] = $v; |
|
| 56 | - } |
|
| 57 | - |
|
| 58 | - spip_log("Analyser DTD $avail $grammaire (" . spip_timer('dtd') . ') ' . (is_countable($dtc->macros) ? count($dtc->macros) : 0) . ' macros, ' . (is_countable($dtc->elements) ? count($dtc->elements) : 0) . ' elements, ' . (is_countable($dtc->attributs) ? count($dtc->attributs) : 0) . " listes d'attributs, " . (is_countable($dtc->entites) ? count($dtc->entites) : 0) . ' entites'); |
|
| 59 | - # $r = $dtc->regles; ksort($r);foreach($r as $l => $v) {$t=array_keys($dtc->attributs[$l]);echo "<b>$l</b> '$v' ", count($t), " attributs: ", join (', ',$t);$t=$dtc->peres[$l];echo "<br />",count($t), " peres: ", @join (', ',$t), "<br />\n";}exit; |
|
| 60 | - ecrire_fichier($file, serialize($dtc), true); |
|
| 61 | - } |
|
| 62 | - } |
|
| 63 | - $dtd[$grammaire] = $dtc; |
|
| 64 | - |
|
| 65 | - return $dtc; |
|
| 20 | + $r = null; |
|
| 21 | + static $dtd = []; # cache bien utile pour le validateur en boucle |
|
| 22 | + |
|
| 23 | + if (isset($dtd[$grammaire])) { |
|
| 24 | + return $dtd[$grammaire]; |
|
| 25 | + } |
|
| 26 | + |
|
| 27 | + if ($avail == 'SYSTEM') { |
|
| 28 | + $grammaire = find_in_path($grammaire); |
|
| 29 | + } |
|
| 30 | + |
|
| 31 | + $file = _DIR_CACHE_XML . preg_replace('/[^\w.]/', '_', $rotlvl) . '.gz'; |
|
| 32 | + |
|
| 33 | + if (lire_fichier($file, $r)) { |
|
| 34 | + if (!$grammaire) { |
|
| 35 | + return []; |
|
| 36 | + } |
|
| 37 | + if (($avail == 'SYSTEM') and filemtime($file) < filemtime($grammaire)) { |
|
| 38 | + $r = false; |
|
| 39 | + } |
|
| 40 | + } |
|
| 41 | + |
|
| 42 | + if ($r) { |
|
| 43 | + $dtc = unserialize($r); |
|
| 44 | + } else { |
|
| 45 | + spip_timer('dtd'); |
|
| 46 | + $dtc = new DTC(); |
|
| 47 | + // L'analyseur retourne un booleen de reussite et modifie $dtc. |
|
| 48 | + // Retourner vide en cas d'echec |
|
| 49 | + if (!analyser_dtd($grammaire, $avail, $dtc)) { |
|
| 50 | + $dtc = []; |
|
| 51 | + } else { |
|
| 52 | + // tri final pour presenter les suggestions de corrections |
|
| 53 | + foreach ($dtc->peres as $k => $v) { |
|
| 54 | + asort($v); |
|
| 55 | + $dtc->peres[$k] = $v; |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + spip_log("Analyser DTD $avail $grammaire (" . spip_timer('dtd') . ') ' . (is_countable($dtc->macros) ? count($dtc->macros) : 0) . ' macros, ' . (is_countable($dtc->elements) ? count($dtc->elements) : 0) . ' elements, ' . (is_countable($dtc->attributs) ? count($dtc->attributs) : 0) . " listes d'attributs, " . (is_countable($dtc->entites) ? count($dtc->entites) : 0) . ' entites'); |
|
| 59 | + # $r = $dtc->regles; ksort($r);foreach($r as $l => $v) {$t=array_keys($dtc->attributs[$l]);echo "<b>$l</b> '$v' ", count($t), " attributs: ", join (', ',$t);$t=$dtc->peres[$l];echo "<br />",count($t), " peres: ", @join (', ',$t), "<br />\n";}exit; |
|
| 60 | + ecrire_fichier($file, serialize($dtc), true); |
|
| 61 | + } |
|
| 62 | + } |
|
| 63 | + $dtd[$grammaire] = $dtc; |
|
| 64 | + |
|
| 65 | + return $dtc; |
|
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | // Compiler une regle de production en une Regexp qu'on appliquera sur la |
@@ -74,153 +74,153 @@ discard block |
||
| 74 | 74 | // et parentheser le tout pour que | + * ? s'applique dessus. |
| 75 | 75 | |
| 76 | 76 | function compilerRegle($val) { |
| 77 | - $x = str_replace( |
|
| 78 | - '()', |
|
| 79 | - '', |
|
| 80 | - preg_replace( |
|
| 81 | - '/\s*,\s*/', |
|
| 82 | - '', |
|
| 83 | - preg_replace( |
|
| 84 | - '/(\w+)\s*/', |
|
| 85 | - '(?:\1 )', |
|
| 86 | - preg_replace( |
|
| 87 | - '/\s*\)/', |
|
| 88 | - ')', |
|
| 89 | - preg_replace( |
|
| 90 | - '/\s*([(+*|?])\s*/', |
|
| 91 | - '\1', |
|
| 92 | - preg_replace('/\s*#\w+\s*[,|]?\s*/', '', $val) |
|
| 93 | - ) |
|
| 94 | - ) |
|
| 95 | - ) |
|
| 96 | - ) |
|
| 97 | - ); |
|
| 98 | - |
|
| 99 | - return $x; |
|
| 77 | + $x = str_replace( |
|
| 78 | + '()', |
|
| 79 | + '', |
|
| 80 | + preg_replace( |
|
| 81 | + '/\s*,\s*/', |
|
| 82 | + '', |
|
| 83 | + preg_replace( |
|
| 84 | + '/(\w+)\s*/', |
|
| 85 | + '(?:\1 )', |
|
| 86 | + preg_replace( |
|
| 87 | + '/\s*\)/', |
|
| 88 | + ')', |
|
| 89 | + preg_replace( |
|
| 90 | + '/\s*([(+*|?])\s*/', |
|
| 91 | + '\1', |
|
| 92 | + preg_replace('/\s*#\w+\s*[,|]?\s*/', '', $val) |
|
| 93 | + ) |
|
| 94 | + ) |
|
| 95 | + ) |
|
| 96 | + ) |
|
| 97 | + ); |
|
| 98 | + |
|
| 99 | + return $x; |
|
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | |
| 103 | 103 | function analyser_dtd($loc, $avail, &$dtc) { |
| 104 | - // creer le repertoire de cache si ce n'est fait |
|
| 105 | - // (utile aussi pour le resultat de la compil) |
|
| 106 | - $file = sous_repertoire(_DIR_CACHE_XML); |
|
| 107 | - // si DTD locale, ignorer ce repertoire pour le moment |
|
| 108 | - if ($avail == 'SYSTEM') { |
|
| 109 | - $file = $loc; |
|
| 110 | - if (_DIR_RACINE and strncmp($file, _DIR_RACINE, strlen(_DIR_RACINE)) == 0) { |
|
| 111 | - $file = substr($file, strlen(_DIR_RACINE)); |
|
| 112 | - } |
|
| 113 | - $file = find_in_path($file); |
|
| 114 | - } else { |
|
| 115 | - $file .= preg_replace('/[^\w.]/', '_', $loc); |
|
| 116 | - } |
|
| 117 | - |
|
| 118 | - $dtd = ''; |
|
| 119 | - if (@is_readable($file)) { |
|
| 120 | - lire_fichier($file, $dtd); |
|
| 121 | - } else { |
|
| 122 | - if ($avail == 'PUBLIC') { |
|
| 123 | - include_spip('inc/distant'); |
|
| 124 | - $dtd = recuperer_url($loc); |
|
| 125 | - $dtd = trim($dtd['page'] ?? ''); |
|
| 126 | - if ($dtd) { |
|
| 127 | - ecrire_fichier($file, $dtd, true); |
|
| 128 | - } |
|
| 129 | - } |
|
| 130 | - } |
|
| 131 | - |
|
| 132 | - $dtd = ltrim($dtd); |
|
| 133 | - if (!$dtd) { |
|
| 134 | - spip_log("DTD '$loc' ($file) inaccessible"); |
|
| 135 | - |
|
| 136 | - return false; |
|
| 137 | - } else { |
|
| 138 | - spip_log("analyse de la DTD $loc "); |
|
| 139 | - } |
|
| 140 | - |
|
| 141 | - while ($dtd) { |
|
| 142 | - if ($dtd[0] != '<') { |
|
| 143 | - $r = analyser_dtd_lexeme($dtd, $dtc, $loc); |
|
| 144 | - } elseif ($dtd[1] != '!') { |
|
| 145 | - $r = analyser_dtd_pi($dtd, $dtc, $loc); |
|
| 146 | - } elseif ($dtd[2] == '[') { |
|
| 147 | - $r = analyser_dtd_data($dtd, $dtc, $loc); |
|
| 148 | - } else { |
|
| 149 | - switch ($dtd[3]) { |
|
| 150 | - case '%': |
|
| 151 | - $r = analyser_dtd_data($dtd, $dtc, $loc); |
|
| 152 | - break; |
|
| 153 | - case 'T': |
|
| 154 | - $r = analyser_dtd_attlist($dtd, $dtc, $loc); |
|
| 155 | - break; |
|
| 156 | - case 'L': |
|
| 157 | - $r = analyser_dtd_element($dtd, $dtc, $loc); |
|
| 158 | - break; |
|
| 159 | - case 'N': |
|
| 160 | - $r = analyser_dtd_entity($dtd, $dtc, $loc); |
|
| 161 | - break; |
|
| 162 | - case 'O': |
|
| 163 | - $r = analyser_dtd_notation($dtd, $dtc, $loc); |
|
| 164 | - break; |
|
| 165 | - case '-': |
|
| 166 | - $r = analyser_dtd_comment($dtd, $dtc, $loc); |
|
| 167 | - break; |
|
| 168 | - default: |
|
| 169 | - $r = -1; |
|
| 170 | - } |
|
| 171 | - } |
|
| 172 | - if (!is_string($r)) { |
|
| 173 | - spip_log("erreur $r dans la DTD " . substr($dtd, 0, 80) . '.....'); |
|
| 174 | - |
|
| 175 | - return false; |
|
| 176 | - } |
|
| 177 | - $dtd = $r; |
|
| 178 | - } |
|
| 179 | - |
|
| 180 | - return true; |
|
| 104 | + // creer le repertoire de cache si ce n'est fait |
|
| 105 | + // (utile aussi pour le resultat de la compil) |
|
| 106 | + $file = sous_repertoire(_DIR_CACHE_XML); |
|
| 107 | + // si DTD locale, ignorer ce repertoire pour le moment |
|
| 108 | + if ($avail == 'SYSTEM') { |
|
| 109 | + $file = $loc; |
|
| 110 | + if (_DIR_RACINE and strncmp($file, _DIR_RACINE, strlen(_DIR_RACINE)) == 0) { |
|
| 111 | + $file = substr($file, strlen(_DIR_RACINE)); |
|
| 112 | + } |
|
| 113 | + $file = find_in_path($file); |
|
| 114 | + } else { |
|
| 115 | + $file .= preg_replace('/[^\w.]/', '_', $loc); |
|
| 116 | + } |
|
| 117 | + |
|
| 118 | + $dtd = ''; |
|
| 119 | + if (@is_readable($file)) { |
|
| 120 | + lire_fichier($file, $dtd); |
|
| 121 | + } else { |
|
| 122 | + if ($avail == 'PUBLIC') { |
|
| 123 | + include_spip('inc/distant'); |
|
| 124 | + $dtd = recuperer_url($loc); |
|
| 125 | + $dtd = trim($dtd['page'] ?? ''); |
|
| 126 | + if ($dtd) { |
|
| 127 | + ecrire_fichier($file, $dtd, true); |
|
| 128 | + } |
|
| 129 | + } |
|
| 130 | + } |
|
| 131 | + |
|
| 132 | + $dtd = ltrim($dtd); |
|
| 133 | + if (!$dtd) { |
|
| 134 | + spip_log("DTD '$loc' ($file) inaccessible"); |
|
| 135 | + |
|
| 136 | + return false; |
|
| 137 | + } else { |
|
| 138 | + spip_log("analyse de la DTD $loc "); |
|
| 139 | + } |
|
| 140 | + |
|
| 141 | + while ($dtd) { |
|
| 142 | + if ($dtd[0] != '<') { |
|
| 143 | + $r = analyser_dtd_lexeme($dtd, $dtc, $loc); |
|
| 144 | + } elseif ($dtd[1] != '!') { |
|
| 145 | + $r = analyser_dtd_pi($dtd, $dtc, $loc); |
|
| 146 | + } elseif ($dtd[2] == '[') { |
|
| 147 | + $r = analyser_dtd_data($dtd, $dtc, $loc); |
|
| 148 | + } else { |
|
| 149 | + switch ($dtd[3]) { |
|
| 150 | + case '%': |
|
| 151 | + $r = analyser_dtd_data($dtd, $dtc, $loc); |
|
| 152 | + break; |
|
| 153 | + case 'T': |
|
| 154 | + $r = analyser_dtd_attlist($dtd, $dtc, $loc); |
|
| 155 | + break; |
|
| 156 | + case 'L': |
|
| 157 | + $r = analyser_dtd_element($dtd, $dtc, $loc); |
|
| 158 | + break; |
|
| 159 | + case 'N': |
|
| 160 | + $r = analyser_dtd_entity($dtd, $dtc, $loc); |
|
| 161 | + break; |
|
| 162 | + case 'O': |
|
| 163 | + $r = analyser_dtd_notation($dtd, $dtc, $loc); |
|
| 164 | + break; |
|
| 165 | + case '-': |
|
| 166 | + $r = analyser_dtd_comment($dtd, $dtc, $loc); |
|
| 167 | + break; |
|
| 168 | + default: |
|
| 169 | + $r = -1; |
|
| 170 | + } |
|
| 171 | + } |
|
| 172 | + if (!is_string($r)) { |
|
| 173 | + spip_log("erreur $r dans la DTD " . substr($dtd, 0, 80) . '.....'); |
|
| 174 | + |
|
| 175 | + return false; |
|
| 176 | + } |
|
| 177 | + $dtd = $r; |
|
| 178 | + } |
|
| 179 | + |
|
| 180 | + return true; |
|
| 181 | 181 | } |
| 182 | 182 | |
| 183 | 183 | function analyser_dtd_comment($dtd, &$dtc, $grammaire) { |
| 184 | - // ejecter les commentaires, surtout quand ils contiennent du code. |
|
| 185 | - // Option /s car sur plusieurs lignes parfois |
|
| 184 | + // ejecter les commentaires, surtout quand ils contiennent du code. |
|
| 185 | + // Option /s car sur plusieurs lignes parfois |
|
| 186 | 186 | |
| 187 | - if (!preg_match('/^<!--.*?-->\s*(.*)$/s', $dtd, $m)) { |
|
| 188 | - return -6; |
|
| 189 | - } |
|
| 187 | + if (!preg_match('/^<!--.*?-->\s*(.*)$/s', $dtd, $m)) { |
|
| 188 | + return -6; |
|
| 189 | + } |
|
| 190 | 190 | |
| 191 | - return $m[1]; |
|
| 191 | + return $m[1]; |
|
| 192 | 192 | } |
| 193 | 193 | |
| 194 | 194 | function analyser_dtd_pi($dtd, &$dtc, $grammaire) { |
| 195 | - if (!preg_match('/^<\?.*?>\s*(.*)$/s', $dtd, $m)) { |
|
| 196 | - return -10; |
|
| 197 | - } |
|
| 195 | + if (!preg_match('/^<\?.*?>\s*(.*)$/s', $dtd, $m)) { |
|
| 196 | + return -10; |
|
| 197 | + } |
|
| 198 | 198 | |
| 199 | - return $m[1]; |
|
| 199 | + return $m[1]; |
|
| 200 | 200 | } |
| 201 | 201 | |
| 202 | 202 | function analyser_dtd_lexeme($dtd, &$dtc, $grammaire) { |
| 203 | 203 | |
| 204 | - if (!preg_match(_REGEXP_ENTITY_DEF, $dtd, $m)) { |
|
| 205 | - return -9; |
|
| 206 | - } |
|
| 207 | - |
|
| 208 | - [, $s] = $m; |
|
| 209 | - $n = $dtc->macros[$s]; |
|
| 210 | - |
|
| 211 | - if (is_array($n)) { |
|
| 212 | - // en cas d'inclusion, l'espace de nom est le meme |
|
| 213 | - // mais gaffe aux DTD dont l'URL est relative a l'engloblante |
|
| 214 | - if ( |
|
| 215 | - ($n[0] == 'PUBLIC') |
|
| 216 | - and !tester_url_absolue($n[1]) |
|
| 217 | - ) { |
|
| 218 | - $n[1] = substr($grammaire, 0, strrpos($grammaire, '/') + 1) . $n[1]; |
|
| 219 | - } |
|
| 220 | - analyser_dtd($n[1], $n[0], $dtc); |
|
| 221 | - } |
|
| 222 | - |
|
| 223 | - return ltrim(substr($dtd, strlen($m[0]))); |
|
| 204 | + if (!preg_match(_REGEXP_ENTITY_DEF, $dtd, $m)) { |
|
| 205 | + return -9; |
|
| 206 | + } |
|
| 207 | + |
|
| 208 | + [, $s] = $m; |
|
| 209 | + $n = $dtc->macros[$s]; |
|
| 210 | + |
|
| 211 | + if (is_array($n)) { |
|
| 212 | + // en cas d'inclusion, l'espace de nom est le meme |
|
| 213 | + // mais gaffe aux DTD dont l'URL est relative a l'engloblante |
|
| 214 | + if ( |
|
| 215 | + ($n[0] == 'PUBLIC') |
|
| 216 | + and !tester_url_absolue($n[1]) |
|
| 217 | + ) { |
|
| 218 | + $n[1] = substr($grammaire, 0, strrpos($grammaire, '/') + 1) . $n[1]; |
|
| 219 | + } |
|
| 220 | + analyser_dtd($n[1], $n[0], $dtc); |
|
| 221 | + } |
|
| 222 | + |
|
| 223 | + return ltrim(substr($dtd, strlen($m[0]))); |
|
| 224 | 224 | } |
| 225 | 225 | |
| 226 | 226 | // il faudrait gerer plus proprement les niveaux d'inclusion: |
@@ -228,83 +228,83 @@ discard block |
||
| 228 | 228 | |
| 229 | 229 | function analyser_dtd_data($dtd, &$dtc, $grammaire) { |
| 230 | 230 | |
| 231 | - if (!preg_match(_REGEXP_INCLUDE_USE, $dtd, $m)) { |
|
| 232 | - return -11; |
|
| 233 | - } |
|
| 234 | - if ( |
|
| 235 | - !preg_match( |
|
| 236 | - '/^((\s*<!(\[\s*%\s*[^;]*;\s*\[([^]<]*<[^>]*>)*[^]<]*\]\]>)|([^]>]*>))*[^]<]*)\]\]>\s*/s', |
|
| 237 | - $m[2], |
|
| 238 | - $r |
|
| 239 | - ) |
|
| 240 | - ) { |
|
| 241 | - return -12; |
|
| 242 | - } |
|
| 243 | - |
|
| 244 | - if ($dtc->macros[$m[1]] == 'INCLUDE') { |
|
| 245 | - $retour = $r[1] . substr($m[2], strlen($r[0])); |
|
| 246 | - } else { |
|
| 247 | - $retour = substr($m[2], strlen($r[0])); |
|
| 248 | - } |
|
| 249 | - |
|
| 250 | - return $retour; |
|
| 231 | + if (!preg_match(_REGEXP_INCLUDE_USE, $dtd, $m)) { |
|
| 232 | + return -11; |
|
| 233 | + } |
|
| 234 | + if ( |
|
| 235 | + !preg_match( |
|
| 236 | + '/^((\s*<!(\[\s*%\s*[^;]*;\s*\[([^]<]*<[^>]*>)*[^]<]*\]\]>)|([^]>]*>))*[^]<]*)\]\]>\s*/s', |
|
| 237 | + $m[2], |
|
| 238 | + $r |
|
| 239 | + ) |
|
| 240 | + ) { |
|
| 241 | + return -12; |
|
| 242 | + } |
|
| 243 | + |
|
| 244 | + if ($dtc->macros[$m[1]] == 'INCLUDE') { |
|
| 245 | + $retour = $r[1] . substr($m[2], strlen($r[0])); |
|
| 246 | + } else { |
|
| 247 | + $retour = substr($m[2], strlen($r[0])); |
|
| 248 | + } |
|
| 249 | + |
|
| 250 | + return $retour; |
|
| 251 | 251 | } |
| 252 | 252 | |
| 253 | 253 | function analyser_dtd_notation($dtd, &$dtc, $grammaire) { |
| 254 | - if (!preg_match('/^<!NOTATION.*?>\s*(.*)$/s', $dtd, $m)) { |
|
| 255 | - return -8; |
|
| 256 | - } |
|
| 257 | - spip_log('analyser_dtd_notation a ecrire'); |
|
| 254 | + if (!preg_match('/^<!NOTATION.*?>\s*(.*)$/s', $dtd, $m)) { |
|
| 255 | + return -8; |
|
| 256 | + } |
|
| 257 | + spip_log('analyser_dtd_notation a ecrire'); |
|
| 258 | 258 | |
| 259 | - return $m[1]; |
|
| 259 | + return $m[1]; |
|
| 260 | 260 | } |
| 261 | 261 | |
| 262 | 262 | function analyser_dtd_entity($dtd, &$dtc, $grammaire) { |
| 263 | - if (!preg_match(_REGEXP_ENTITY_DECL, $dtd, $m)) { |
|
| 264 | - return -2; |
|
| 265 | - } |
|
| 266 | - |
|
| 267 | - [$t, $term, $nom, $type, $k1, $k2, $k3, $k4, $k5, $k6, $c, $q, $alt, $dtd] = $m; |
|
| 268 | - |
|
| 269 | - if (isset($dtc->macros[$nom]) and $dtc->macros[$nom]) { |
|
| 270 | - return $dtd; |
|
| 271 | - } |
|
| 272 | - if (isset($dtc->entites[$nom])) { |
|
| 273 | - spip_log("redefinition de l'entite $nom"); |
|
| 274 | - } |
|
| 275 | - if ($k6) { |
|
| 276 | - return $k6 . $dtd; |
|
| 277 | - } // cas du synonyme complet |
|
| 278 | - $val = expanserEntite(($k2 ? $k3 : ($k4 ? $k5 : $k6)), $dtc->macros); |
|
| 279 | - |
|
| 280 | - // cas particulier double evaluation: 'PUBLIC "..." "...."' |
|
| 281 | - if (preg_match('/(PUBLIC|SYSTEM)\s+"([^"]*)"\s*("([^"]*)")?\s*$/s', $val, $r)) { |
|
| 282 | - [$t, $type, $val, $q, $alt] = $r; |
|
| 283 | - } |
|
| 284 | - |
|
| 285 | - if (!$term) { |
|
| 286 | - $dtc->entites[$nom] = $val; |
|
| 287 | - } elseif (!$type) { |
|
| 288 | - $dtc->macros[$nom] = $val; |
|
| 289 | - } else { |
|
| 290 | - if (($type == 'SYSTEM') and !$alt) { |
|
| 291 | - $alt = $val; |
|
| 292 | - } |
|
| 293 | - if (!$alt) { |
|
| 294 | - $dtc->macros[$nom] = $val; |
|
| 295 | - } else { |
|
| 296 | - if ( |
|
| 297 | - ($type == 'PUBLIC') |
|
| 298 | - and (strpos($alt, '/') === false) |
|
| 299 | - ) { |
|
| 300 | - $alt = preg_replace(',/[^/]+$,', '/', $grammaire) |
|
| 301 | - . $alt; |
|
| 302 | - } |
|
| 303 | - $dtc->macros[$nom] = [$type, $alt]; |
|
| 304 | - } |
|
| 305 | - } |
|
| 306 | - |
|
| 307 | - return $dtd; |
|
| 263 | + if (!preg_match(_REGEXP_ENTITY_DECL, $dtd, $m)) { |
|
| 264 | + return -2; |
|
| 265 | + } |
|
| 266 | + |
|
| 267 | + [$t, $term, $nom, $type, $k1, $k2, $k3, $k4, $k5, $k6, $c, $q, $alt, $dtd] = $m; |
|
| 268 | + |
|
| 269 | + if (isset($dtc->macros[$nom]) and $dtc->macros[$nom]) { |
|
| 270 | + return $dtd; |
|
| 271 | + } |
|
| 272 | + if (isset($dtc->entites[$nom])) { |
|
| 273 | + spip_log("redefinition de l'entite $nom"); |
|
| 274 | + } |
|
| 275 | + if ($k6) { |
|
| 276 | + return $k6 . $dtd; |
|
| 277 | + } // cas du synonyme complet |
|
| 278 | + $val = expanserEntite(($k2 ? $k3 : ($k4 ? $k5 : $k6)), $dtc->macros); |
|
| 279 | + |
|
| 280 | + // cas particulier double evaluation: 'PUBLIC "..." "...."' |
|
| 281 | + if (preg_match('/(PUBLIC|SYSTEM)\s+"([^"]*)"\s*("([^"]*)")?\s*$/s', $val, $r)) { |
|
| 282 | + [$t, $type, $val, $q, $alt] = $r; |
|
| 283 | + } |
|
| 284 | + |
|
| 285 | + if (!$term) { |
|
| 286 | + $dtc->entites[$nom] = $val; |
|
| 287 | + } elseif (!$type) { |
|
| 288 | + $dtc->macros[$nom] = $val; |
|
| 289 | + } else { |
|
| 290 | + if (($type == 'SYSTEM') and !$alt) { |
|
| 291 | + $alt = $val; |
|
| 292 | + } |
|
| 293 | + if (!$alt) { |
|
| 294 | + $dtc->macros[$nom] = $val; |
|
| 295 | + } else { |
|
| 296 | + if ( |
|
| 297 | + ($type == 'PUBLIC') |
|
| 298 | + and (strpos($alt, '/') === false) |
|
| 299 | + ) { |
|
| 300 | + $alt = preg_replace(',/[^/]+$,', '/', $grammaire) |
|
| 301 | + . $alt; |
|
| 302 | + } |
|
| 303 | + $dtc->macros[$nom] = [$type, $alt]; |
|
| 304 | + } |
|
| 305 | + } |
|
| 306 | + |
|
| 307 | + return $dtd; |
|
| 308 | 308 | } |
| 309 | 309 | |
| 310 | 310 | // Dresser le tableau des filles potentielles de l'element |
@@ -317,76 +317,76 @@ discard block |
||
| 317 | 317 | // Fin du controle en finElement |
| 318 | 318 | |
| 319 | 319 | function analyser_dtd_element($dtd, &$dtc, $grammaire) { |
| 320 | - if (!preg_match('/^<!ELEMENT\s+([^>\s]+)([^>]*)>\s*(.*)$/s', $dtd, $m)) { |
|
| 321 | - return -3; |
|
| 322 | - } |
|
| 323 | - |
|
| 324 | - [, $nom, $contenu, $dtd] = $m; |
|
| 325 | - $nom = expanserEntite($nom, $dtc->macros); |
|
| 326 | - |
|
| 327 | - if (isset($dtc->elements[$nom])) { |
|
| 328 | - spip_log("redefinition de l'element $nom dans la DTD"); |
|
| 329 | - |
|
| 330 | - return -4; |
|
| 331 | - } |
|
| 332 | - $filles = []; |
|
| 333 | - $contenu = expanserEntite($contenu, $dtc->macros); |
|
| 334 | - $val = $contenu ? compilerRegle($contenu) : '(?:EMPTY )'; |
|
| 335 | - if ($val == '(?:EMPTY )') { |
|
| 336 | - $dtc->regles[$nom] = 'EMPTY'; |
|
| 337 | - } elseif ($val == '(?:ANY )') { |
|
| 338 | - $dtc->regles[$nom] = 'ANY'; |
|
| 339 | - } else { |
|
| 340 | - $last = substr($val, -1); |
|
| 341 | - if ( |
|
| 342 | - preg_match('/ \w/', $val) |
|
| 343 | - or (!empty($last) and strpos('*+?', $last) === false) |
|
| 344 | - ) { |
|
| 345 | - $dtc->regles[$nom] = "/^$val$/"; |
|
| 346 | - } else { |
|
| 347 | - $dtc->regles[$nom] = $last; |
|
| 348 | - } |
|
| 349 | - $filles = array_values(preg_split('/\W+/', $val, -1, PREG_SPLIT_NO_EMPTY)); |
|
| 350 | - |
|
| 351 | - foreach ($filles as $k) { |
|
| 352 | - if (!isset($dtc->peres[$k])) { |
|
| 353 | - $dtc->peres[$k] = []; |
|
| 354 | - } |
|
| 355 | - if (!in_array($nom, $dtc->peres[$k])) { |
|
| 356 | - $dtc->peres[$k][] = $nom; |
|
| 357 | - } |
|
| 358 | - } |
|
| 359 | - } |
|
| 360 | - $dtc->pcdata[$nom] = (strpos($contenu, '#PCDATA') === false); |
|
| 361 | - $dtc->elements[$nom] = $filles; |
|
| 362 | - |
|
| 363 | - return $dtd; |
|
| 320 | + if (!preg_match('/^<!ELEMENT\s+([^>\s]+)([^>]*)>\s*(.*)$/s', $dtd, $m)) { |
|
| 321 | + return -3; |
|
| 322 | + } |
|
| 323 | + |
|
| 324 | + [, $nom, $contenu, $dtd] = $m; |
|
| 325 | + $nom = expanserEntite($nom, $dtc->macros); |
|
| 326 | + |
|
| 327 | + if (isset($dtc->elements[$nom])) { |
|
| 328 | + spip_log("redefinition de l'element $nom dans la DTD"); |
|
| 329 | + |
|
| 330 | + return -4; |
|
| 331 | + } |
|
| 332 | + $filles = []; |
|
| 333 | + $contenu = expanserEntite($contenu, $dtc->macros); |
|
| 334 | + $val = $contenu ? compilerRegle($contenu) : '(?:EMPTY )'; |
|
| 335 | + if ($val == '(?:EMPTY )') { |
|
| 336 | + $dtc->regles[$nom] = 'EMPTY'; |
|
| 337 | + } elseif ($val == '(?:ANY )') { |
|
| 338 | + $dtc->regles[$nom] = 'ANY'; |
|
| 339 | + } else { |
|
| 340 | + $last = substr($val, -1); |
|
| 341 | + if ( |
|
| 342 | + preg_match('/ \w/', $val) |
|
| 343 | + or (!empty($last) and strpos('*+?', $last) === false) |
|
| 344 | + ) { |
|
| 345 | + $dtc->regles[$nom] = "/^$val$/"; |
|
| 346 | + } else { |
|
| 347 | + $dtc->regles[$nom] = $last; |
|
| 348 | + } |
|
| 349 | + $filles = array_values(preg_split('/\W+/', $val, -1, PREG_SPLIT_NO_EMPTY)); |
|
| 350 | + |
|
| 351 | + foreach ($filles as $k) { |
|
| 352 | + if (!isset($dtc->peres[$k])) { |
|
| 353 | + $dtc->peres[$k] = []; |
|
| 354 | + } |
|
| 355 | + if (!in_array($nom, $dtc->peres[$k])) { |
|
| 356 | + $dtc->peres[$k][] = $nom; |
|
| 357 | + } |
|
| 358 | + } |
|
| 359 | + } |
|
| 360 | + $dtc->pcdata[$nom] = (strpos($contenu, '#PCDATA') === false); |
|
| 361 | + $dtc->elements[$nom] = $filles; |
|
| 362 | + |
|
| 363 | + return $dtd; |
|
| 364 | 364 | } |
| 365 | 365 | |
| 366 | 366 | |
| 367 | 367 | function analyser_dtd_attlist($dtd, &$dtc, $grammaire) { |
| 368 | - if (!preg_match('/^<!ATTLIST\s+(\S+)\s+([^>]*)>\s*(.*)/s', $dtd, $m)) { |
|
| 369 | - return -5; |
|
| 370 | - } |
|
| 371 | - |
|
| 372 | - [, $nom, $val, $dtd] = $m; |
|
| 373 | - $nom = expanserEntite($nom, $dtc->macros); |
|
| 374 | - $val = expanserEntite($val, $dtc->macros); |
|
| 375 | - if (!isset($dtc->attributs[$nom])) { |
|
| 376 | - $dtc->attributs[$nom] = []; |
|
| 377 | - } |
|
| 378 | - |
|
| 379 | - if (preg_match_all("/\s*(\S+)\s+(([(][^)]*[)])|(\S+))\s+([^\s']*)(\s*'[^']*')?/", $val, $r2, PREG_SET_ORDER)) { |
|
| 380 | - foreach ($r2 as $m2) { |
|
| 381 | - $v = preg_match('/^\w+$/', $m2[2]) ? $m2[2] |
|
| 382 | - : ('/^' . preg_replace('/\s+/', '', $m2[2]) . '$/'); |
|
| 383 | - $m21 = expanserEntite($m2[1], $dtc->macros); |
|
| 384 | - $m25 = expanserEntite($m2[5], $dtc->macros); |
|
| 385 | - $dtc->attributs[$nom][$m21] = [$v, $m25]; |
|
| 386 | - } |
|
| 387 | - } |
|
| 388 | - |
|
| 389 | - return $dtd; |
|
| 368 | + if (!preg_match('/^<!ATTLIST\s+(\S+)\s+([^>]*)>\s*(.*)/s', $dtd, $m)) { |
|
| 369 | + return -5; |
|
| 370 | + } |
|
| 371 | + |
|
| 372 | + [, $nom, $val, $dtd] = $m; |
|
| 373 | + $nom = expanserEntite($nom, $dtc->macros); |
|
| 374 | + $val = expanserEntite($val, $dtc->macros); |
|
| 375 | + if (!isset($dtc->attributs[$nom])) { |
|
| 376 | + $dtc->attributs[$nom] = []; |
|
| 377 | + } |
|
| 378 | + |
|
| 379 | + if (preg_match_all("/\s*(\S+)\s+(([(][^)]*[)])|(\S+))\s+([^\s']*)(\s*'[^']*')?/", $val, $r2, PREG_SET_ORDER)) { |
|
| 380 | + foreach ($r2 as $m2) { |
|
| 381 | + $v = preg_match('/^\w+$/', $m2[2]) ? $m2[2] |
|
| 382 | + : ('/^' . preg_replace('/\s+/', '', $m2[2]) . '$/'); |
|
| 383 | + $m21 = expanserEntite($m2[1], $dtc->macros); |
|
| 384 | + $m25 = expanserEntite($m2[5], $dtc->macros); |
|
| 385 | + $dtc->attributs[$nom][$m21] = [$v, $m25]; |
|
| 386 | + } |
|
| 387 | + } |
|
| 388 | + |
|
| 389 | + return $dtd; |
|
| 390 | 390 | } |
| 391 | 391 | |
| 392 | 392 | |
@@ -402,26 +402,26 @@ discard block |
||
| 402 | 402 | * @return string|array |
| 403 | 403 | **/ |
| 404 | 404 | function expanserEntite($val, $macros = []) { |
| 405 | - static $vu = []; |
|
| 406 | - if (!is_string($val)) { |
|
| 407 | - return $vu; |
|
| 408 | - } |
|
| 409 | - |
|
| 410 | - if (preg_match_all(_REGEXP_ENTITY_USE, $val, $r, PREG_SET_ORDER)) { |
|
| 411 | - foreach ($r as $m) { |
|
| 412 | - $ent = $m[1]; |
|
| 413 | - // il peut valoir "" |
|
| 414 | - if (!isset($macros[$ent])) { |
|
| 415 | - spip_log("Entite $ent inconnu"); |
|
| 416 | - } else { |
|
| 417 | - if (!isset($vu[$ent])) { |
|
| 418 | - $vu[$ent] = 0; |
|
| 419 | - } |
|
| 420 | - ++$vu[$ent]; |
|
| 421 | - $val = str_replace($m[0], $macros[$ent], $val); |
|
| 422 | - } |
|
| 423 | - } |
|
| 424 | - } |
|
| 425 | - |
|
| 426 | - return trim(preg_replace('/\s+/', ' ', $val)); |
|
| 405 | + static $vu = []; |
|
| 406 | + if (!is_string($val)) { |
|
| 407 | + return $vu; |
|
| 408 | + } |
|
| 409 | + |
|
| 410 | + if (preg_match_all(_REGEXP_ENTITY_USE, $val, $r, PREG_SET_ORDER)) { |
|
| 411 | + foreach ($r as $m) { |
|
| 412 | + $ent = $m[1]; |
|
| 413 | + // il peut valoir "" |
|
| 414 | + if (!isset($macros[$ent])) { |
|
| 415 | + spip_log("Entite $ent inconnu"); |
|
| 416 | + } else { |
|
| 417 | + if (!isset($vu[$ent])) { |
|
| 418 | + $vu[$ent] = 0; |
|
| 419 | + } |
|
| 420 | + ++$vu[$ent]; |
|
| 421 | + $val = str_replace($m[0], $macros[$ent], $val); |
|
| 422 | + } |
|
| 423 | + } |
|
| 424 | + } |
|
| 425 | + |
|
| 426 | + return trim(preg_replace('/\s+/', ' ', $val)); |
|
| 427 | 427 | } |
@@ -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 | } |
@@ -11,7 +11,7 @@ discard block |
||
| 11 | 11 | \***************************************************************************/ |
| 12 | 12 | |
| 13 | 13 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 14 | - return; |
|
| 14 | + return; |
|
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | /** |
@@ -25,9 +25,9 @@ discard block |
||
| 25 | 25 | * @return string |
| 26 | 26 | */ |
| 27 | 27 | function generer_nom_fichier_cache($contexte, $page) { |
| 28 | - $u = md5(var_export([$contexte, $page], true)); |
|
| 28 | + $u = md5(var_export([$contexte, $page], true)); |
|
| 29 | 29 | |
| 30 | - return $u . '.cache'; |
|
| 30 | + return $u . '.cache'; |
|
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | /** |
@@ -43,26 +43,26 @@ discard block |
||
| 43 | 43 | * @return string |
| 44 | 44 | */ |
| 45 | 45 | function cache_chemin_fichier($nom_cache, $ecrire = false) { |
| 46 | - static $l1, $l2; |
|
| 47 | - if (is_null($l1)) { |
|
| 48 | - $length = (defined('_CACHE_PROFONDEUR_STOCKAGE') ? min(8, max(_CACHE_PROFONDEUR_STOCKAGE, 2)) : 4); |
|
| 49 | - $l1 = intval(floor($length / 2)); |
|
| 50 | - $l2 = $length - $l1; |
|
| 51 | - } |
|
| 52 | - $d = substr($nom_cache, 0, $l1); |
|
| 53 | - $u = substr($nom_cache, $l1, $l2); |
|
| 54 | - |
|
| 55 | - if ($ecrire) { |
|
| 56 | - $rep = sous_repertoire(_DIR_CACHE, '', false, true); |
|
| 57 | - $rep = sous_repertoire($rep, 'calcul/', false, true); |
|
| 58 | - $rep = sous_repertoire($rep, $d, false, true); |
|
| 59 | - } |
|
| 60 | - else { |
|
| 61 | - // en lecture on essaye pas de creer les repertoires, on va au plus vite |
|
| 62 | - $rep = _DIR_CACHE . "calcul/$d/"; |
|
| 63 | - } |
|
| 64 | - |
|
| 65 | - return $rep . $u . '.cache'; |
|
| 46 | + static $l1, $l2; |
|
| 47 | + if (is_null($l1)) { |
|
| 48 | + $length = (defined('_CACHE_PROFONDEUR_STOCKAGE') ? min(8, max(_CACHE_PROFONDEUR_STOCKAGE, 2)) : 4); |
|
| 49 | + $l1 = intval(floor($length / 2)); |
|
| 50 | + $l2 = $length - $l1; |
|
| 51 | + } |
|
| 52 | + $d = substr($nom_cache, 0, $l1); |
|
| 53 | + $u = substr($nom_cache, $l1, $l2); |
|
| 54 | + |
|
| 55 | + if ($ecrire) { |
|
| 56 | + $rep = sous_repertoire(_DIR_CACHE, '', false, true); |
|
| 57 | + $rep = sous_repertoire($rep, 'calcul/', false, true); |
|
| 58 | + $rep = sous_repertoire($rep, $d, false, true); |
|
| 59 | + } |
|
| 60 | + else { |
|
| 61 | + // en lecture on essaye pas de creer les repertoires, on va au plus vite |
|
| 62 | + $rep = _DIR_CACHE . "calcul/$d/"; |
|
| 63 | + } |
|
| 64 | + |
|
| 65 | + return $rep . $u . '.cache'; |
|
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | /** |
@@ -73,7 +73,7 @@ discard block |
||
| 73 | 73 | * @return bool |
| 74 | 74 | */ |
| 75 | 75 | function ecrire_cache($nom_cache, $valeur) { |
| 76 | - return ecrire_fichier(cache_chemin_fichier($nom_cache, true), serialize(['nom_cache' => $nom_cache, 'valeur' => $valeur])); |
|
| 76 | + return ecrire_fichier(cache_chemin_fichier($nom_cache, true), serialize(['nom_cache' => $nom_cache, 'valeur' => $valeur])); |
|
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | /** |
@@ -83,38 +83,38 @@ discard block |
||
| 83 | 83 | * @return mixed |
| 84 | 84 | */ |
| 85 | 85 | function lire_cache($nom_cache) { |
| 86 | - $tmp = []; |
|
| 87 | - if ( |
|
| 88 | - file_exists($f = cache_chemin_fichier($nom_cache)) |
|
| 89 | - and lire_fichier($f, $tmp) |
|
| 90 | - and $tmp = unserialize($tmp) |
|
| 91 | - and $tmp['nom_cache'] == $nom_cache |
|
| 92 | - and isset($tmp['valeur']) |
|
| 93 | - ) { |
|
| 94 | - return $tmp['valeur']; |
|
| 95 | - } |
|
| 96 | - |
|
| 97 | - return false; |
|
| 86 | + $tmp = []; |
|
| 87 | + if ( |
|
| 88 | + file_exists($f = cache_chemin_fichier($nom_cache)) |
|
| 89 | + and lire_fichier($f, $tmp) |
|
| 90 | + and $tmp = unserialize($tmp) |
|
| 91 | + and $tmp['nom_cache'] == $nom_cache |
|
| 92 | + and isset($tmp['valeur']) |
|
| 93 | + ) { |
|
| 94 | + return $tmp['valeur']; |
|
| 95 | + } |
|
| 96 | + |
|
| 97 | + return false; |
|
| 98 | 98 | } |
| 99 | 99 | |
| 100 | 100 | // Parano : on signe le cache, afin d'interdire un hack d'injection |
| 101 | 101 | // dans notre memcache |
| 102 | 102 | function cache_signature(&$page) { |
| 103 | - if (!isset($GLOBALS['meta']['cache_signature'])) { |
|
| 104 | - include_spip('inc/acces'); |
|
| 105 | - include_spip('auth/sha256.inc'); |
|
| 106 | - ecrire_meta( |
|
| 107 | - 'cache_signature', |
|
| 108 | - spip_sha256( |
|
| 109 | - $_SERVER['DOCUMENT_ROOT'] |
|
| 110 | - . ($_SERVER['SERVER_SIGNATURE'] ?? '') |
|
| 111 | - . creer_uniqid() |
|
| 112 | - ), |
|
| 113 | - 'non' |
|
| 114 | - ); |
|
| 115 | - } |
|
| 116 | - |
|
| 117 | - return crc32($GLOBALS['meta']['cache_signature'] . $page['texte']); |
|
| 103 | + if (!isset($GLOBALS['meta']['cache_signature'])) { |
|
| 104 | + include_spip('inc/acces'); |
|
| 105 | + include_spip('auth/sha256.inc'); |
|
| 106 | + ecrire_meta( |
|
| 107 | + 'cache_signature', |
|
| 108 | + spip_sha256( |
|
| 109 | + $_SERVER['DOCUMENT_ROOT'] |
|
| 110 | + . ($_SERVER['SERVER_SIGNATURE'] ?? '') |
|
| 111 | + . creer_uniqid() |
|
| 112 | + ), |
|
| 113 | + 'non' |
|
| 114 | + ); |
|
| 115 | + } |
|
| 116 | + |
|
| 117 | + return crc32($GLOBALS['meta']['cache_signature'] . $page['texte']); |
|
| 118 | 118 | } |
| 119 | 119 | |
| 120 | 120 | /** |
@@ -127,14 +127,14 @@ discard block |
||
| 127 | 127 | * @return array |
| 128 | 128 | */ |
| 129 | 129 | function gzip_page($page) { |
| 130 | - if (function_exists('gzcompress') and strlen($page['texte']) > 16 * 1024) { |
|
| 131 | - $page['gz'] = true; |
|
| 132 | - $page['texte'] = gzcompress($page['texte']); |
|
| 133 | - } else { |
|
| 134 | - $page['gz'] = false; |
|
| 135 | - } |
|
| 136 | - |
|
| 137 | - return $page; |
|
| 130 | + if (function_exists('gzcompress') and strlen($page['texte']) > 16 * 1024) { |
|
| 131 | + $page['gz'] = true; |
|
| 132 | + $page['texte'] = gzcompress($page['texte']); |
|
| 133 | + } else { |
|
| 134 | + $page['gz'] = false; |
|
| 135 | + } |
|
| 136 | + |
|
| 137 | + return $page; |
|
| 138 | 138 | } |
| 139 | 139 | |
| 140 | 140 | /** |
@@ -147,10 +147,10 @@ discard block |
||
| 147 | 147 | * @return void |
| 148 | 148 | */ |
| 149 | 149 | function gunzip_page(&$page) { |
| 150 | - if ($page['gz']) { |
|
| 151 | - $page['texte'] = gzuncompress($page['texte']); |
|
| 152 | - $page['gz'] = false; // ne pas gzuncompress deux fois une meme page |
|
| 153 | - } |
|
| 150 | + if ($page['gz']) { |
|
| 151 | + $page['texte'] = gzuncompress($page['texte']); |
|
| 152 | + $page['gz'] = false; // ne pas gzuncompress deux fois une meme page |
|
| 153 | + } |
|
| 154 | 154 | } |
| 155 | 155 | |
| 156 | 156 | /** |
@@ -165,72 +165,72 @@ discard block |
||
| 165 | 165 | * -1 si il faut calculer sans stocker en cache |
| 166 | 166 | */ |
| 167 | 167 | function cache_valide(&$page, $date) { |
| 168 | - $now = $_SERVER['REQUEST_TIME']; |
|
| 169 | - |
|
| 170 | - // Apparition d'un nouvel article post-date ? |
|
| 171 | - if ( |
|
| 172 | - isset($GLOBALS['meta']['post_dates']) |
|
| 173 | - and $GLOBALS['meta']['post_dates'] == 'non' |
|
| 174 | - and isset($GLOBALS['meta']['date_prochain_postdate']) |
|
| 175 | - and $now > $GLOBALS['meta']['date_prochain_postdate'] |
|
| 176 | - ) { |
|
| 177 | - spip_log('Un article post-date invalide le cache'); |
|
| 178 | - include_spip('inc/rubriques'); |
|
| 179 | - calculer_prochain_postdate(true); |
|
| 180 | - } |
|
| 181 | - |
|
| 182 | - if (defined('_VAR_NOCACHE') and _VAR_NOCACHE) { |
|
| 183 | - return -1; |
|
| 184 | - } |
|
| 185 | - if (isset($GLOBALS['meta']['cache_inhib']) and $_SERVER['REQUEST_TIME'] < $GLOBALS['meta']['cache_inhib']) { |
|
| 186 | - return -1; |
|
| 187 | - } |
|
| 188 | - if (defined('_NO_CACHE')) { |
|
| 189 | - return (_NO_CACHE == 0 and !isset($page['texte'])) ? 1 : _NO_CACHE; |
|
| 190 | - } |
|
| 191 | - |
|
| 192 | - // pas de cache ? on le met a jour, sauf pour les bots (on leur calcule la page sans mise en cache) |
|
| 193 | - if (!$page or !isset($page['texte']) or !isset($page['entetes']['X-Spip-Cache'])) { |
|
| 194 | - return _IS_BOT ? -1 : 1; |
|
| 195 | - } |
|
| 196 | - |
|
| 197 | - // controle de la signature |
|
| 198 | - if ($page['sig'] !== cache_signature($page)) { |
|
| 199 | - return _IS_BOT ? -1 : 1; |
|
| 200 | - } |
|
| 201 | - |
|
| 202 | - // #CACHE{n,statique} => on n'invalide pas avec derniere_modif |
|
| 203 | - // cf. ecrire/public/balises.php, balise_CACHE_dist() |
|
| 204 | - if (!isset($page['entetes']['X-Spip-Statique']) or $page['entetes']['X-Spip-Statique'] !== 'oui') { |
|
| 205 | - // Cache invalide par la meta 'derniere_modif' |
|
| 206 | - // sauf pour les bots, qui utilisent toujours le cache |
|
| 207 | - if ( |
|
| 208 | - !_IS_BOT |
|
| 209 | - and $GLOBALS['derniere_modif_invalide'] |
|
| 210 | - and isset($GLOBALS['meta']['derniere_modif']) |
|
| 211 | - and $date < $GLOBALS['meta']['derniere_modif'] |
|
| 212 | - ) { |
|
| 213 | - return 1; |
|
| 214 | - } |
|
| 215 | - } |
|
| 216 | - |
|
| 217 | - // Sinon comparer l'age du fichier a sa duree de cache |
|
| 218 | - $duree = intval($page['entetes']['X-Spip-Cache']); |
|
| 219 | - $cache_mark = ($GLOBALS['meta']['cache_mark'] ?? 0); |
|
| 220 | - if ($duree == 0) { #CACHE{0} |
|
| 221 | - return -1; |
|
| 222 | - } // sauf pour les bots, qui utilisent toujours le cache |
|
| 223 | - else { |
|
| 224 | - if ( |
|
| 225 | - (!_IS_BOT and $date + $duree < $now) |
|
| 226 | - # le cache est anterieur a la derniere purge : l'ignorer, meme pour les bots |
|
| 227 | - or $date < $cache_mark |
|
| 228 | - ) { |
|
| 229 | - return _IS_BOT ? -1 : 1; |
|
| 230 | - } else { |
|
| 231 | - return 0; |
|
| 232 | - } |
|
| 233 | - } |
|
| 168 | + $now = $_SERVER['REQUEST_TIME']; |
|
| 169 | + |
|
| 170 | + // Apparition d'un nouvel article post-date ? |
|
| 171 | + if ( |
|
| 172 | + isset($GLOBALS['meta']['post_dates']) |
|
| 173 | + and $GLOBALS['meta']['post_dates'] == 'non' |
|
| 174 | + and isset($GLOBALS['meta']['date_prochain_postdate']) |
|
| 175 | + and $now > $GLOBALS['meta']['date_prochain_postdate'] |
|
| 176 | + ) { |
|
| 177 | + spip_log('Un article post-date invalide le cache'); |
|
| 178 | + include_spip('inc/rubriques'); |
|
| 179 | + calculer_prochain_postdate(true); |
|
| 180 | + } |
|
| 181 | + |
|
| 182 | + if (defined('_VAR_NOCACHE') and _VAR_NOCACHE) { |
|
| 183 | + return -1; |
|
| 184 | + } |
|
| 185 | + if (isset($GLOBALS['meta']['cache_inhib']) and $_SERVER['REQUEST_TIME'] < $GLOBALS['meta']['cache_inhib']) { |
|
| 186 | + return -1; |
|
| 187 | + } |
|
| 188 | + if (defined('_NO_CACHE')) { |
|
| 189 | + return (_NO_CACHE == 0 and !isset($page['texte'])) ? 1 : _NO_CACHE; |
|
| 190 | + } |
|
| 191 | + |
|
| 192 | + // pas de cache ? on le met a jour, sauf pour les bots (on leur calcule la page sans mise en cache) |
|
| 193 | + if (!$page or !isset($page['texte']) or !isset($page['entetes']['X-Spip-Cache'])) { |
|
| 194 | + return _IS_BOT ? -1 : 1; |
|
| 195 | + } |
|
| 196 | + |
|
| 197 | + // controle de la signature |
|
| 198 | + if ($page['sig'] !== cache_signature($page)) { |
|
| 199 | + return _IS_BOT ? -1 : 1; |
|
| 200 | + } |
|
| 201 | + |
|
| 202 | + // #CACHE{n,statique} => on n'invalide pas avec derniere_modif |
|
| 203 | + // cf. ecrire/public/balises.php, balise_CACHE_dist() |
|
| 204 | + if (!isset($page['entetes']['X-Spip-Statique']) or $page['entetes']['X-Spip-Statique'] !== 'oui') { |
|
| 205 | + // Cache invalide par la meta 'derniere_modif' |
|
| 206 | + // sauf pour les bots, qui utilisent toujours le cache |
|
| 207 | + if ( |
|
| 208 | + !_IS_BOT |
|
| 209 | + and $GLOBALS['derniere_modif_invalide'] |
|
| 210 | + and isset($GLOBALS['meta']['derniere_modif']) |
|
| 211 | + and $date < $GLOBALS['meta']['derniere_modif'] |
|
| 212 | + ) { |
|
| 213 | + return 1; |
|
| 214 | + } |
|
| 215 | + } |
|
| 216 | + |
|
| 217 | + // Sinon comparer l'age du fichier a sa duree de cache |
|
| 218 | + $duree = intval($page['entetes']['X-Spip-Cache']); |
|
| 219 | + $cache_mark = ($GLOBALS['meta']['cache_mark'] ?? 0); |
|
| 220 | + if ($duree == 0) { #CACHE{0} |
|
| 221 | + return -1; |
|
| 222 | + } // sauf pour les bots, qui utilisent toujours le cache |
|
| 223 | + else { |
|
| 224 | + if ( |
|
| 225 | + (!_IS_BOT and $date + $duree < $now) |
|
| 226 | + # le cache est anterieur a la derniere purge : l'ignorer, meme pour les bots |
|
| 227 | + or $date < $cache_mark |
|
| 228 | + ) { |
|
| 229 | + return _IS_BOT ? -1 : 1; |
|
| 230 | + } else { |
|
| 231 | + return 0; |
|
| 232 | + } |
|
| 233 | + } |
|
| 234 | 234 | } |
| 235 | 235 | |
| 236 | 236 | /** |
@@ -243,59 +243,59 @@ discard block |
||
| 243 | 243 | */ |
| 244 | 244 | function creer_cache(&$page, &$chemin_cache) { |
| 245 | 245 | |
| 246 | - // Ne rien faire si on est en preview, debug, ou si une erreur |
|
| 247 | - // grave s'est presentee (compilation du squelette, MySQL, etc) |
|
| 248 | - // le cas var_nocache ne devrait jamais arriver ici (securite) |
|
| 249 | - // le cas spip_interdire_cache correspond a une ereur SQL grave non anticipable |
|
| 250 | - if ( |
|
| 251 | - (defined('_VAR_NOCACHE') and _VAR_NOCACHE) |
|
| 252 | - or defined('spip_interdire_cache') |
|
| 253 | - ) { |
|
| 254 | - return; |
|
| 255 | - } |
|
| 256 | - |
|
| 257 | - // Si la page c1234 a un invalideur de session 'zz', sauver dans |
|
| 258 | - // 'tmp/cache/MD5(chemin_cache)_zz' |
|
| 259 | - if ( |
|
| 260 | - isset($page['invalideurs']) |
|
| 261 | - and isset($page['invalideurs']['session']) |
|
| 262 | - ) { |
|
| 263 | - // on verifie que le contenu du chemin cache indique seulement |
|
| 264 | - // "cache sessionne" ; sa date indique la date de validite |
|
| 265 | - // des caches sessionnes |
|
| 266 | - if (!$tmp = lire_cache($chemin_cache)) { |
|
| 267 | - spip_log('Creation cache sessionne ' . $chemin_cache); |
|
| 268 | - $tmp = [ |
|
| 269 | - 'invalideurs' => ['session' => ''], |
|
| 270 | - 'lastmodified' => $_SERVER['REQUEST_TIME'] |
|
| 271 | - ]; |
|
| 272 | - ecrire_cache($chemin_cache, $tmp); |
|
| 273 | - } |
|
| 274 | - $chemin_cache = generer_nom_fichier_cache( |
|
| 275 | - ['chemin_cache' => $chemin_cache], |
|
| 276 | - ['session' => $page['invalideurs']['session']] |
|
| 277 | - ); |
|
| 278 | - } |
|
| 279 | - |
|
| 280 | - // ajouter la date de production dans le cache lui meme |
|
| 281 | - // (qui contient deja sa duree de validite) |
|
| 282 | - $page['lastmodified'] = $_SERVER['REQUEST_TIME']; |
|
| 283 | - |
|
| 284 | - // compresser le contenu si besoin |
|
| 285 | - $pagez = gzip_page($page); |
|
| 286 | - |
|
| 287 | - // signer le contenu |
|
| 288 | - $pagez['sig'] = cache_signature($pagez); |
|
| 289 | - |
|
| 290 | - // l'enregistrer, compresse ou non... |
|
| 291 | - $ok = ecrire_cache($chemin_cache, $pagez); |
|
| 292 | - |
|
| 293 | - spip_log((_IS_BOT ? 'Bot:' : '') . "Creation du cache $chemin_cache pour " |
|
| 294 | - . $page['entetes']['X-Spip-Cache'] . ' secondes' . ($ok ? '' : ' (erreur!)'), _LOG_INFO); |
|
| 295 | - |
|
| 296 | - // Inserer ses invalideurs |
|
| 297 | - include_spip('inc/invalideur'); |
|
| 298 | - maj_invalideurs($chemin_cache, $page); |
|
| 246 | + // Ne rien faire si on est en preview, debug, ou si une erreur |
|
| 247 | + // grave s'est presentee (compilation du squelette, MySQL, etc) |
|
| 248 | + // le cas var_nocache ne devrait jamais arriver ici (securite) |
|
| 249 | + // le cas spip_interdire_cache correspond a une ereur SQL grave non anticipable |
|
| 250 | + if ( |
|
| 251 | + (defined('_VAR_NOCACHE') and _VAR_NOCACHE) |
|
| 252 | + or defined('spip_interdire_cache') |
|
| 253 | + ) { |
|
| 254 | + return; |
|
| 255 | + } |
|
| 256 | + |
|
| 257 | + // Si la page c1234 a un invalideur de session 'zz', sauver dans |
|
| 258 | + // 'tmp/cache/MD5(chemin_cache)_zz' |
|
| 259 | + if ( |
|
| 260 | + isset($page['invalideurs']) |
|
| 261 | + and isset($page['invalideurs']['session']) |
|
| 262 | + ) { |
|
| 263 | + // on verifie que le contenu du chemin cache indique seulement |
|
| 264 | + // "cache sessionne" ; sa date indique la date de validite |
|
| 265 | + // des caches sessionnes |
|
| 266 | + if (!$tmp = lire_cache($chemin_cache)) { |
|
| 267 | + spip_log('Creation cache sessionne ' . $chemin_cache); |
|
| 268 | + $tmp = [ |
|
| 269 | + 'invalideurs' => ['session' => ''], |
|
| 270 | + 'lastmodified' => $_SERVER['REQUEST_TIME'] |
|
| 271 | + ]; |
|
| 272 | + ecrire_cache($chemin_cache, $tmp); |
|
| 273 | + } |
|
| 274 | + $chemin_cache = generer_nom_fichier_cache( |
|
| 275 | + ['chemin_cache' => $chemin_cache], |
|
| 276 | + ['session' => $page['invalideurs']['session']] |
|
| 277 | + ); |
|
| 278 | + } |
|
| 279 | + |
|
| 280 | + // ajouter la date de production dans le cache lui meme |
|
| 281 | + // (qui contient deja sa duree de validite) |
|
| 282 | + $page['lastmodified'] = $_SERVER['REQUEST_TIME']; |
|
| 283 | + |
|
| 284 | + // compresser le contenu si besoin |
|
| 285 | + $pagez = gzip_page($page); |
|
| 286 | + |
|
| 287 | + // signer le contenu |
|
| 288 | + $pagez['sig'] = cache_signature($pagez); |
|
| 289 | + |
|
| 290 | + // l'enregistrer, compresse ou non... |
|
| 291 | + $ok = ecrire_cache($chemin_cache, $pagez); |
|
| 292 | + |
|
| 293 | + spip_log((_IS_BOT ? 'Bot:' : '') . "Creation du cache $chemin_cache pour " |
|
| 294 | + . $page['entetes']['X-Spip-Cache'] . ' secondes' . ($ok ? '' : ' (erreur!)'), _LOG_INFO); |
|
| 295 | + |
|
| 296 | + // Inserer ses invalideurs |
|
| 297 | + include_spip('inc/invalideur'); |
|
| 298 | + maj_invalideurs($chemin_cache, $page); |
|
| 299 | 299 | } |
| 300 | 300 | |
| 301 | 301 | |
@@ -308,15 +308,15 @@ discard block |
||
| 308 | 308 | * @return void |
| 309 | 309 | */ |
| 310 | 310 | function nettoyer_petit_cache($prefix, $duree = 300) { |
| 311 | - // determiner le repertoire a purger : 'tmp/CACHE/rech/' |
|
| 312 | - $dircache = sous_repertoire(_DIR_CACHE, $prefix); |
|
| 313 | - if (spip_touch($dircache . 'purger_' . $prefix, $duree, true)) { |
|
| 314 | - foreach (preg_files($dircache, '[.]txt$') as $f) { |
|
| 315 | - if ($_SERVER['REQUEST_TIME'] - (@file_exists($f) ? @filemtime($f) : 0) > $duree) { |
|
| 316 | - spip_unlink($f); |
|
| 317 | - } |
|
| 318 | - } |
|
| 319 | - } |
|
| 311 | + // determiner le repertoire a purger : 'tmp/CACHE/rech/' |
|
| 312 | + $dircache = sous_repertoire(_DIR_CACHE, $prefix); |
|
| 313 | + if (spip_touch($dircache . 'purger_' . $prefix, $duree, true)) { |
|
| 314 | + foreach (preg_files($dircache, '[.]txt$') as $f) { |
|
| 315 | + if ($_SERVER['REQUEST_TIME'] - (@file_exists($f) ? @filemtime($f) : 0) > $duree) { |
|
| 316 | + spip_unlink($f); |
|
| 317 | + } |
|
| 318 | + } |
|
| 319 | + } |
|
| 320 | 320 | } |
| 321 | 321 | |
| 322 | 322 | |
@@ -344,133 +344,133 @@ discard block |
||
| 344 | 344 | */ |
| 345 | 345 | function public_cacher_dist($contexte, &$use_cache, &$chemin_cache, &$page, &$lastmodified) { |
| 346 | 346 | |
| 347 | - # fonction de cache minimale : dire "non on ne met rien en cache" |
|
| 348 | - # $use_cache = -1; return; |
|
| 349 | - |
|
| 350 | - // Second appel, destine a l'enregistrement du cache sur le disque |
|
| 351 | - if (isset($chemin_cache)) { |
|
| 352 | - return creer_cache($page, $chemin_cache); |
|
| 353 | - } |
|
| 354 | - |
|
| 355 | - // Toute la suite correspond au premier appel |
|
| 356 | - $contexte_implicite = $page['contexte_implicite']; |
|
| 357 | - |
|
| 358 | - // Cas ignorant le cache car completement dynamique |
|
| 359 | - if ( |
|
| 360 | - (!empty($_SERVER['REQUEST_METHOD']) and $_SERVER['REQUEST_METHOD'] === 'POST') |
|
| 361 | - or _request('connect') |
|
| 362 | - ) { |
|
| 363 | - $use_cache = -1; |
|
| 364 | - $lastmodified = 0; |
|
| 365 | - $chemin_cache = ''; |
|
| 366 | - $page = []; |
|
| 367 | - |
|
| 368 | - return; |
|
| 369 | - } |
|
| 370 | - |
|
| 371 | - // Controler l'existence d'un cache nous correspondant |
|
| 372 | - $chemin_cache = generer_nom_fichier_cache($contexte, $page); |
|
| 373 | - $lastmodified = 0; |
|
| 374 | - |
|
| 375 | - // charger le cache s'il existe (et si il a bien le bon hash = anticollision) |
|
| 376 | - if (!$page = lire_cache($chemin_cache)) { |
|
| 377 | - $page = []; |
|
| 378 | - } |
|
| 379 | - |
|
| 380 | - // s'il est sessionne, charger celui correspondant a notre session |
|
| 381 | - if ( |
|
| 382 | - isset($page['invalideurs']) |
|
| 383 | - and isset($page['invalideurs']['session']) |
|
| 384 | - ) { |
|
| 385 | - $chemin_cache_session = generer_nom_fichier_cache( |
|
| 386 | - ['chemin_cache' => $chemin_cache], |
|
| 387 | - ['session' => spip_session()] |
|
| 388 | - ); |
|
| 389 | - if ( |
|
| 390 | - $page_session = lire_cache($chemin_cache_session) |
|
| 391 | - and $page_session['lastmodified'] >= $page['lastmodified'] |
|
| 392 | - ) { |
|
| 393 | - $page = $page_session; |
|
| 394 | - } else { |
|
| 395 | - $page = []; |
|
| 396 | - } |
|
| 397 | - } |
|
| 398 | - |
|
| 399 | - |
|
| 400 | - // Faut-il effacer des pages invalidees (en particulier ce cache-ci) ? |
|
| 401 | - if (isset($GLOBALS['meta']['invalider'])) { |
|
| 402 | - // ne le faire que si la base est disponible |
|
| 403 | - if (spip_connect()) { |
|
| 404 | - include_spip('inc/invalideur'); |
|
| 405 | - retire_caches($chemin_cache); # API invalideur inutile |
|
| 406 | - supprimer_fichier(_DIR_CACHE . $chemin_cache); |
|
| 407 | - if (isset($chemin_cache_session) and $chemin_cache_session) { |
|
| 408 | - supprimer_fichier(_DIR_CACHE . $chemin_cache_session); |
|
| 409 | - } |
|
| 410 | - } |
|
| 411 | - } |
|
| 412 | - |
|
| 413 | - // Si un calcul, recalcul [ou preview, mais c'est recalcul] est demande, |
|
| 414 | - // on supprime le cache |
|
| 415 | - if ( |
|
| 416 | - defined('_VAR_MODE') && |
|
| 417 | - _VAR_MODE && |
|
| 418 | - (isset($_COOKIE['spip_session']) || |
|
| 419 | - isset($_COOKIE['spip_admin']) || |
|
| 420 | - @file_exists(_ACCESS_FILE_NAME)) |
|
| 421 | - ) { |
|
| 422 | - $page = ['contexte_implicite' => $contexte_implicite]; // ignorer le cache deja lu |
|
| 423 | - include_spip('inc/invalideur'); |
|
| 424 | - retire_caches($chemin_cache); # API invalideur inutile |
|
| 425 | - supprimer_fichier(_DIR_CACHE . $chemin_cache); |
|
| 426 | - if (isset($chemin_cache_session) and $chemin_cache_session) { |
|
| 427 | - supprimer_fichier(_DIR_CACHE . $chemin_cache_session); |
|
| 428 | - } |
|
| 429 | - } |
|
| 430 | - |
|
| 431 | - // $delais par defaut |
|
| 432 | - // pour toutes les pages sans #CACHE{} hors modeles/ et espace privé |
|
| 433 | - // qui sont a cache nul par defaut |
|
| 434 | - if (!isset($GLOBALS['delais'])) { |
|
| 435 | - if (!defined('_DUREE_CACHE_DEFAUT')) { |
|
| 436 | - define('_DUREE_CACHE_DEFAUT', 24 * 3600); |
|
| 437 | - } |
|
| 438 | - $GLOBALS['delais'] = _DUREE_CACHE_DEFAUT; |
|
| 439 | - } |
|
| 440 | - |
|
| 441 | - // determiner la validite de la page |
|
| 442 | - if ($page) { |
|
| 443 | - $use_cache = cache_valide($page, $page['lastmodified'] ?? 0); |
|
| 444 | - // le contexte implicite n'est pas stocke dans le cache, mais il y a equivalence |
|
| 445 | - // par le nom du cache. On le reinjecte donc ici pour utilisation eventuelle au calcul |
|
| 446 | - $page['contexte_implicite'] = $contexte_implicite; |
|
| 447 | - if (!$use_cache) { |
|
| 448 | - // $page est un cache utilisable |
|
| 449 | - gunzip_page($page); |
|
| 450 | - |
|
| 451 | - return; |
|
| 452 | - } |
|
| 453 | - } else { |
|
| 454 | - $page = ['contexte_implicite' => $contexte_implicite]; |
|
| 455 | - $use_cache = cache_valide($page, 0); // fichier cache absent : provoque le calcul |
|
| 456 | - } |
|
| 457 | - |
|
| 458 | - // Si pas valide mais pas de connexion a la base, le garder quand meme |
|
| 459 | - if (!spip_connect()) { |
|
| 460 | - if (isset($page['texte'])) { |
|
| 461 | - gunzip_page($page); |
|
| 462 | - $use_cache = 0; |
|
| 463 | - } else { |
|
| 464 | - spip_log("Erreur base de donnees, impossible utiliser $chemin_cache"); |
|
| 465 | - include_spip('inc/minipres'); |
|
| 466 | - |
|
| 467 | - return minipres(_T('info_travaux_titre'), _T('titre_probleme_technique'), ['status' => 503]); |
|
| 468 | - } |
|
| 469 | - } |
|
| 470 | - |
|
| 471 | - if ($use_cache < 0) { |
|
| 472 | - $chemin_cache = ''; |
|
| 473 | - } |
|
| 474 | - |
|
| 475 | - return; |
|
| 347 | + # fonction de cache minimale : dire "non on ne met rien en cache" |
|
| 348 | + # $use_cache = -1; return; |
|
| 349 | + |
|
| 350 | + // Second appel, destine a l'enregistrement du cache sur le disque |
|
| 351 | + if (isset($chemin_cache)) { |
|
| 352 | + return creer_cache($page, $chemin_cache); |
|
| 353 | + } |
|
| 354 | + |
|
| 355 | + // Toute la suite correspond au premier appel |
|
| 356 | + $contexte_implicite = $page['contexte_implicite']; |
|
| 357 | + |
|
| 358 | + // Cas ignorant le cache car completement dynamique |
|
| 359 | + if ( |
|
| 360 | + (!empty($_SERVER['REQUEST_METHOD']) and $_SERVER['REQUEST_METHOD'] === 'POST') |
|
| 361 | + or _request('connect') |
|
| 362 | + ) { |
|
| 363 | + $use_cache = -1; |
|
| 364 | + $lastmodified = 0; |
|
| 365 | + $chemin_cache = ''; |
|
| 366 | + $page = []; |
|
| 367 | + |
|
| 368 | + return; |
|
| 369 | + } |
|
| 370 | + |
|
| 371 | + // Controler l'existence d'un cache nous correspondant |
|
| 372 | + $chemin_cache = generer_nom_fichier_cache($contexte, $page); |
|
| 373 | + $lastmodified = 0; |
|
| 374 | + |
|
| 375 | + // charger le cache s'il existe (et si il a bien le bon hash = anticollision) |
|
| 376 | + if (!$page = lire_cache($chemin_cache)) { |
|
| 377 | + $page = []; |
|
| 378 | + } |
|
| 379 | + |
|
| 380 | + // s'il est sessionne, charger celui correspondant a notre session |
|
| 381 | + if ( |
|
| 382 | + isset($page['invalideurs']) |
|
| 383 | + and isset($page['invalideurs']['session']) |
|
| 384 | + ) { |
|
| 385 | + $chemin_cache_session = generer_nom_fichier_cache( |
|
| 386 | + ['chemin_cache' => $chemin_cache], |
|
| 387 | + ['session' => spip_session()] |
|
| 388 | + ); |
|
| 389 | + if ( |
|
| 390 | + $page_session = lire_cache($chemin_cache_session) |
|
| 391 | + and $page_session['lastmodified'] >= $page['lastmodified'] |
|
| 392 | + ) { |
|
| 393 | + $page = $page_session; |
|
| 394 | + } else { |
|
| 395 | + $page = []; |
|
| 396 | + } |
|
| 397 | + } |
|
| 398 | + |
|
| 399 | + |
|
| 400 | + // Faut-il effacer des pages invalidees (en particulier ce cache-ci) ? |
|
| 401 | + if (isset($GLOBALS['meta']['invalider'])) { |
|
| 402 | + // ne le faire que si la base est disponible |
|
| 403 | + if (spip_connect()) { |
|
| 404 | + include_spip('inc/invalideur'); |
|
| 405 | + retire_caches($chemin_cache); # API invalideur inutile |
|
| 406 | + supprimer_fichier(_DIR_CACHE . $chemin_cache); |
|
| 407 | + if (isset($chemin_cache_session) and $chemin_cache_session) { |
|
| 408 | + supprimer_fichier(_DIR_CACHE . $chemin_cache_session); |
|
| 409 | + } |
|
| 410 | + } |
|
| 411 | + } |
|
| 412 | + |
|
| 413 | + // Si un calcul, recalcul [ou preview, mais c'est recalcul] est demande, |
|
| 414 | + // on supprime le cache |
|
| 415 | + if ( |
|
| 416 | + defined('_VAR_MODE') && |
|
| 417 | + _VAR_MODE && |
|
| 418 | + (isset($_COOKIE['spip_session']) || |
|
| 419 | + isset($_COOKIE['spip_admin']) || |
|
| 420 | + @file_exists(_ACCESS_FILE_NAME)) |
|
| 421 | + ) { |
|
| 422 | + $page = ['contexte_implicite' => $contexte_implicite]; // ignorer le cache deja lu |
|
| 423 | + include_spip('inc/invalideur'); |
|
| 424 | + retire_caches($chemin_cache); # API invalideur inutile |
|
| 425 | + supprimer_fichier(_DIR_CACHE . $chemin_cache); |
|
| 426 | + if (isset($chemin_cache_session) and $chemin_cache_session) { |
|
| 427 | + supprimer_fichier(_DIR_CACHE . $chemin_cache_session); |
|
| 428 | + } |
|
| 429 | + } |
|
| 430 | + |
|
| 431 | + // $delais par defaut |
|
| 432 | + // pour toutes les pages sans #CACHE{} hors modeles/ et espace privé |
|
| 433 | + // qui sont a cache nul par defaut |
|
| 434 | + if (!isset($GLOBALS['delais'])) { |
|
| 435 | + if (!defined('_DUREE_CACHE_DEFAUT')) { |
|
| 436 | + define('_DUREE_CACHE_DEFAUT', 24 * 3600); |
|
| 437 | + } |
|
| 438 | + $GLOBALS['delais'] = _DUREE_CACHE_DEFAUT; |
|
| 439 | + } |
|
| 440 | + |
|
| 441 | + // determiner la validite de la page |
|
| 442 | + if ($page) { |
|
| 443 | + $use_cache = cache_valide($page, $page['lastmodified'] ?? 0); |
|
| 444 | + // le contexte implicite n'est pas stocke dans le cache, mais il y a equivalence |
|
| 445 | + // par le nom du cache. On le reinjecte donc ici pour utilisation eventuelle au calcul |
|
| 446 | + $page['contexte_implicite'] = $contexte_implicite; |
|
| 447 | + if (!$use_cache) { |
|
| 448 | + // $page est un cache utilisable |
|
| 449 | + gunzip_page($page); |
|
| 450 | + |
|
| 451 | + return; |
|
| 452 | + } |
|
| 453 | + } else { |
|
| 454 | + $page = ['contexte_implicite' => $contexte_implicite]; |
|
| 455 | + $use_cache = cache_valide($page, 0); // fichier cache absent : provoque le calcul |
|
| 456 | + } |
|
| 457 | + |
|
| 458 | + // Si pas valide mais pas de connexion a la base, le garder quand meme |
|
| 459 | + if (!spip_connect()) { |
|
| 460 | + if (isset($page['texte'])) { |
|
| 461 | + gunzip_page($page); |
|
| 462 | + $use_cache = 0; |
|
| 463 | + } else { |
|
| 464 | + spip_log("Erreur base de donnees, impossible utiliser $chemin_cache"); |
|
| 465 | + include_spip('inc/minipres'); |
|
| 466 | + |
|
| 467 | + return minipres(_T('info_travaux_titre'), _T('titre_probleme_technique'), ['status' => 503]); |
|
| 468 | + } |
|
| 469 | + } |
|
| 470 | + |
|
| 471 | + if ($use_cache < 0) { |
|
| 472 | + $chemin_cache = ''; |
|
| 473 | + } |
|
| 474 | + |
|
| 475 | + return; |
|
| 476 | 476 | } |
@@ -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,98 +394,98 @@ 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 (is_array($page['entetes'])) { |
|
| 415 | - // mais pas toutes |
|
| 416 | - unset($page['entetes']['X-Spip-Cache']); |
|
| 417 | - unset($page['entetes']['Content-Type']); |
|
| 418 | - if (isset($GLOBALS['page']) and is_array($GLOBALS['page'])) { |
|
| 419 | - if (!is_array($GLOBALS['page']['entetes'])) { |
|
| 420 | - $GLOBALS['page']['entetes'] = []; |
|
| 421 | - } |
|
| 422 | - $GLOBALS['page']['entetes'] = |
|
| 423 | - array_merge($GLOBALS['page']['entetes'], $page['entetes']); |
|
| 424 | - } |
|
| 425 | - } |
|
| 426 | - // _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines |
|
| 427 | - if ( |
|
| 428 | - isset($page['contexte']['_pipelines']) |
|
| 429 | - and is_array($page['contexte']['_pipelines']) |
|
| 430 | - and count($page['contexte']['_pipelines']) |
|
| 431 | - ) { |
|
| 432 | - foreach ($page['contexte']['_pipelines'] as $pipe => $args) { |
|
| 433 | - $args['contexte'] = $page['contexte']; |
|
| 434 | - unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul |
|
| 435 | - $texte = pipeline( |
|
| 436 | - $pipe, |
|
| 437 | - [ |
|
| 438 | - 'data' => $texte, |
|
| 439 | - 'args' => $args |
|
| 440 | - ] |
|
| 441 | - ); |
|
| 442 | - } |
|
| 443 | - } |
|
| 444 | - } |
|
| 445 | - |
|
| 446 | - if (defined('_VAR_MODE') and _VAR_MODE == 'debug') { |
|
| 447 | - // compatibilite : avant on donnait le numero de ligne ou rien. |
|
| 448 | - $ligne = intval($contexte_compil[3] ?? $contexte_compil); |
|
| 449 | - $GLOBALS['debug_objets']['resultat'][$ligne] = $texte; |
|
| 450 | - } |
|
| 451 | - if ($echo) { |
|
| 452 | - echo $texte; |
|
| 453 | - } else { |
|
| 454 | - return $texte; |
|
| 455 | - } |
|
| 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 (is_array($page['entetes'])) { |
|
| 415 | + // mais pas toutes |
|
| 416 | + unset($page['entetes']['X-Spip-Cache']); |
|
| 417 | + unset($page['entetes']['Content-Type']); |
|
| 418 | + if (isset($GLOBALS['page']) and is_array($GLOBALS['page'])) { |
|
| 419 | + if (!is_array($GLOBALS['page']['entetes'])) { |
|
| 420 | + $GLOBALS['page']['entetes'] = []; |
|
| 421 | + } |
|
| 422 | + $GLOBALS['page']['entetes'] = |
|
| 423 | + array_merge($GLOBALS['page']['entetes'], $page['entetes']); |
|
| 424 | + } |
|
| 425 | + } |
|
| 426 | + // _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines |
|
| 427 | + if ( |
|
| 428 | + isset($page['contexte']['_pipelines']) |
|
| 429 | + and is_array($page['contexte']['_pipelines']) |
|
| 430 | + and count($page['contexte']['_pipelines']) |
|
| 431 | + ) { |
|
| 432 | + foreach ($page['contexte']['_pipelines'] as $pipe => $args) { |
|
| 433 | + $args['contexte'] = $page['contexte']; |
|
| 434 | + unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul |
|
| 435 | + $texte = pipeline( |
|
| 436 | + $pipe, |
|
| 437 | + [ |
|
| 438 | + 'data' => $texte, |
|
| 439 | + 'args' => $args |
|
| 440 | + ] |
|
| 441 | + ); |
|
| 442 | + } |
|
| 443 | + } |
|
| 444 | + } |
|
| 445 | + |
|
| 446 | + if (defined('_VAR_MODE') and _VAR_MODE == 'debug') { |
|
| 447 | + // compatibilite : avant on donnait le numero de ligne ou rien. |
|
| 448 | + $ligne = intval($contexte_compil[3] ?? $contexte_compil); |
|
| 449 | + $GLOBALS['debug_objets']['resultat'][$ligne] = $texte; |
|
| 450 | + } |
|
| 451 | + if ($echo) { |
|
| 452 | + echo $texte; |
|
| 453 | + } else { |
|
| 454 | + return $texte; |
|
| 455 | + } |
|
| 456 | 456 | } |
| 457 | 457 | |
| 458 | 458 | function message_page_indisponible($page, $contexte) { |
| 459 | - static $deja = false; |
|
| 460 | - if ($deja) { |
|
| 461 | - return 'erreur'; |
|
| 462 | - } |
|
| 463 | - $codes = [ |
|
| 464 | - '404' => '404 Not Found', |
|
| 465 | - '503' => '503 Service Unavailable', |
|
| 466 | - ]; |
|
| 467 | - |
|
| 468 | - $contexte['status'] = ($page !== false) ? '404' : '503'; |
|
| 469 | - $contexte['code'] = $codes[$contexte['status']]; |
|
| 470 | - $contexte['fond'] = '404'; // gere les 2 erreurs |
|
| 471 | - if (!isset($contexte['lang'])) { |
|
| 472 | - include_spip('inc/lang'); |
|
| 473 | - $contexte['lang'] = $GLOBALS['spip_lang']; |
|
| 474 | - } |
|
| 475 | - |
|
| 476 | - $deja = true; |
|
| 477 | - // passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent |
|
| 478 | - // ex restriction d'acces => 401 |
|
| 479 | - $contexte = pipeline('page_indisponible', $contexte); |
|
| 480 | - |
|
| 481 | - // produire la page d'erreur |
|
| 482 | - $page = inclure_page($contexte['fond'], $contexte); |
|
| 483 | - if (!$page) { |
|
| 484 | - $page = inclure_page('404', $contexte); |
|
| 485 | - } |
|
| 486 | - $page['status'] = $contexte['status']; |
|
| 487 | - |
|
| 488 | - return $page; |
|
| 459 | + static $deja = false; |
|
| 460 | + if ($deja) { |
|
| 461 | + return 'erreur'; |
|
| 462 | + } |
|
| 463 | + $codes = [ |
|
| 464 | + '404' => '404 Not Found', |
|
| 465 | + '503' => '503 Service Unavailable', |
|
| 466 | + ]; |
|
| 467 | + |
|
| 468 | + $contexte['status'] = ($page !== false) ? '404' : '503'; |
|
| 469 | + $contexte['code'] = $codes[$contexte['status']]; |
|
| 470 | + $contexte['fond'] = '404'; // gere les 2 erreurs |
|
| 471 | + if (!isset($contexte['lang'])) { |
|
| 472 | + include_spip('inc/lang'); |
|
| 473 | + $contexte['lang'] = $GLOBALS['spip_lang']; |
|
| 474 | + } |
|
| 475 | + |
|
| 476 | + $deja = true; |
|
| 477 | + // passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent |
|
| 478 | + // ex restriction d'acces => 401 |
|
| 479 | + $contexte = pipeline('page_indisponible', $contexte); |
|
| 480 | + |
|
| 481 | + // produire la page d'erreur |
|
| 482 | + $page = inclure_page($contexte['fond'], $contexte); |
|
| 483 | + if (!$page) { |
|
| 484 | + $page = inclure_page('404', $contexte); |
|
| 485 | + } |
|
| 486 | + $page['status'] = $contexte['status']; |
|
| 487 | + |
|
| 488 | + return $page; |
|
| 489 | 489 | } |
| 490 | 490 | |
| 491 | 491 | /** |
@@ -497,44 +497,44 @@ discard block |
||
| 497 | 497 | * @return mixed |
| 498 | 498 | */ |
| 499 | 499 | function arguments_balise_dyn_depuis_modele($arg, $operation = 'set') { |
| 500 | - static $balise_dyn_appellee_par_modele = null; |
|
| 501 | - switch ($operation) { |
|
| 502 | - case 'read': |
|
| 503 | - return $balise_dyn_appellee_par_modele; |
|
| 504 | - case 'reset': |
|
| 505 | - $balise_dyn_appellee_par_modele = null; |
|
| 506 | - return null; |
|
| 507 | - case 'set': |
|
| 508 | - default: |
|
| 509 | - $balise_dyn_appellee_par_modele = $arg; |
|
| 510 | - return $arg; |
|
| 511 | - } |
|
| 500 | + static $balise_dyn_appellee_par_modele = null; |
|
| 501 | + switch ($operation) { |
|
| 502 | + case 'read': |
|
| 503 | + return $balise_dyn_appellee_par_modele; |
|
| 504 | + case 'reset': |
|
| 505 | + $balise_dyn_appellee_par_modele = null; |
|
| 506 | + return null; |
|
| 507 | + case 'set': |
|
| 508 | + default: |
|
| 509 | + $balise_dyn_appellee_par_modele = $arg; |
|
| 510 | + return $arg; |
|
| 511 | + } |
|
| 512 | 512 | } |
| 513 | 513 | |
| 514 | 514 | // temporairement ici : a mettre dans le futur inc/modeles |
| 515 | 515 | // creer_contexte_de_modele('left', 'autostart=true', ...) renvoie un array() |
| 516 | 516 | function creer_contexte_de_modele($args) { |
| 517 | - $contexte = []; |
|
| 518 | - foreach ($args as $var => $val) { |
|
| 519 | - if (is_int($var)) { // argument pas formate |
|
| 520 | - if (in_array($val, ['left', 'right', 'center'])) { |
|
| 521 | - $var = 'align'; |
|
| 522 | - $contexte[$var] = $val; |
|
| 523 | - } else { |
|
| 524 | - $args = explode('=', $val); |
|
| 525 | - if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args |
|
| 526 | - $contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1); |
|
| 527 | - } else // notation abregee |
|
| 528 | - { |
|
| 529 | - $contexte[trim($val)] = trim($val); |
|
| 530 | - } |
|
| 531 | - } |
|
| 532 | - } else { |
|
| 533 | - $contexte[$var] = $val; |
|
| 534 | - } |
|
| 535 | - } |
|
| 536 | - |
|
| 537 | - return $contexte; |
|
| 517 | + $contexte = []; |
|
| 518 | + foreach ($args as $var => $val) { |
|
| 519 | + if (is_int($var)) { // argument pas formate |
|
| 520 | + if (in_array($val, ['left', 'right', 'center'])) { |
|
| 521 | + $var = 'align'; |
|
| 522 | + $contexte[$var] = $val; |
|
| 523 | + } else { |
|
| 524 | + $args = explode('=', $val); |
|
| 525 | + if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args |
|
| 526 | + $contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1); |
|
| 527 | + } else // notation abregee |
|
| 528 | + { |
|
| 529 | + $contexte[trim($val)] = trim($val); |
|
| 530 | + } |
|
| 531 | + } |
|
| 532 | + } else { |
|
| 533 | + $contexte[$var] = $val; |
|
| 534 | + } |
|
| 535 | + } |
|
| 536 | + |
|
| 537 | + return $contexte; |
|
| 538 | 538 | } |
| 539 | 539 | |
| 540 | 540 | /** |
@@ -549,43 +549,43 @@ discard block |
||
| 549 | 549 | * @return string |
| 550 | 550 | */ |
| 551 | 551 | function styliser_modele($modele, $id, $contexte = null) { |
| 552 | - static $styliseurs = null; |
|
| 553 | - if (is_null($styliseurs)) { |
|
| 554 | - $tables_objet = lister_tables_objets_sql(); |
|
| 555 | - foreach ($tables_objet as $table => $desc) { |
|
| 556 | - if ( |
|
| 557 | - isset($desc['modeles']) and $desc['modeles'] |
|
| 558 | - and isset($desc['modeles_styliser']) and $desc['modeles_styliser'] |
|
| 559 | - and function_exists($desc['modeles_styliser']) |
|
| 560 | - ) { |
|
| 561 | - $primary = id_table_objet($table); |
|
| 562 | - foreach ($desc['modeles'] as $m) { |
|
| 563 | - $styliseurs[$m] = ['primary' => $primary, 'callback' => $desc['modeles_styliser']]; |
|
| 564 | - } |
|
| 565 | - } |
|
| 566 | - } |
|
| 567 | - } |
|
| 568 | - |
|
| 569 | - if (isset($styliseurs[$modele])) { |
|
| 570 | - $styliseur = $styliseurs[$modele]['callback']; |
|
| 571 | - $primary = $styliseurs[$modele]['primary']; |
|
| 572 | - if (is_null($id) and $contexte) { |
|
| 573 | - if (isset($contexte['id'])) { |
|
| 574 | - $id = $contexte['id']; |
|
| 575 | - } elseif (isset($contexte[$primary])) { |
|
| 576 | - $id = $contexte[$primary]; |
|
| 577 | - } |
|
| 578 | - } |
|
| 579 | - if (is_null($id)) { |
|
| 580 | - $msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]); |
|
| 581 | - erreur_squelette($msg); |
|
| 582 | - // on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant |
|
| 583 | - $id = 0; |
|
| 584 | - } |
|
| 585 | - $modele = $styliseur($modele, $id); |
|
| 586 | - } |
|
| 587 | - |
|
| 588 | - return $modele; |
|
| 552 | + static $styliseurs = null; |
|
| 553 | + if (is_null($styliseurs)) { |
|
| 554 | + $tables_objet = lister_tables_objets_sql(); |
|
| 555 | + foreach ($tables_objet as $table => $desc) { |
|
| 556 | + if ( |
|
| 557 | + isset($desc['modeles']) and $desc['modeles'] |
|
| 558 | + and isset($desc['modeles_styliser']) and $desc['modeles_styliser'] |
|
| 559 | + and function_exists($desc['modeles_styliser']) |
|
| 560 | + ) { |
|
| 561 | + $primary = id_table_objet($table); |
|
| 562 | + foreach ($desc['modeles'] as $m) { |
|
| 563 | + $styliseurs[$m] = ['primary' => $primary, 'callback' => $desc['modeles_styliser']]; |
|
| 564 | + } |
|
| 565 | + } |
|
| 566 | + } |
|
| 567 | + } |
|
| 568 | + |
|
| 569 | + if (isset($styliseurs[$modele])) { |
|
| 570 | + $styliseur = $styliseurs[$modele]['callback']; |
|
| 571 | + $primary = $styliseurs[$modele]['primary']; |
|
| 572 | + if (is_null($id) and $contexte) { |
|
| 573 | + if (isset($contexte['id'])) { |
|
| 574 | + $id = $contexte['id']; |
|
| 575 | + } elseif (isset($contexte[$primary])) { |
|
| 576 | + $id = $contexte[$primary]; |
|
| 577 | + } |
|
| 578 | + } |
|
| 579 | + if (is_null($id)) { |
|
| 580 | + $msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]); |
|
| 581 | + erreur_squelette($msg); |
|
| 582 | + // on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant |
|
| 583 | + $id = 0; |
|
| 584 | + } |
|
| 585 | + $modele = $styliseur($modele, $id); |
|
| 586 | + } |
|
| 587 | + |
|
| 588 | + return $modele; |
|
| 589 | 589 | } |
| 590 | 590 | |
| 591 | 591 | /** |
@@ -602,102 +602,102 @@ discard block |
||
| 602 | 602 | */ |
| 603 | 603 | function inclure_modele($type, $id, $params, $lien, string $connect = '', $env = []) { |
| 604 | 604 | |
| 605 | - static $compteur; |
|
| 606 | - if (++$compteur > 10) { |
|
| 607 | - return ''; |
|
| 608 | - } # ne pas boucler indefiniment |
|
| 609 | - |
|
| 610 | - $type = strtolower($type); |
|
| 611 | - $type = styliser_modele($type, $id); |
|
| 612 | - |
|
| 613 | - $fond = $class = ''; |
|
| 614 | - |
|
| 615 | - $params = array_filter(explode('|', $params)); |
|
| 616 | - if ($params) { |
|
| 617 | - $soustype = current($params); |
|
| 618 | - $soustype = strtolower(trim($soustype)); |
|
| 619 | - if (in_array($soustype, ['left', 'right', 'center', 'ajax'])) { |
|
| 620 | - $soustype = next($params); |
|
| 621 | - $soustype = strtolower($soustype); |
|
| 622 | - } |
|
| 623 | - |
|
| 624 | - if (preg_match(',^[a-z0-9_]+$,', $soustype)) { |
|
| 625 | - if (!trouve_modele($fond = ($type . '_' . $soustype))) { |
|
| 626 | - $fond = ''; |
|
| 627 | - $class = $soustype; |
|
| 628 | - } |
|
| 629 | - // enlever le sous type des params |
|
| 630 | - $params = array_diff($params, [$soustype]); |
|
| 631 | - } |
|
| 632 | - } |
|
| 633 | - |
|
| 634 | - // Si ca marche pas en precisant le sous-type, prendre le type |
|
| 635 | - if (!$fond and !trouve_modele($fond = $type)) { |
|
| 636 | - spip_log("Modele $type introuvable", _LOG_INFO_IMPORTANTE); |
|
| 637 | - |
|
| 638 | - return false; |
|
| 639 | - } |
|
| 640 | - $fond = 'modeles/' . $fond; |
|
| 641 | - // Creer le contexte |
|
| 642 | - $contexte = $env; |
|
| 643 | - $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 |
|
| 644 | - |
|
| 645 | - // Le numero du modele est mis dans l'environnement |
|
| 646 | - // d'une part sous l'identifiant "id" |
|
| 647 | - // et d'autre part sous l'identifiant de la cle primaire |
|
| 648 | - // par la fonction id_table_objet, |
|
| 649 | - // (<article1> =>> article =>> id_article =>> id_article=1) |
|
| 650 | - $_id = id_table_objet($type); |
|
| 651 | - $contexte['id'] = $contexte[$_id] = $id; |
|
| 652 | - |
|
| 653 | - if (isset($class)) { |
|
| 654 | - $contexte['class'] = $class; |
|
| 655 | - } |
|
| 656 | - |
|
| 657 | - // Si un lien a ete passe en parametre, ex: [<modele1>->url] ou [<modele1|title_du_lien{hreflang}->url] |
|
| 658 | - if ($lien) { |
|
| 659 | - # un eventuel guillemet (") sera reechappe par #ENV |
|
| 660 | - $contexte['lien'] = str_replace('"', '"', $lien['href']); |
|
| 661 | - $contexte['lien_class'] = $lien['class']; |
|
| 662 | - $contexte['lien_mime'] = $lien['mime']; |
|
| 663 | - $contexte['lien_title'] = $lien['title']; |
|
| 664 | - $contexte['lien_hreflang'] = $lien['hreflang']; |
|
| 665 | - } |
|
| 666 | - |
|
| 667 | - // Traiter les parametres |
|
| 668 | - // par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en> |
|
| 669 | - $arg_list = creer_contexte_de_modele($params); |
|
| 670 | - $contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args |
|
| 671 | - $contexte = array_merge($contexte, $arg_list); |
|
| 672 | - |
|
| 673 | - // Appliquer le modele avec le contexte |
|
| 674 | - $retour = recuperer_fond($fond, $contexte, [], $connect); |
|
| 675 | - |
|
| 676 | - // Regarder si le modele tient compte des liens (il *doit* alors indiquer |
|
| 677 | - // spip_lien_ok dans les classes de son conteneur de premier niveau ; |
|
| 678 | - // sinon, s'il y a un lien, on l'ajoute classiquement |
|
| 679 | - if ( |
|
| 680 | - strstr( |
|
| 681 | - ' ' . ($classes = extraire_attribut($retour, 'class')) . ' ', |
|
| 682 | - 'spip_lien_ok' |
|
| 683 | - ) |
|
| 684 | - ) { |
|
| 685 | - $retour = inserer_attribut( |
|
| 686 | - $retour, |
|
| 687 | - 'class', |
|
| 688 | - trim(str_replace(' spip_lien_ok ', ' ', " $classes ")) |
|
| 689 | - ); |
|
| 690 | - } else { |
|
| 691 | - if ($lien) { |
|
| 692 | - $retour = "<a href='" . $lien['href'] . "' class='" . $lien['class'] . "'>" . $retour . '</a>'; |
|
| 693 | - } |
|
| 694 | - } |
|
| 695 | - |
|
| 696 | - $compteur--; |
|
| 697 | - |
|
| 698 | - return (isset($arg_list['ajax']) and $arg_list['ajax'] == 'ajax') |
|
| 699 | - ? encoder_contexte_ajax($contexte, '', $retour) |
|
| 700 | - : $retour; |
|
| 605 | + static $compteur; |
|
| 606 | + if (++$compteur > 10) { |
|
| 607 | + return ''; |
|
| 608 | + } # ne pas boucler indefiniment |
|
| 609 | + |
|
| 610 | + $type = strtolower($type); |
|
| 611 | + $type = styliser_modele($type, $id); |
|
| 612 | + |
|
| 613 | + $fond = $class = ''; |
|
| 614 | + |
|
| 615 | + $params = array_filter(explode('|', $params)); |
|
| 616 | + if ($params) { |
|
| 617 | + $soustype = current($params); |
|
| 618 | + $soustype = strtolower(trim($soustype)); |
|
| 619 | + if (in_array($soustype, ['left', 'right', 'center', 'ajax'])) { |
|
| 620 | + $soustype = next($params); |
|
| 621 | + $soustype = strtolower($soustype); |
|
| 622 | + } |
|
| 623 | + |
|
| 624 | + if (preg_match(',^[a-z0-9_]+$,', $soustype)) { |
|
| 625 | + if (!trouve_modele($fond = ($type . '_' . $soustype))) { |
|
| 626 | + $fond = ''; |
|
| 627 | + $class = $soustype; |
|
| 628 | + } |
|
| 629 | + // enlever le sous type des params |
|
| 630 | + $params = array_diff($params, [$soustype]); |
|
| 631 | + } |
|
| 632 | + } |
|
| 633 | + |
|
| 634 | + // Si ca marche pas en precisant le sous-type, prendre le type |
|
| 635 | + if (!$fond and !trouve_modele($fond = $type)) { |
|
| 636 | + spip_log("Modele $type introuvable", _LOG_INFO_IMPORTANTE); |
|
| 637 | + |
|
| 638 | + return false; |
|
| 639 | + } |
|
| 640 | + $fond = 'modeles/' . $fond; |
|
| 641 | + // Creer le contexte |
|
| 642 | + $contexte = $env; |
|
| 643 | + $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 |
|
| 644 | + |
|
| 645 | + // Le numero du modele est mis dans l'environnement |
|
| 646 | + // d'une part sous l'identifiant "id" |
|
| 647 | + // et d'autre part sous l'identifiant de la cle primaire |
|
| 648 | + // par la fonction id_table_objet, |
|
| 649 | + // (<article1> =>> article =>> id_article =>> id_article=1) |
|
| 650 | + $_id = id_table_objet($type); |
|
| 651 | + $contexte['id'] = $contexte[$_id] = $id; |
|
| 652 | + |
|
| 653 | + if (isset($class)) { |
|
| 654 | + $contexte['class'] = $class; |
|
| 655 | + } |
|
| 656 | + |
|
| 657 | + // Si un lien a ete passe en parametre, ex: [<modele1>->url] ou [<modele1|title_du_lien{hreflang}->url] |
|
| 658 | + if ($lien) { |
|
| 659 | + # un eventuel guillemet (") sera reechappe par #ENV |
|
| 660 | + $contexte['lien'] = str_replace('"', '"', $lien['href']); |
|
| 661 | + $contexte['lien_class'] = $lien['class']; |
|
| 662 | + $contexte['lien_mime'] = $lien['mime']; |
|
| 663 | + $contexte['lien_title'] = $lien['title']; |
|
| 664 | + $contexte['lien_hreflang'] = $lien['hreflang']; |
|
| 665 | + } |
|
| 666 | + |
|
| 667 | + // Traiter les parametres |
|
| 668 | + // par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en> |
|
| 669 | + $arg_list = creer_contexte_de_modele($params); |
|
| 670 | + $contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args |
|
| 671 | + $contexte = array_merge($contexte, $arg_list); |
|
| 672 | + |
|
| 673 | + // Appliquer le modele avec le contexte |
|
| 674 | + $retour = recuperer_fond($fond, $contexte, [], $connect); |
|
| 675 | + |
|
| 676 | + // Regarder si le modele tient compte des liens (il *doit* alors indiquer |
|
| 677 | + // spip_lien_ok dans les classes de son conteneur de premier niveau ; |
|
| 678 | + // sinon, s'il y a un lien, on l'ajoute classiquement |
|
| 679 | + if ( |
|
| 680 | + strstr( |
|
| 681 | + ' ' . ($classes = extraire_attribut($retour, 'class')) . ' ', |
|
| 682 | + 'spip_lien_ok' |
|
| 683 | + ) |
|
| 684 | + ) { |
|
| 685 | + $retour = inserer_attribut( |
|
| 686 | + $retour, |
|
| 687 | + 'class', |
|
| 688 | + trim(str_replace(' spip_lien_ok ', ' ', " $classes ")) |
|
| 689 | + ); |
|
| 690 | + } else { |
|
| 691 | + if ($lien) { |
|
| 692 | + $retour = "<a href='" . $lien['href'] . "' class='" . $lien['class'] . "'>" . $retour . '</a>'; |
|
| 693 | + } |
|
| 694 | + } |
|
| 695 | + |
|
| 696 | + $compteur--; |
|
| 697 | + |
|
| 698 | + return (isset($arg_list['ajax']) and $arg_list['ajax'] == 'ajax') |
|
| 699 | + ? encoder_contexte_ajax($contexte, '', $retour) |
|
| 700 | + : $retour; |
|
| 701 | 701 | } |
| 702 | 702 | |
| 703 | 703 | // Un inclure_page qui marche aussi pour l'espace prive |
@@ -706,105 +706,105 @@ discard block |
||
| 706 | 706 | // recuperer_fond($fond,$contexte,array('raw'=>true)) |
| 707 | 707 | function evaluer_fond($fond, $contexte = [], string $connect = '') { |
| 708 | 708 | |
| 709 | - $page = inclure_page($fond, $contexte, $connect); |
|
| 710 | - |
|
| 711 | - if (!$page) { |
|
| 712 | - return $page; |
|
| 713 | - } |
|
| 714 | - // eval $page et affecte $res |
|
| 715 | - include _ROOT_RESTREINT . 'public/evaluer_page.php'; |
|
| 716 | - |
|
| 717 | - // Lever un drapeau (global) si le fond utilise #SESSION |
|
| 718 | - // a destination de public/parametrer |
|
| 719 | - // pour remonter vers les inclusions appelantes |
|
| 720 | - // il faut bien lever ce drapeau apres avoir evalue le fond |
|
| 721 | - // pour ne pas faire descendre le flag vers les inclusions appelees |
|
| 722 | - if ( |
|
| 723 | - isset($page['invalideurs']) |
|
| 724 | - and isset($page['invalideurs']['session']) |
|
| 725 | - ) { |
|
| 726 | - $GLOBALS['cache_utilise_session'] = $page['invalideurs']['session']; |
|
| 727 | - } |
|
| 728 | - |
|
| 729 | - return $page; |
|
| 709 | + $page = inclure_page($fond, $contexte, $connect); |
|
| 710 | + |
|
| 711 | + if (!$page) { |
|
| 712 | + return $page; |
|
| 713 | + } |
|
| 714 | + // eval $page et affecte $res |
|
| 715 | + include _ROOT_RESTREINT . 'public/evaluer_page.php'; |
|
| 716 | + |
|
| 717 | + // Lever un drapeau (global) si le fond utilise #SESSION |
|
| 718 | + // a destination de public/parametrer |
|
| 719 | + // pour remonter vers les inclusions appelantes |
|
| 720 | + // il faut bien lever ce drapeau apres avoir evalue le fond |
|
| 721 | + // pour ne pas faire descendre le flag vers les inclusions appelees |
|
| 722 | + if ( |
|
| 723 | + isset($page['invalideurs']) |
|
| 724 | + and isset($page['invalideurs']['session']) |
|
| 725 | + ) { |
|
| 726 | + $GLOBALS['cache_utilise_session'] = $page['invalideurs']['session']; |
|
| 727 | + } |
|
| 728 | + |
|
| 729 | + return $page; |
|
| 730 | 730 | } |
| 731 | 731 | |
| 732 | 732 | |
| 733 | 733 | function page_base_href(&$texte) { |
| 734 | - static $set_html_base = null; |
|
| 735 | - if (is_null($set_html_base)) { |
|
| 736 | - if (!defined('_SET_HTML_BASE')) { |
|
| 737 | - // si la profondeur est superieure a 1 |
|
| 738 | - // est que ce n'est pas une url page ni une url action |
|
| 739 | - // activer par defaut |
|
| 740 | - $set_html_base = (( |
|
| 741 | - $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2) |
|
| 742 | - and _request(_SPIP_PAGE) !== 'login' |
|
| 743 | - and !_request('action')) ? true : false); |
|
| 744 | - } else { |
|
| 745 | - $set_html_base = _SET_HTML_BASE; |
|
| 746 | - } |
|
| 747 | - } |
|
| 748 | - |
|
| 749 | - if ( |
|
| 750 | - $set_html_base |
|
| 751 | - and isset($GLOBALS['html']) and $GLOBALS['html'] |
|
| 752 | - and $GLOBALS['profondeur_url'] > 0 |
|
| 753 | - and ($poshead = strpos($texte, '</head>')) !== false |
|
| 754 | - ) { |
|
| 755 | - $head = substr($texte, 0, $poshead); |
|
| 756 | - $insert = false; |
|
| 757 | - $href_base = false; |
|
| 758 | - if (strpos($head, '<base') === false) { |
|
| 759 | - $insert = true; |
|
| 760 | - } else { |
|
| 761 | - // si aucun <base ...> n'a de href il faut en inserer un |
|
| 762 | - // sinon juste re-ecrire les ancres si besoin |
|
| 763 | - $insert = true; |
|
| 764 | - include_spip('inc/filtres'); |
|
| 765 | - $bases = extraire_balises($head, 'base'); |
|
| 766 | - foreach ($bases as $base) { |
|
| 767 | - if ($href_base = extraire_attribut($base, 'href')) { |
|
| 768 | - $insert = false; |
|
| 769 | - break; |
|
| 770 | - } |
|
| 771 | - } |
|
| 772 | - } |
|
| 773 | - |
|
| 774 | - if ($insert) { |
|
| 775 | - include_spip('inc/filtres_mini'); |
|
| 776 | - // ajouter un base qui reglera tous les liens relatifs |
|
| 777 | - $href_base = url_absolue('./'); |
|
| 778 | - $base = "\n<base href=\"$href_base\" />"; |
|
| 779 | - if (($pos = strpos($head, '<head>')) !== false) { |
|
| 780 | - $head = substr_replace($head, $base, $pos + 6, 0); |
|
| 781 | - } elseif (preg_match(',<head[^>]*>,i', $head, $r)) { |
|
| 782 | - $head = str_replace($r[0], $r[0] . $base, $head); |
|
| 783 | - } |
|
| 784 | - $texte = $head . substr($texte, $poshead); |
|
| 785 | - } |
|
| 786 | - if ($href_base) { |
|
| 787 | - // gerer les ancres |
|
| 788 | - $base = $_SERVER['REQUEST_URI']; |
|
| 789 | - // pas de guillemets ni < dans l'URL qu'on insere dans le HTML |
|
| 790 | - if (strpos($base, "'") or strpos($base, '"') or strpos($base, '<')) { |
|
| 791 | - $base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base); |
|
| 792 | - } |
|
| 793 | - if (strpos($texte, "href='#") !== false) { |
|
| 794 | - $texte = str_replace("href='#", "href='$base#", $texte); |
|
| 795 | - } |
|
| 796 | - if (strpos($texte, 'href="#') !== false) { |
|
| 797 | - $texte = str_replace('href="#', "href=\"$base#", $texte); |
|
| 798 | - } |
|
| 799 | - } |
|
| 800 | - } |
|
| 734 | + static $set_html_base = null; |
|
| 735 | + if (is_null($set_html_base)) { |
|
| 736 | + if (!defined('_SET_HTML_BASE')) { |
|
| 737 | + // si la profondeur est superieure a 1 |
|
| 738 | + // est que ce n'est pas une url page ni une url action |
|
| 739 | + // activer par defaut |
|
| 740 | + $set_html_base = (( |
|
| 741 | + $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2) |
|
| 742 | + and _request(_SPIP_PAGE) !== 'login' |
|
| 743 | + and !_request('action')) ? true : false); |
|
| 744 | + } else { |
|
| 745 | + $set_html_base = _SET_HTML_BASE; |
|
| 746 | + } |
|
| 747 | + } |
|
| 748 | + |
|
| 749 | + if ( |
|
| 750 | + $set_html_base |
|
| 751 | + and isset($GLOBALS['html']) and $GLOBALS['html'] |
|
| 752 | + and $GLOBALS['profondeur_url'] > 0 |
|
| 753 | + and ($poshead = strpos($texte, '</head>')) !== false |
|
| 754 | + ) { |
|
| 755 | + $head = substr($texte, 0, $poshead); |
|
| 756 | + $insert = false; |
|
| 757 | + $href_base = false; |
|
| 758 | + if (strpos($head, '<base') === false) { |
|
| 759 | + $insert = true; |
|
| 760 | + } else { |
|
| 761 | + // si aucun <base ...> n'a de href il faut en inserer un |
|
| 762 | + // sinon juste re-ecrire les ancres si besoin |
|
| 763 | + $insert = true; |
|
| 764 | + include_spip('inc/filtres'); |
|
| 765 | + $bases = extraire_balises($head, 'base'); |
|
| 766 | + foreach ($bases as $base) { |
|
| 767 | + if ($href_base = extraire_attribut($base, 'href')) { |
|
| 768 | + $insert = false; |
|
| 769 | + break; |
|
| 770 | + } |
|
| 771 | + } |
|
| 772 | + } |
|
| 773 | + |
|
| 774 | + if ($insert) { |
|
| 775 | + include_spip('inc/filtres_mini'); |
|
| 776 | + // ajouter un base qui reglera tous les liens relatifs |
|
| 777 | + $href_base = url_absolue('./'); |
|
| 778 | + $base = "\n<base href=\"$href_base\" />"; |
|
| 779 | + if (($pos = strpos($head, '<head>')) !== false) { |
|
| 780 | + $head = substr_replace($head, $base, $pos + 6, 0); |
|
| 781 | + } elseif (preg_match(',<head[^>]*>,i', $head, $r)) { |
|
| 782 | + $head = str_replace($r[0], $r[0] . $base, $head); |
|
| 783 | + } |
|
| 784 | + $texte = $head . substr($texte, $poshead); |
|
| 785 | + } |
|
| 786 | + if ($href_base) { |
|
| 787 | + // gerer les ancres |
|
| 788 | + $base = $_SERVER['REQUEST_URI']; |
|
| 789 | + // pas de guillemets ni < dans l'URL qu'on insere dans le HTML |
|
| 790 | + if (strpos($base, "'") or strpos($base, '"') or strpos($base, '<')) { |
|
| 791 | + $base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base); |
|
| 792 | + } |
|
| 793 | + if (strpos($texte, "href='#") !== false) { |
|
| 794 | + $texte = str_replace("href='#", "href='$base#", $texte); |
|
| 795 | + } |
|
| 796 | + if (strpos($texte, 'href="#') !== false) { |
|
| 797 | + $texte = str_replace('href="#', "href=\"$base#", $texte); |
|
| 798 | + } |
|
| 799 | + } |
|
| 800 | + } |
|
| 801 | 801 | } |
| 802 | 802 | |
| 803 | 803 | |
| 804 | 804 | // Envoyer les entetes, en retenant ceux qui sont a usage interne |
| 805 | 805 | // et demarrent par X-Spip-... |
| 806 | 806 | function envoyer_entetes($entetes) { |
| 807 | - foreach ($entetes as $k => $v) { # if (strncmp($k, 'X-Spip-', 7)) |
|
| 808 | - @header(strlen($v) ? "$k: $v" : $k); |
|
| 809 | - } |
|
| 807 | + foreach ($entetes as $k => $v) { # if (strncmp($k, 'X-Spip-', 7)) |
|
| 808 | + @header(strlen($v) ? "$k: $v" : $k); |
|
| 809 | + } |
|
| 810 | 810 | } |
@@ -16,7 +16,7 @@ discard block |
||
| 16 | 16 | * @package SPIP\Core\Compilateur\References |
| 17 | 17 | **/ |
| 18 | 18 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 19 | - return; |
|
| 19 | + return; |
|
| 20 | 20 | } |
| 21 | 21 | |
| 22 | 22 | /** |
@@ -41,14 +41,14 @@ discard block |
||
| 41 | 41 | * - '' si une référence explicite incorrecte est envoyée |
| 42 | 42 | */ |
| 43 | 43 | function index_boucle($p) { |
| 44 | - if (strlen($p->nom_boucle)) { |
|
| 45 | - // retourne l’index explicite demandé s’il existe |
|
| 46 | - if (!empty($p->boucles[$p->nom_boucle])) { |
|
| 47 | - return $p->nom_boucle; |
|
| 48 | - } |
|
| 49 | - return ''; |
|
| 50 | - } |
|
| 51 | - return $p->id_boucle; |
|
| 44 | + if (strlen($p->nom_boucle)) { |
|
| 45 | + // retourne l’index explicite demandé s’il existe |
|
| 46 | + if (!empty($p->boucles[$p->nom_boucle])) { |
|
| 47 | + return $p->nom_boucle; |
|
| 48 | + } |
|
| 49 | + return ''; |
|
| 50 | + } |
|
| 51 | + return $p->id_boucle; |
|
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | |
@@ -71,17 +71,17 @@ discard block |
||
| 71 | 71 | * - '' si une référence explicite incorrecte est envoyée |
| 72 | 72 | */ |
| 73 | 73 | function index_boucle_mere($p) { |
| 74 | - if (strlen($p->nom_boucle)) { |
|
| 75 | - // retourne l’index explicite demandé s’il existe |
|
| 76 | - if (!empty($p->boucles[$p->nom_boucle])) { |
|
| 77 | - return $p->nom_boucle; |
|
| 78 | - } |
|
| 79 | - return ''; |
|
| 80 | - } |
|
| 81 | - if (!empty($p->descr['id_mere'])) { |
|
| 82 | - return $p->descr['id_mere']; |
|
| 83 | - } |
|
| 84 | - return ''; |
|
| 74 | + if (strlen($p->nom_boucle)) { |
|
| 75 | + // retourne l’index explicite demandé s’il existe |
|
| 76 | + if (!empty($p->boucles[$p->nom_boucle])) { |
|
| 77 | + return $p->nom_boucle; |
|
| 78 | + } |
|
| 79 | + return ''; |
|
| 80 | + } |
|
| 81 | + if (!empty($p->descr['id_mere'])) { |
|
| 82 | + return $p->descr['id_mere']; |
|
| 83 | + } |
|
| 84 | + return ''; |
|
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | /** |
@@ -115,74 +115,74 @@ discard block |
||
| 115 | 115 | * Code PHP pour obtenir le champ SQL |
| 116 | 116 | */ |
| 117 | 117 | function index_pile( |
| 118 | - $idb, |
|
| 119 | - $nom_champ, |
|
| 120 | - &$boucles, |
|
| 121 | - $explicite = '', |
|
| 122 | - $defaut = null, |
|
| 123 | - $remonte_pile = true, |
|
| 124 | - $select = true |
|
| 118 | + $idb, |
|
| 119 | + $nom_champ, |
|
| 120 | + &$boucles, |
|
| 121 | + $explicite = '', |
|
| 122 | + $defaut = null, |
|
| 123 | + $remonte_pile = true, |
|
| 124 | + $select = true |
|
| 125 | 125 | ) { |
| 126 | - if (!is_string($defaut)) { |
|
| 127 | - $defaut = '($Pile[0][\'' . strtolower($nom_champ) . '\'] ?? null)'; |
|
| 128 | - } |
|
| 129 | - |
|
| 130 | - $idb_origine = $idb; |
|
| 131 | - $nom_champ_origine = $nom_champ; |
|
| 132 | - |
|
| 133 | - $i = 0; |
|
| 134 | - if (strlen($explicite)) { |
|
| 135 | - // Recherche d'un champ dans un etage superieur |
|
| 136 | - while (($idb !== $explicite) && ($idb !== '')) { |
|
| 137 | - # spip_log("Cherchexpl: $nom_champ '$explicite' '$idb' '$i'"); |
|
| 138 | - $i++; |
|
| 139 | - $idb = $boucles[$idb]->id_parent; |
|
| 140 | - } |
|
| 141 | - } |
|
| 142 | - |
|
| 143 | - # spip_log("Cherche: $nom_champ a partir de '$idb'"); |
|
| 144 | - $nom_champ = strtolower($nom_champ); |
|
| 145 | - $conditionnel = []; |
|
| 146 | - // attention: entre la boucle nommee 0, "" et le tableau vide, |
|
| 147 | - // il y a incoherences qu'il vaut mieux eviter |
|
| 148 | - while (isset($boucles[$idb])) { |
|
| 149 | - $joker = true; |
|
| 150 | - // modifie $joker si tous les champs sont autorisés. |
|
| 151 | - // $t = le select pour le champ, si on l'a trouvé (ou si joker) |
|
| 152 | - // $c = le nom du champ demandé |
|
| 153 | - [$t, $c] = index_tables_en_pile($idb, $nom_champ, $boucles, $joker); |
|
| 154 | - if ($t) { |
|
| 155 | - if ($select and !in_array($t, $boucles[$idb]->select)) { |
|
| 156 | - $boucles[$idb]->select[] = $t; |
|
| 157 | - } |
|
| 158 | - // renseigner la boucle source de ce champ pour les traitements |
|
| 159 | - $boucles[$idb_origine]->index_champ[$nom_champ_origine] = $idb; |
|
| 160 | - $champ = '$Pile[$SP' . ($i ? "-$i" : '') . '][\'' . $c . '\']'; |
|
| 161 | - if (!$joker) { |
|
| 162 | - return index_compose($conditionnel, $champ); |
|
| 163 | - } |
|
| 164 | - |
|
| 165 | - // tant que l'on trouve des tables avec joker, on continue |
|
| 166 | - // avec la boucle parente et on conditionne à l'exécution |
|
| 167 | - // la présence du champ. Si le champ existe à l'exécution |
|
| 168 | - // dans une boucle, il est pris, sinon on le cherche dans le parent... |
|
| 169 | - $conditionnel[] = "isset($champ)?$champ"; |
|
| 170 | - } |
|
| 171 | - |
|
| 172 | - if ($remonte_pile) { |
|
| 173 | - # spip_log("On remonte vers $i"); |
|
| 174 | - // Sinon on remonte d'un cran |
|
| 175 | - $idb = $boucles[$idb]->id_parent; |
|
| 176 | - $i++; |
|
| 177 | - } else { |
|
| 178 | - $idb = null; |
|
| 179 | - } |
|
| 180 | - } |
|
| 181 | - |
|
| 182 | - # spip_log("Pas vu $nom_champ"); |
|
| 183 | - // esperons qu'il y sera |
|
| 184 | - // ou qu'on a fourni une valeur par "defaut" plus pertinent |
|
| 185 | - return index_compose($conditionnel, $defaut); |
|
| 126 | + if (!is_string($defaut)) { |
|
| 127 | + $defaut = '($Pile[0][\'' . strtolower($nom_champ) . '\'] ?? null)'; |
|
| 128 | + } |
|
| 129 | + |
|
| 130 | + $idb_origine = $idb; |
|
| 131 | + $nom_champ_origine = $nom_champ; |
|
| 132 | + |
|
| 133 | + $i = 0; |
|
| 134 | + if (strlen($explicite)) { |
|
| 135 | + // Recherche d'un champ dans un etage superieur |
|
| 136 | + while (($idb !== $explicite) && ($idb !== '')) { |
|
| 137 | + # spip_log("Cherchexpl: $nom_champ '$explicite' '$idb' '$i'"); |
|
| 138 | + $i++; |
|
| 139 | + $idb = $boucles[$idb]->id_parent; |
|
| 140 | + } |
|
| 141 | + } |
|
| 142 | + |
|
| 143 | + # spip_log("Cherche: $nom_champ a partir de '$idb'"); |
|
| 144 | + $nom_champ = strtolower($nom_champ); |
|
| 145 | + $conditionnel = []; |
|
| 146 | + // attention: entre la boucle nommee 0, "" et le tableau vide, |
|
| 147 | + // il y a incoherences qu'il vaut mieux eviter |
|
| 148 | + while (isset($boucles[$idb])) { |
|
| 149 | + $joker = true; |
|
| 150 | + // modifie $joker si tous les champs sont autorisés. |
|
| 151 | + // $t = le select pour le champ, si on l'a trouvé (ou si joker) |
|
| 152 | + // $c = le nom du champ demandé |
|
| 153 | + [$t, $c] = index_tables_en_pile($idb, $nom_champ, $boucles, $joker); |
|
| 154 | + if ($t) { |
|
| 155 | + if ($select and !in_array($t, $boucles[$idb]->select)) { |
|
| 156 | + $boucles[$idb]->select[] = $t; |
|
| 157 | + } |
|
| 158 | + // renseigner la boucle source de ce champ pour les traitements |
|
| 159 | + $boucles[$idb_origine]->index_champ[$nom_champ_origine] = $idb; |
|
| 160 | + $champ = '$Pile[$SP' . ($i ? "-$i" : '') . '][\'' . $c . '\']'; |
|
| 161 | + if (!$joker) { |
|
| 162 | + return index_compose($conditionnel, $champ); |
|
| 163 | + } |
|
| 164 | + |
|
| 165 | + // tant que l'on trouve des tables avec joker, on continue |
|
| 166 | + // avec la boucle parente et on conditionne à l'exécution |
|
| 167 | + // la présence du champ. Si le champ existe à l'exécution |
|
| 168 | + // dans une boucle, il est pris, sinon on le cherche dans le parent... |
|
| 169 | + $conditionnel[] = "isset($champ)?$champ"; |
|
| 170 | + } |
|
| 171 | + |
|
| 172 | + if ($remonte_pile) { |
|
| 173 | + # spip_log("On remonte vers $i"); |
|
| 174 | + // Sinon on remonte d'un cran |
|
| 175 | + $idb = $boucles[$idb]->id_parent; |
|
| 176 | + $i++; |
|
| 177 | + } else { |
|
| 178 | + $idb = null; |
|
| 179 | + } |
|
| 180 | + } |
|
| 181 | + |
|
| 182 | + # spip_log("Pas vu $nom_champ"); |
|
| 183 | + // esperons qu'il y sera |
|
| 184 | + // ou qu'on a fourni une valeur par "defaut" plus pertinent |
|
| 185 | + return index_compose($conditionnel, $defaut); |
|
| 186 | 186 | } |
| 187 | 187 | |
| 188 | 188 | /** |
@@ -196,12 +196,12 @@ discard block |
||
| 196 | 196 | * @return string Code PHP complet de recherche d'un champ |
| 197 | 197 | */ |
| 198 | 198 | function index_compose($conditionnel, $defaut) { |
| 199 | - while ($c = array_pop($conditionnel)) { |
|
| 200 | - // si on passe defaut = '', ne pas générer d'erreur de compilation. |
|
| 201 | - $defaut = "($c:(" . ($defaut ?: "''") . '))'; |
|
| 202 | - } |
|
| 199 | + while ($c = array_pop($conditionnel)) { |
|
| 200 | + // si on passe defaut = '', ne pas générer d'erreur de compilation. |
|
| 201 | + $defaut = "($c:(" . ($defaut ?: "''") . '))'; |
|
| 202 | + } |
|
| 203 | 203 | |
| 204 | - return $defaut; |
|
| 204 | + return $defaut; |
|
| 205 | 205 | } |
| 206 | 206 | |
| 207 | 207 | /** |
@@ -237,77 +237,77 @@ discard block |
||
| 237 | 237 | **/ |
| 238 | 238 | function index_tables_en_pile($idb, $nom_champ, &$boucles, &$joker) { |
| 239 | 239 | |
| 240 | - $r = $boucles[$idb]->type_requete; |
|
| 241 | - // boucle recursive, c'est foutu... |
|
| 242 | - if ($r == TYPE_RECURSIF) { |
|
| 243 | - return []; |
|
| 244 | - } |
|
| 245 | - if (!$r) { |
|
| 246 | - $joker = false; // indiquer a l'appelant |
|
| 247 | - # continuer pour chercher l'erreur suivante |
|
| 248 | - return ["'#" . $r . ':' . $nom_champ . "'", '']; |
|
| 249 | - } |
|
| 250 | - |
|
| 251 | - $desc = $boucles[$idb]->show; |
|
| 252 | - // le nom du champ est il une exception de la table ? un alias ? |
|
| 253 | - $excep = $GLOBALS['exceptions_des_tables'][$r] ?? ''; |
|
| 254 | - if ($excep) { |
|
| 255 | - $excep = $excep[$nom_champ] ?? ''; |
|
| 256 | - } |
|
| 257 | - if ($excep) { |
|
| 258 | - $joker = false; // indiquer a l'appelant |
|
| 259 | - return index_exception($boucles[$idb], $desc, $nom_champ, $excep); |
|
| 260 | - } // pas d'alias. Le champ existe t'il ? |
|
| 261 | - else { |
|
| 262 | - // le champ est réellement présent, on le prend. |
|
| 263 | - if (isset($desc['field'][$nom_champ])) { |
|
| 264 | - $t = $boucles[$idb]->id_table; |
|
| 265 | - $joker = false; // indiquer a l'appelant |
|
| 266 | - return ["$t.$nom_champ", $nom_champ]; |
|
| 267 | - } |
|
| 268 | - // Tous les champs sont-ils acceptés ? |
|
| 269 | - // Si oui, on retourne le champ, et on lève le flag joker |
|
| 270 | - // C'est le cas des itérateurs DATA qui acceptent tout |
|
| 271 | - // et testent la présence du champ à l'exécution et non à la compilation |
|
| 272 | - // car ils ne connaissent pas ici leurs contenus. |
|
| 273 | - elseif ( |
|
| 240 | + $r = $boucles[$idb]->type_requete; |
|
| 241 | + // boucle recursive, c'est foutu... |
|
| 242 | + if ($r == TYPE_RECURSIF) { |
|
| 243 | + return []; |
|
| 244 | + } |
|
| 245 | + if (!$r) { |
|
| 246 | + $joker = false; // indiquer a l'appelant |
|
| 247 | + # continuer pour chercher l'erreur suivante |
|
| 248 | + return ["'#" . $r . ':' . $nom_champ . "'", '']; |
|
| 249 | + } |
|
| 250 | + |
|
| 251 | + $desc = $boucles[$idb]->show; |
|
| 252 | + // le nom du champ est il une exception de la table ? un alias ? |
|
| 253 | + $excep = $GLOBALS['exceptions_des_tables'][$r] ?? ''; |
|
| 254 | + if ($excep) { |
|
| 255 | + $excep = $excep[$nom_champ] ?? ''; |
|
| 256 | + } |
|
| 257 | + if ($excep) { |
|
| 258 | + $joker = false; // indiquer a l'appelant |
|
| 259 | + return index_exception($boucles[$idb], $desc, $nom_champ, $excep); |
|
| 260 | + } // pas d'alias. Le champ existe t'il ? |
|
| 261 | + else { |
|
| 262 | + // le champ est réellement présent, on le prend. |
|
| 263 | + if (isset($desc['field'][$nom_champ])) { |
|
| 264 | + $t = $boucles[$idb]->id_table; |
|
| 265 | + $joker = false; // indiquer a l'appelant |
|
| 266 | + return ["$t.$nom_champ", $nom_champ]; |
|
| 267 | + } |
|
| 268 | + // Tous les champs sont-ils acceptés ? |
|
| 269 | + // Si oui, on retourne le champ, et on lève le flag joker |
|
| 270 | + // C'est le cas des itérateurs DATA qui acceptent tout |
|
| 271 | + // et testent la présence du champ à l'exécution et non à la compilation |
|
| 272 | + // car ils ne connaissent pas ici leurs contenus. |
|
| 273 | + elseif ( |
|
| 274 | 274 | /*$joker AND */ |
| 275 | - isset($desc['field']['*']) |
|
| 276 | - ) { |
|
| 277 | - $joker = true; // indiquer a l'appelant |
|
| 278 | - return [$nom_champ, $nom_champ]; |
|
| 279 | - } |
|
| 280 | - // pas d'alias, pas de champ, pas de joker... |
|
| 281 | - // tenter via une jointure... |
|
| 282 | - else { |
|
| 283 | - $joker = false; // indiquer a l'appelant |
|
| 284 | - // regarder si le champ est deja dans une jointure existante |
|
| 285 | - // sinon, si il y a des joitures explicites, la construire |
|
| 286 | - if (!$t = trouver_champ_exterieur($nom_champ, $boucles[$idb]->from, $boucles[$idb])) { |
|
| 287 | - if ($boucles[$idb]->jointures_explicites) { |
|
| 288 | - // [todo] Ne pas lancer que lorsque il y a des jointures explicites !!!! |
|
| 289 | - // fonctionnel, il suffit d'utiliser $boucles[$idb]->jointures au lieu de jointures_explicites |
|
| 290 | - // mais est-ce ce qu'on veut ? |
|
| 291 | - $jointures = preg_split('/\s+/', $boucles[$idb]->jointures_explicites); |
|
| 292 | - if ($cle = trouver_jointure_champ($nom_champ, $boucles[$idb], $jointures)) { |
|
| 293 | - $t = trouver_champ_exterieur($nom_champ, $boucles[$idb]->from, $boucles[$idb]); |
|
| 294 | - } |
|
| 295 | - } |
|
| 296 | - } |
|
| 297 | - if ($t) { |
|
| 298 | - // si on a trouvé une jointure possible, on fait comme |
|
| 299 | - // si c'était une exception pour le champ demandé |
|
| 300 | - return index_exception( |
|
| 301 | - $boucles[$idb], |
|
| 302 | - $desc, |
|
| 303 | - $nom_champ, |
|
| 304 | - [$t[1]['id_table'], reset($t[2])] |
|
| 305 | - ); |
|
| 306 | - } |
|
| 307 | - |
|
| 308 | - return ['', '']; |
|
| 309 | - } |
|
| 310 | - } |
|
| 275 | + isset($desc['field']['*']) |
|
| 276 | + ) { |
|
| 277 | + $joker = true; // indiquer a l'appelant |
|
| 278 | + return [$nom_champ, $nom_champ]; |
|
| 279 | + } |
|
| 280 | + // pas d'alias, pas de champ, pas de joker... |
|
| 281 | + // tenter via une jointure... |
|
| 282 | + else { |
|
| 283 | + $joker = false; // indiquer a l'appelant |
|
| 284 | + // regarder si le champ est deja dans une jointure existante |
|
| 285 | + // sinon, si il y a des joitures explicites, la construire |
|
| 286 | + if (!$t = trouver_champ_exterieur($nom_champ, $boucles[$idb]->from, $boucles[$idb])) { |
|
| 287 | + if ($boucles[$idb]->jointures_explicites) { |
|
| 288 | + // [todo] Ne pas lancer que lorsque il y a des jointures explicites !!!! |
|
| 289 | + // fonctionnel, il suffit d'utiliser $boucles[$idb]->jointures au lieu de jointures_explicites |
|
| 290 | + // mais est-ce ce qu'on veut ? |
|
| 291 | + $jointures = preg_split('/\s+/', $boucles[$idb]->jointures_explicites); |
|
| 292 | + if ($cle = trouver_jointure_champ($nom_champ, $boucles[$idb], $jointures)) { |
|
| 293 | + $t = trouver_champ_exterieur($nom_champ, $boucles[$idb]->from, $boucles[$idb]); |
|
| 294 | + } |
|
| 295 | + } |
|
| 296 | + } |
|
| 297 | + if ($t) { |
|
| 298 | + // si on a trouvé une jointure possible, on fait comme |
|
| 299 | + // si c'était une exception pour le champ demandé |
|
| 300 | + return index_exception( |
|
| 301 | + $boucles[$idb], |
|
| 302 | + $desc, |
|
| 303 | + $nom_champ, |
|
| 304 | + [$t[1]['id_table'], reset($t[2])] |
|
| 305 | + ); |
|
| 306 | + } |
|
| 307 | + |
|
| 308 | + return ['', '']; |
|
| 309 | + } |
|
| 310 | + } |
|
| 311 | 311 | } |
| 312 | 312 | |
| 313 | 313 | |
@@ -335,52 +335,52 @@ discard block |
||
| 335 | 335 | * est une expression pour le SELECT de la boucle du style "mots.titre AS titre_mot" |
| 336 | 336 | **/ |
| 337 | 337 | function index_exception(&$boucle, $desc, $nom_champ, $excep) { |
| 338 | - static $trouver_table; |
|
| 339 | - if (!$trouver_table) { |
|
| 340 | - $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 341 | - } |
|
| 342 | - |
|
| 343 | - if (is_array($excep)) { |
|
| 344 | - // permettre aux plugins de gerer eux meme des jointures derogatoire ingerables |
|
| 345 | - $t = null; |
|
| 346 | - if (count($excep) == 3) { |
|
| 347 | - $index_exception_derogatoire = array_pop($excep); |
|
| 348 | - $t = $index_exception_derogatoire($boucle, $desc, $nom_champ, $excep); |
|
| 349 | - } |
|
| 350 | - if ($t == null) { |
|
| 351 | - [$e, $x] = $excep; #PHP4 affecte de gauche a droite |
|
| 352 | - $excep = $x; #PHP5 de droite a gauche ! |
|
| 353 | - $j = $trouver_table($e, $boucle->sql_serveur); |
|
| 354 | - if (!$j) { |
|
| 355 | - return ['', '']; |
|
| 356 | - } |
|
| 357 | - $e = $j['table']; |
|
| 358 | - if (!$t = array_search($e, $boucle->from)) { |
|
| 359 | - $k = $j['key']['PRIMARY KEY']; |
|
| 360 | - if (strpos($k, ',')) { |
|
| 361 | - $l = (preg_split('/\s*,\s*/', $k)); |
|
| 362 | - $k = $desc['key']['PRIMARY KEY']; |
|
| 363 | - if (!in_array($k, $l)) { |
|
| 364 | - spip_log("jointure impossible $e " . join(',', $l)); |
|
| 365 | - |
|
| 366 | - return ['', '']; |
|
| 367 | - } |
|
| 368 | - } |
|
| 369 | - $k = [$boucle->id_table, [$e], $k]; |
|
| 370 | - fabrique_jointures($boucle, [$k]); |
|
| 371 | - $t = array_search($e, $boucle->from); |
|
| 372 | - } |
|
| 373 | - } |
|
| 374 | - } else { |
|
| 375 | - $t = $boucle->id_table; |
|
| 376 | - } |
|
| 377 | - // demander a SQL de gerer le synonyme |
|
| 378 | - // ca permet que excep soit dynamique (Cedric, 2/3/06) |
|
| 379 | - if ($excep != $nom_champ) { |
|
| 380 | - $excep .= ' AS ' . $nom_champ; |
|
| 381 | - } |
|
| 382 | - |
|
| 383 | - return ["$t.$excep", $nom_champ]; |
|
| 338 | + static $trouver_table; |
|
| 339 | + if (!$trouver_table) { |
|
| 340 | + $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 341 | + } |
|
| 342 | + |
|
| 343 | + if (is_array($excep)) { |
|
| 344 | + // permettre aux plugins de gerer eux meme des jointures derogatoire ingerables |
|
| 345 | + $t = null; |
|
| 346 | + if (count($excep) == 3) { |
|
| 347 | + $index_exception_derogatoire = array_pop($excep); |
|
| 348 | + $t = $index_exception_derogatoire($boucle, $desc, $nom_champ, $excep); |
|
| 349 | + } |
|
| 350 | + if ($t == null) { |
|
| 351 | + [$e, $x] = $excep; #PHP4 affecte de gauche a droite |
|
| 352 | + $excep = $x; #PHP5 de droite a gauche ! |
|
| 353 | + $j = $trouver_table($e, $boucle->sql_serveur); |
|
| 354 | + if (!$j) { |
|
| 355 | + return ['', '']; |
|
| 356 | + } |
|
| 357 | + $e = $j['table']; |
|
| 358 | + if (!$t = array_search($e, $boucle->from)) { |
|
| 359 | + $k = $j['key']['PRIMARY KEY']; |
|
| 360 | + if (strpos($k, ',')) { |
|
| 361 | + $l = (preg_split('/\s*,\s*/', $k)); |
|
| 362 | + $k = $desc['key']['PRIMARY KEY']; |
|
| 363 | + if (!in_array($k, $l)) { |
|
| 364 | + spip_log("jointure impossible $e " . join(',', $l)); |
|
| 365 | + |
|
| 366 | + return ['', '']; |
|
| 367 | + } |
|
| 368 | + } |
|
| 369 | + $k = [$boucle->id_table, [$e], $k]; |
|
| 370 | + fabrique_jointures($boucle, [$k]); |
|
| 371 | + $t = array_search($e, $boucle->from); |
|
| 372 | + } |
|
| 373 | + } |
|
| 374 | + } else { |
|
| 375 | + $t = $boucle->id_table; |
|
| 376 | + } |
|
| 377 | + // demander a SQL de gerer le synonyme |
|
| 378 | + // ca permet que excep soit dynamique (Cedric, 2/3/06) |
|
| 379 | + if ($excep != $nom_champ) { |
|
| 380 | + $excep .= ' AS ' . $nom_champ; |
|
| 381 | + } |
|
| 382 | + |
|
| 383 | + return ["$t.$excep", $nom_champ]; |
|
| 384 | 384 | } |
| 385 | 385 | |
| 386 | 386 | /** |
@@ -405,7 +405,7 @@ discard block |
||
| 405 | 405 | * Code PHP pour retrouver le champ |
| 406 | 406 | */ |
| 407 | 407 | function champ_sql($champ, $p, $defaut = null, $remonte_pile = true) { |
| 408 | - return index_pile($p->id_boucle, $champ, $p->boucles, $p->nom_boucle, $defaut, $remonte_pile); |
|
| 408 | + return index_pile($p->id_boucle, $champ, $p->boucles, $p->nom_boucle, $defaut, $remonte_pile); |
|
| 409 | 409 | } |
| 410 | 410 | |
| 411 | 411 | |
@@ -425,9 +425,9 @@ discard block |
||
| 425 | 425 | * Code PHP pour d'exécution de la balise et de ses filtres |
| 426 | 426 | **/ |
| 427 | 427 | function calculer_champ($p) { |
| 428 | - $p = calculer_balise($p->nom_champ, $p); |
|
| 428 | + $p = calculer_balise($p->nom_champ, $p); |
|
| 429 | 429 | |
| 430 | - return applique_filtres($p); |
|
| 430 | + return applique_filtres($p); |
|
| 431 | 431 | } |
| 432 | 432 | |
| 433 | 433 | |
@@ -464,26 +464,26 @@ discard block |
||
| 464 | 464 | **/ |
| 465 | 465 | function calculer_balise(string $nom, \Champ $p): \Champ { |
| 466 | 466 | |
| 467 | - // S'agit-t-il d'une balise_XXXX[_dist]() ? |
|
| 468 | - if ($f = charger_fonction($nom, 'balise', true)) { |
|
| 469 | - $p->balise_calculee = true; |
|
| 470 | - $res = $f($p); |
|
| 471 | - if ($res !== null and is_object($res)) { |
|
| 472 | - return $res; |
|
| 473 | - } |
|
| 474 | - } |
|
| 475 | - |
|
| 476 | - // Certaines des balises comportant un _ sont generiques |
|
| 477 | - if ($balise_generique = chercher_balise_generique($nom)) { |
|
| 478 | - $res = $balise_generique['fonction_generique']($p); |
|
| 479 | - if ($res !== null and is_object($res)) { |
|
| 480 | - return $res; |
|
| 481 | - } |
|
| 482 | - } |
|
| 483 | - |
|
| 484 | - $f = charger_fonction('DEFAUT', 'calculer_balise'); |
|
| 485 | - |
|
| 486 | - return $f($nom, $p); |
|
| 467 | + // S'agit-t-il d'une balise_XXXX[_dist]() ? |
|
| 468 | + if ($f = charger_fonction($nom, 'balise', true)) { |
|
| 469 | + $p->balise_calculee = true; |
|
| 470 | + $res = $f($p); |
|
| 471 | + if ($res !== null and is_object($res)) { |
|
| 472 | + return $res; |
|
| 473 | + } |
|
| 474 | + } |
|
| 475 | + |
|
| 476 | + // Certaines des balises comportant un _ sont generiques |
|
| 477 | + if ($balise_generique = chercher_balise_generique($nom)) { |
|
| 478 | + $res = $balise_generique['fonction_generique']($p); |
|
| 479 | + if ($res !== null and is_object($res)) { |
|
| 480 | + return $res; |
|
| 481 | + } |
|
| 482 | + } |
|
| 483 | + |
|
| 484 | + $f = charger_fonction('DEFAUT', 'calculer_balise'); |
|
| 485 | + |
|
| 486 | + return $f($nom, $p); |
|
| 487 | 487 | } |
| 488 | 488 | |
| 489 | 489 | |
@@ -511,37 +511,37 @@ discard block |
||
| 511 | 511 | **/ |
| 512 | 512 | function calculer_balise_DEFAUT_dist($nom, $p) { |
| 513 | 513 | |
| 514 | - // ca pourrait etre un champ SQL homonyme, |
|
| 515 | - $p->code = index_pile($p->id_boucle, $nom, $p->boucles, $p->nom_boucle); |
|
| 516 | - |
|
| 517 | - // compatibilite: depuis qu'on accepte #BALISE{ses_args} sans [(...)] autour |
|
| 518 | - // il faut recracher {...} quand ce n'est finalement pas des args |
|
| 519 | - if ($p->fonctions and (!$p->fonctions[0][0]) and $p->fonctions[0][1]) { |
|
| 520 | - $code = addslashes($p->fonctions[0][1]); |
|
| 521 | - $p->code .= " . '$code'"; |
|
| 522 | - } |
|
| 523 | - |
|
| 524 | - // ne pas passer le filtre securite sur les id_xxx |
|
| 525 | - if (strpos($nom, 'ID_') === 0) { |
|
| 526 | - $p->interdire_scripts = false; |
|
| 527 | - } |
|
| 528 | - |
|
| 529 | - // Compatibilite ascendante avec les couleurs html (#FEFEFE) : |
|
| 530 | - // SI le champ SQL n'est pas trouve |
|
| 531 | - // ET si la balise a une forme de couleur |
|
| 532 | - // ET s'il n'y a ni filtre ni etoile |
|
| 533 | - // ALORS retourner la couleur. |
|
| 534 | - // Ca permet si l'on veut vraiment de recuperer [(#ACCEDE*)] |
|
| 535 | - if ( |
|
| 536 | - preg_match('/^[A-F]{1,6}$/i', $nom) |
|
| 537 | - and !$p->etoile |
|
| 538 | - and !$p->fonctions |
|
| 539 | - ) { |
|
| 540 | - $p->code = "'#$nom'"; |
|
| 541 | - $p->interdire_scripts = false; |
|
| 542 | - } |
|
| 543 | - |
|
| 544 | - return $p; |
|
| 514 | + // ca pourrait etre un champ SQL homonyme, |
|
| 515 | + $p->code = index_pile($p->id_boucle, $nom, $p->boucles, $p->nom_boucle); |
|
| 516 | + |
|
| 517 | + // compatibilite: depuis qu'on accepte #BALISE{ses_args} sans [(...)] autour |
|
| 518 | + // il faut recracher {...} quand ce n'est finalement pas des args |
|
| 519 | + if ($p->fonctions and (!$p->fonctions[0][0]) and $p->fonctions[0][1]) { |
|
| 520 | + $code = addslashes($p->fonctions[0][1]); |
|
| 521 | + $p->code .= " . '$code'"; |
|
| 522 | + } |
|
| 523 | + |
|
| 524 | + // ne pas passer le filtre securite sur les id_xxx |
|
| 525 | + if (strpos($nom, 'ID_') === 0) { |
|
| 526 | + $p->interdire_scripts = false; |
|
| 527 | + } |
|
| 528 | + |
|
| 529 | + // Compatibilite ascendante avec les couleurs html (#FEFEFE) : |
|
| 530 | + // SI le champ SQL n'est pas trouve |
|
| 531 | + // ET si la balise a une forme de couleur |
|
| 532 | + // ET s'il n'y a ni filtre ni etoile |
|
| 533 | + // ALORS retourner la couleur. |
|
| 534 | + // Ca permet si l'on veut vraiment de recuperer [(#ACCEDE*)] |
|
| 535 | + if ( |
|
| 536 | + preg_match('/^[A-F]{1,6}$/i', $nom) |
|
| 537 | + and !$p->etoile |
|
| 538 | + and !$p->fonctions |
|
| 539 | + ) { |
|
| 540 | + $p->code = "'#$nom'"; |
|
| 541 | + $p->interdire_scripts = false; |
|
| 542 | + } |
|
| 543 | + |
|
| 544 | + return $p; |
|
| 545 | 545 | } |
| 546 | 546 | |
| 547 | 547 | |
@@ -584,39 +584,39 @@ discard block |
||
| 584 | 584 | **/ |
| 585 | 585 | function calculer_balise_dynamique($p, $nom, $l, $supp = []) { |
| 586 | 586 | |
| 587 | - if (!balise_distante_interdite($p)) { |
|
| 588 | - $p->code = "''"; |
|
| 589 | - |
|
| 590 | - return $p; |
|
| 591 | - } |
|
| 592 | - // compatibilite: depuis qu'on accepte #BALISE{ses_args} sans [(...)] autour |
|
| 593 | - // il faut recracher {...} quand ce n'est finalement pas des args |
|
| 594 | - if ($p->fonctions and (!$p->fonctions[0][0]) and $p->fonctions[0][1]) { |
|
| 595 | - $p->fonctions = null; |
|
| 596 | - } |
|
| 597 | - |
|
| 598 | - if ($p->param and ($c = $p->param[0])) { |
|
| 599 | - // liste d'arguments commence toujours par la chaine vide |
|
| 600 | - array_shift($c); |
|
| 601 | - // construire la liste d'arguments comme pour un filtre |
|
| 602 | - $param = compose_filtres_args($p, $c, ','); |
|
| 603 | - } else { |
|
| 604 | - $param = ''; |
|
| 605 | - } |
|
| 606 | - $collecte = collecter_balise_dynamique($l, $p, $nom); |
|
| 607 | - |
|
| 608 | - $p->code = sprintf( |
|
| 609 | - CODE_EXECUTER_BALISE, |
|
| 610 | - $nom, |
|
| 611 | - join(',', $collecte), |
|
| 612 | - ($collecte ? $param : substr($param, 1)), # virer la virgule |
|
| 613 | - memoriser_contexte_compil($p), |
|
| 614 | - (!$supp ? '' : (', ' . join(',', $supp))) |
|
| 615 | - ); |
|
| 616 | - |
|
| 617 | - $p->interdire_scripts = false; |
|
| 618 | - |
|
| 619 | - return $p; |
|
| 587 | + if (!balise_distante_interdite($p)) { |
|
| 588 | + $p->code = "''"; |
|
| 589 | + |
|
| 590 | + return $p; |
|
| 591 | + } |
|
| 592 | + // compatibilite: depuis qu'on accepte #BALISE{ses_args} sans [(...)] autour |
|
| 593 | + // il faut recracher {...} quand ce n'est finalement pas des args |
|
| 594 | + if ($p->fonctions and (!$p->fonctions[0][0]) and $p->fonctions[0][1]) { |
|
| 595 | + $p->fonctions = null; |
|
| 596 | + } |
|
| 597 | + |
|
| 598 | + if ($p->param and ($c = $p->param[0])) { |
|
| 599 | + // liste d'arguments commence toujours par la chaine vide |
|
| 600 | + array_shift($c); |
|
| 601 | + // construire la liste d'arguments comme pour un filtre |
|
| 602 | + $param = compose_filtres_args($p, $c, ','); |
|
| 603 | + } else { |
|
| 604 | + $param = ''; |
|
| 605 | + } |
|
| 606 | + $collecte = collecter_balise_dynamique($l, $p, $nom); |
|
| 607 | + |
|
| 608 | + $p->code = sprintf( |
|
| 609 | + CODE_EXECUTER_BALISE, |
|
| 610 | + $nom, |
|
| 611 | + join(',', $collecte), |
|
| 612 | + ($collecte ? $param : substr($param, 1)), # virer la virgule |
|
| 613 | + memoriser_contexte_compil($p), |
|
| 614 | + (!$supp ? '' : (', ' . join(',', $supp))) |
|
| 615 | + ); |
|
| 616 | + |
|
| 617 | + $p->interdire_scripts = false; |
|
| 618 | + |
|
| 619 | + return $p; |
|
| 620 | 620 | } |
| 621 | 621 | |
| 622 | 622 | |
@@ -646,17 +646,17 @@ discard block |
||
| 646 | 646 | * Liste des codes PHP d'éxecution des balises collectées |
| 647 | 647 | **/ |
| 648 | 648 | function collecter_balise_dynamique(array $l, \Champ &$p, string $nom): array { |
| 649 | - $args = []; |
|
| 650 | - foreach ($l as $c) { |
|
| 651 | - if ($c === null) { |
|
| 652 | - $args[] = 'null'; |
|
| 653 | - } else { |
|
| 654 | - $x = calculer_balise($c, $p); |
|
| 655 | - $args[] = $x->code; |
|
| 656 | - } |
|
| 657 | - } |
|
| 658 | - |
|
| 659 | - return $args; |
|
| 649 | + $args = []; |
|
| 650 | + foreach ($l as $c) { |
|
| 651 | + if ($c === null) { |
|
| 652 | + $args[] = 'null'; |
|
| 653 | + } else { |
|
| 654 | + $x = calculer_balise($c, $p); |
|
| 655 | + $args[] = $x->code; |
|
| 656 | + } |
|
| 657 | + } |
|
| 658 | + |
|
| 659 | + return $args; |
|
| 660 | 660 | } |
| 661 | 661 | |
| 662 | 662 | |
@@ -671,22 +671,22 @@ discard block |
||
| 671 | 671 | * Nom de la connexion |
| 672 | 672 | **/ |
| 673 | 673 | function trouver_nom_serveur_distant($p) { |
| 674 | - $nom = $p->id_boucle; |
|
| 675 | - if ( |
|
| 676 | - $nom |
|
| 677 | - and isset($p->boucles[$nom]) |
|
| 678 | - ) { |
|
| 679 | - $s = $p->boucles[$nom]->sql_serveur; |
|
| 680 | - if ( |
|
| 681 | - strlen($s) |
|
| 682 | - and strlen($serveur = strtolower($s)) |
|
| 683 | - and !in_array($serveur, $GLOBALS['exception_des_connect']) |
|
| 684 | - ) { |
|
| 685 | - return $serveur; |
|
| 686 | - } |
|
| 687 | - } |
|
| 688 | - |
|
| 689 | - return ''; |
|
| 674 | + $nom = $p->id_boucle; |
|
| 675 | + if ( |
|
| 676 | + $nom |
|
| 677 | + and isset($p->boucles[$nom]) |
|
| 678 | + ) { |
|
| 679 | + $s = $p->boucles[$nom]->sql_serveur; |
|
| 680 | + if ( |
|
| 681 | + strlen($s) |
|
| 682 | + and strlen($serveur = strtolower($s)) |
|
| 683 | + and !in_array($serveur, $GLOBALS['exception_des_connect']) |
|
| 684 | + ) { |
|
| 685 | + return $serveur; |
|
| 686 | + } |
|
| 687 | + } |
|
| 688 | + |
|
| 689 | + return ''; |
|
| 690 | 690 | } |
| 691 | 691 | |
| 692 | 692 | |
@@ -710,15 +710,15 @@ discard block |
||
| 710 | 710 | * - false : La balise est interdite car le serveur est distant |
| 711 | 711 | **/ |
| 712 | 712 | function balise_distante_interdite($p) { |
| 713 | - $nom = $p->id_boucle; |
|
| 713 | + $nom = $p->id_boucle; |
|
| 714 | 714 | |
| 715 | - if ($nom and trouver_nom_serveur_distant($p)) { |
|
| 716 | - spip_log($nom . ':' . $p->nom_champ . ' ' . _T('zbug_distant_interdit')); |
|
| 715 | + if ($nom and trouver_nom_serveur_distant($p)) { |
|
| 716 | + spip_log($nom . ':' . $p->nom_champ . ' ' . _T('zbug_distant_interdit')); |
|
| 717 | 717 | |
| 718 | - return false; |
|
| 719 | - } |
|
| 718 | + return false; |
|
| 719 | + } |
|
| 720 | 720 | |
| 721 | - return true; |
|
| 721 | + return true; |
|
| 722 | 722 | } |
| 723 | 723 | |
| 724 | 724 | |
@@ -728,84 +728,84 @@ discard block |
||
| 728 | 728 | // |
| 729 | 729 | function champs_traitements($p) { |
| 730 | 730 | |
| 731 | - if (isset($GLOBALS['table_des_traitements'][$p->nom_champ])) { |
|
| 732 | - $ps = $GLOBALS['table_des_traitements'][$p->nom_champ]; |
|
| 733 | - } else { |
|
| 734 | - // quand on utilise un traitement catch-all * |
|
| 735 | - // celui-ci ne s'applique pas sur les balises calculees qui peuvent gerer |
|
| 736 | - // leur propre securite |
|
| 737 | - if (!$p->balise_calculee) { |
|
| 738 | - $ps = $GLOBALS['table_des_traitements']['*']; |
|
| 739 | - } else { |
|
| 740 | - $ps = false; |
|
| 741 | - } |
|
| 742 | - } |
|
| 743 | - |
|
| 744 | - if (is_array($ps)) { |
|
| 745 | - // Recuperer le type de boucle (articles, DATA) et la table SQL sur laquelle elle porte |
|
| 746 | - $idb = index_boucle($p); |
|
| 747 | - // si le champ a ete trouve dans une boucle parente sa source est renseignee ici |
|
| 748 | - if (!empty($p->boucles[$idb]->index_champ[$p->nom_champ])) { |
|
| 749 | - $idb = $p->boucles[$idb]->index_champ[$p->nom_champ]; |
|
| 750 | - } |
|
| 751 | - |
|
| 752 | - // mais on peut aussi etre hors boucle. Se mefier. |
|
| 753 | - $type_requete = $p->boucles[$idb]->type_requete ?? false; |
|
| 754 | - $table_sql = $p->boucles[$idb]->show['table_sql'] ?? false; |
|
| 755 | - |
|
| 756 | - // bien prendre en compte les alias de boucles (hierarchie => rubrique, syndication => syncdic, etc.) |
|
| 757 | - if ($type_requete and isset($GLOBALS['table_des_tables'][$type_requete])) { |
|
| 758 | - $type_alias = $type_requete; |
|
| 759 | - $type_requete = $GLOBALS['table_des_tables'][$type_requete]; |
|
| 760 | - } else { |
|
| 761 | - $type_alias = false; |
|
| 762 | - } |
|
| 763 | - |
|
| 764 | - // le traitement peut n'etre defini que pour une table en particulier "spip_articles" |
|
| 765 | - if ($table_sql and isset($ps[$table_sql])) { |
|
| 766 | - $ps = $ps[$table_sql]; |
|
| 767 | - } // ou pour une boucle en particulier "DATA","articles" |
|
| 768 | - elseif ($type_requete and isset($ps[$type_requete])) { |
|
| 769 | - $ps = $ps[$type_requete]; |
|
| 770 | - } // ou pour une boucle utilisant un alias ("hierarchie") |
|
| 771 | - elseif ($type_alias and isset($ps[$type_alias])) { |
|
| 772 | - $ps = $ps[$type_alias]; |
|
| 773 | - } // ou pour indifféremment quelle que soit la boucle |
|
| 774 | - elseif (isset($ps[0])) { |
|
| 775 | - $ps = $ps[0]; |
|
| 776 | - } else { |
|
| 777 | - $ps = false; |
|
| 778 | - } |
|
| 779 | - } |
|
| 780 | - |
|
| 781 | - if (!$ps) { |
|
| 782 | - return $p->code; |
|
| 783 | - } |
|
| 784 | - |
|
| 785 | - // Si une boucle DOCUMENTS{doublons} est presente dans le squelette, |
|
| 786 | - // ou si in INCLURE contient {doublons} |
|
| 787 | - // on insere une fonction de remplissage du tableau des doublons |
|
| 788 | - // dans les filtres propre() ou typo() |
|
| 789 | - // (qui traitent les raccourcis <docXX> referencant les docs) |
|
| 790 | - |
|
| 791 | - if ( |
|
| 792 | - isset($p->descr['documents']) |
|
| 793 | - and |
|
| 794 | - $p->descr['documents'] |
|
| 795 | - and ( |
|
| 796 | - (strpos($ps, 'propre') !== false) |
|
| 797 | - or |
|
| 798 | - (strpos($ps, 'typo') !== false) |
|
| 799 | - ) |
|
| 800 | - ) { |
|
| 801 | - $ps = 'traiter_doublons_documents($doublons, ' . $ps . ')'; |
|
| 802 | - } |
|
| 803 | - |
|
| 804 | - // La protection des champs par |safehtml est assuree par les extensions |
|
| 805 | - // dans la declaration des traitements des champs sensibles |
|
| 806 | - |
|
| 807 | - // Remplacer enfin le placeholder %s par le vrai code de la balise |
|
| 808 | - return str_replace('%s', $p->code, $ps); |
|
| 731 | + if (isset($GLOBALS['table_des_traitements'][$p->nom_champ])) { |
|
| 732 | + $ps = $GLOBALS['table_des_traitements'][$p->nom_champ]; |
|
| 733 | + } else { |
|
| 734 | + // quand on utilise un traitement catch-all * |
|
| 735 | + // celui-ci ne s'applique pas sur les balises calculees qui peuvent gerer |
|
| 736 | + // leur propre securite |
|
| 737 | + if (!$p->balise_calculee) { |
|
| 738 | + $ps = $GLOBALS['table_des_traitements']['*']; |
|
| 739 | + } else { |
|
| 740 | + $ps = false; |
|
| 741 | + } |
|
| 742 | + } |
|
| 743 | + |
|
| 744 | + if (is_array($ps)) { |
|
| 745 | + // Recuperer le type de boucle (articles, DATA) et la table SQL sur laquelle elle porte |
|
| 746 | + $idb = index_boucle($p); |
|
| 747 | + // si le champ a ete trouve dans une boucle parente sa source est renseignee ici |
|
| 748 | + if (!empty($p->boucles[$idb]->index_champ[$p->nom_champ])) { |
|
| 749 | + $idb = $p->boucles[$idb]->index_champ[$p->nom_champ]; |
|
| 750 | + } |
|
| 751 | + |
|
| 752 | + // mais on peut aussi etre hors boucle. Se mefier. |
|
| 753 | + $type_requete = $p->boucles[$idb]->type_requete ?? false; |
|
| 754 | + $table_sql = $p->boucles[$idb]->show['table_sql'] ?? false; |
|
| 755 | + |
|
| 756 | + // bien prendre en compte les alias de boucles (hierarchie => rubrique, syndication => syncdic, etc.) |
|
| 757 | + if ($type_requete and isset($GLOBALS['table_des_tables'][$type_requete])) { |
|
| 758 | + $type_alias = $type_requete; |
|
| 759 | + $type_requete = $GLOBALS['table_des_tables'][$type_requete]; |
|
| 760 | + } else { |
|
| 761 | + $type_alias = false; |
|
| 762 | + } |
|
| 763 | + |
|
| 764 | + // le traitement peut n'etre defini que pour une table en particulier "spip_articles" |
|
| 765 | + if ($table_sql and isset($ps[$table_sql])) { |
|
| 766 | + $ps = $ps[$table_sql]; |
|
| 767 | + } // ou pour une boucle en particulier "DATA","articles" |
|
| 768 | + elseif ($type_requete and isset($ps[$type_requete])) { |
|
| 769 | + $ps = $ps[$type_requete]; |
|
| 770 | + } // ou pour une boucle utilisant un alias ("hierarchie") |
|
| 771 | + elseif ($type_alias and isset($ps[$type_alias])) { |
|
| 772 | + $ps = $ps[$type_alias]; |
|
| 773 | + } // ou pour indifféremment quelle que soit la boucle |
|
| 774 | + elseif (isset($ps[0])) { |
|
| 775 | + $ps = $ps[0]; |
|
| 776 | + } else { |
|
| 777 | + $ps = false; |
|
| 778 | + } |
|
| 779 | + } |
|
| 780 | + |
|
| 781 | + if (!$ps) { |
|
| 782 | + return $p->code; |
|
| 783 | + } |
|
| 784 | + |
|
| 785 | + // Si une boucle DOCUMENTS{doublons} est presente dans le squelette, |
|
| 786 | + // ou si in INCLURE contient {doublons} |
|
| 787 | + // on insere une fonction de remplissage du tableau des doublons |
|
| 788 | + // dans les filtres propre() ou typo() |
|
| 789 | + // (qui traitent les raccourcis <docXX> referencant les docs) |
|
| 790 | + |
|
| 791 | + if ( |
|
| 792 | + isset($p->descr['documents']) |
|
| 793 | + and |
|
| 794 | + $p->descr['documents'] |
|
| 795 | + and ( |
|
| 796 | + (strpos($ps, 'propre') !== false) |
|
| 797 | + or |
|
| 798 | + (strpos($ps, 'typo') !== false) |
|
| 799 | + ) |
|
| 800 | + ) { |
|
| 801 | + $ps = 'traiter_doublons_documents($doublons, ' . $ps . ')'; |
|
| 802 | + } |
|
| 803 | + |
|
| 804 | + // La protection des champs par |safehtml est assuree par les extensions |
|
| 805 | + // dans la declaration des traitements des champs sensibles |
|
| 806 | + |
|
| 807 | + // Remplacer enfin le placeholder %s par le vrai code de la balise |
|
| 808 | + return str_replace('%s', $p->code, $ps); |
|
| 809 | 809 | } |
| 810 | 810 | |
| 811 | 811 | |
@@ -817,110 +817,110 @@ discard block |
||
| 817 | 817 | // |
| 818 | 818 | function applique_filtres($p) { |
| 819 | 819 | |
| 820 | - // Traitements standards (cf. supra) |
|
| 821 | - if ($p->etoile == '') { |
|
| 822 | - $code = champs_traitements($p); |
|
| 823 | - } else { |
|
| 824 | - $code = $p->code; |
|
| 825 | - } |
|
| 820 | + // Traitements standards (cf. supra) |
|
| 821 | + if ($p->etoile == '') { |
|
| 822 | + $code = champs_traitements($p); |
|
| 823 | + } else { |
|
| 824 | + $code = $p->code; |
|
| 825 | + } |
|
| 826 | 826 | |
| 827 | - // Appliquer les filtres perso |
|
| 828 | - if ($p->param) { |
|
| 829 | - $code = compose_filtres($p, $code); |
|
| 830 | - } |
|
| 827 | + // Appliquer les filtres perso |
|
| 828 | + if ($p->param) { |
|
| 829 | + $code = compose_filtres($p, $code); |
|
| 830 | + } |
|
| 831 | 831 | |
| 832 | - // S'il y a un lien avec la session, ajouter un code qui levera |
|
| 833 | - // un drapeau dans la structure d'invalidation $Cache |
|
| 834 | - if (isset($p->descr['session'])) { |
|
| 835 | - $code = "invalideur_session(\$Cache, $code)"; |
|
| 836 | - } |
|
| 832 | + // S'il y a un lien avec la session, ajouter un code qui levera |
|
| 833 | + // un drapeau dans la structure d'invalidation $Cache |
|
| 834 | + if (isset($p->descr['session'])) { |
|
| 835 | + $code = "invalideur_session(\$Cache, $code)"; |
|
| 836 | + } |
|
| 837 | 837 | |
| 838 | - $code = sandbox_composer_interdire_scripts($code, $p); |
|
| 838 | + $code = sandbox_composer_interdire_scripts($code, $p); |
|
| 839 | 839 | |
| 840 | - return $code; |
|
| 840 | + return $code; |
|
| 841 | 841 | } |
| 842 | 842 | |
| 843 | 843 | // Cf. function pipeline dans ecrire/inc_utils.php |
| 844 | 844 | function compose_filtres(&$p, $code) { |
| 845 | 845 | |
| 846 | - $image_miette = false; |
|
| 847 | - foreach ($p->param as $filtre) { |
|
| 848 | - $fonc = array_shift($filtre); |
|
| 849 | - if (!$fonc) { |
|
| 850 | - continue; |
|
| 851 | - } // normalement qu'au premier tour. |
|
| 852 | - $is_filtre_image = ((substr($fonc, 0, 6) == 'image_') and $fonc != 'image_graver'); |
|
| 853 | - if ($image_miette and !$is_filtre_image) { |
|
| 854 | - // il faut graver maintenant car apres le filtre en cours |
|
| 855 | - // on est pas sur d'avoir encore le nom du fichier dans le pipe |
|
| 856 | - $code = "filtrer('image_graver', $code)"; |
|
| 857 | - $image_miette = false; |
|
| 858 | - } |
|
| 859 | - |
|
| 860 | - // recuperer les arguments du filtre, |
|
| 861 | - // a separer par "," ou ":" dans le cas du filtre "?{a,b}" |
|
| 862 | - $countfiltre = is_countable($filtre) ? count($filtre) : 0; |
|
| 863 | - if ($fonc !== '?') { |
|
| 864 | - $sep = ','; |
|
| 865 | - } else { |
|
| 866 | - $sep = ':'; |
|
| 867 | - // |?{a,b} *doit* avoir exactement 2 arguments ; on les force |
|
| 868 | - if ($countfiltre != 2) { |
|
| 869 | - $filtre = [$filtre[0] ?? '', $filtre[1] ?? '']; |
|
| 870 | - $countfiltre = 2; |
|
| 871 | - } |
|
| 872 | - } |
|
| 873 | - $arglist = compose_filtres_args($p, $filtre, $sep); |
|
| 874 | - $logique = filtre_logique($fonc, $code, substr($arglist, 1)); |
|
| 875 | - if ($logique) { |
|
| 876 | - $code = $logique; |
|
| 877 | - } else { |
|
| 878 | - $code = sandbox_composer_filtre($fonc, $code, $arglist, $p, $countfiltre); |
|
| 879 | - if ($is_filtre_image) { |
|
| 880 | - $image_miette = true; |
|
| 881 | - } |
|
| 882 | - } |
|
| 883 | - } |
|
| 884 | - // ramasser les images intermediaires inutiles et graver l'image finale |
|
| 885 | - if ($image_miette) { |
|
| 886 | - $code = "filtrer('image_graver',$code)"; |
|
| 887 | - } |
|
| 888 | - |
|
| 889 | - return $code; |
|
| 846 | + $image_miette = false; |
|
| 847 | + foreach ($p->param as $filtre) { |
|
| 848 | + $fonc = array_shift($filtre); |
|
| 849 | + if (!$fonc) { |
|
| 850 | + continue; |
|
| 851 | + } // normalement qu'au premier tour. |
|
| 852 | + $is_filtre_image = ((substr($fonc, 0, 6) == 'image_') and $fonc != 'image_graver'); |
|
| 853 | + if ($image_miette and !$is_filtre_image) { |
|
| 854 | + // il faut graver maintenant car apres le filtre en cours |
|
| 855 | + // on est pas sur d'avoir encore le nom du fichier dans le pipe |
|
| 856 | + $code = "filtrer('image_graver', $code)"; |
|
| 857 | + $image_miette = false; |
|
| 858 | + } |
|
| 859 | + |
|
| 860 | + // recuperer les arguments du filtre, |
|
| 861 | + // a separer par "," ou ":" dans le cas du filtre "?{a,b}" |
|
| 862 | + $countfiltre = is_countable($filtre) ? count($filtre) : 0; |
|
| 863 | + if ($fonc !== '?') { |
|
| 864 | + $sep = ','; |
|
| 865 | + } else { |
|
| 866 | + $sep = ':'; |
|
| 867 | + // |?{a,b} *doit* avoir exactement 2 arguments ; on les force |
|
| 868 | + if ($countfiltre != 2) { |
|
| 869 | + $filtre = [$filtre[0] ?? '', $filtre[1] ?? '']; |
|
| 870 | + $countfiltre = 2; |
|
| 871 | + } |
|
| 872 | + } |
|
| 873 | + $arglist = compose_filtres_args($p, $filtre, $sep); |
|
| 874 | + $logique = filtre_logique($fonc, $code, substr($arglist, 1)); |
|
| 875 | + if ($logique) { |
|
| 876 | + $code = $logique; |
|
| 877 | + } else { |
|
| 878 | + $code = sandbox_composer_filtre($fonc, $code, $arglist, $p, $countfiltre); |
|
| 879 | + if ($is_filtre_image) { |
|
| 880 | + $image_miette = true; |
|
| 881 | + } |
|
| 882 | + } |
|
| 883 | + } |
|
| 884 | + // ramasser les images intermediaires inutiles et graver l'image finale |
|
| 885 | + if ($image_miette) { |
|
| 886 | + $code = "filtrer('image_graver',$code)"; |
|
| 887 | + } |
|
| 888 | + |
|
| 889 | + return $code; |
|
| 890 | 890 | } |
| 891 | 891 | |
| 892 | 892 | // Filtres et,ou,oui,non,sinon,xou,xor,and,or,not,yes |
| 893 | 893 | // et comparateurs |
| 894 | 894 | function filtre_logique($fonc, $code, $arg) { |
| 895 | 895 | |
| 896 | - switch (true) { |
|
| 897 | - case in_array($fonc, $GLOBALS['table_criteres_infixes']): |
|
| 898 | - return "($code $fonc $arg)"; |
|
| 899 | - case ($fonc == 'and') or ($fonc == 'et'): |
|
| 900 | - return "((($code) AND ($arg)) ?' ' :'')"; |
|
| 901 | - case ($fonc == 'or') or ($fonc == 'ou'): |
|
| 902 | - return "((($code) OR ($arg)) ?' ' :'')"; |
|
| 903 | - case ($fonc == 'xor') or ($fonc == 'xou'): |
|
| 904 | - return "((($code) XOR ($arg)) ?' ' :'')"; |
|
| 905 | - case ($fonc == 'sinon'): |
|
| 906 | - return "(((\$a = $code) OR (is_string(\$a) AND strlen(\$a))) ? \$a : $arg)"; |
|
| 907 | - case ($fonc == 'not') or ($fonc == 'non'): |
|
| 908 | - return "(($code) ?'' :' ')"; |
|
| 909 | - case ($fonc == 'yes') or ($fonc == 'oui'): |
|
| 910 | - return "(($code) ?' ' :'')"; |
|
| 911 | - } |
|
| 912 | - |
|
| 913 | - return ''; |
|
| 896 | + switch (true) { |
|
| 897 | + case in_array($fonc, $GLOBALS['table_criteres_infixes']): |
|
| 898 | + return "($code $fonc $arg)"; |
|
| 899 | + case ($fonc == 'and') or ($fonc == 'et'): |
|
| 900 | + return "((($code) AND ($arg)) ?' ' :'')"; |
|
| 901 | + case ($fonc == 'or') or ($fonc == 'ou'): |
|
| 902 | + return "((($code) OR ($arg)) ?' ' :'')"; |
|
| 903 | + case ($fonc == 'xor') or ($fonc == 'xou'): |
|
| 904 | + return "((($code) XOR ($arg)) ?' ' :'')"; |
|
| 905 | + case ($fonc == 'sinon'): |
|
| 906 | + return "(((\$a = $code) OR (is_string(\$a) AND strlen(\$a))) ? \$a : $arg)"; |
|
| 907 | + case ($fonc == 'not') or ($fonc == 'non'): |
|
| 908 | + return "(($code) ?'' :' ')"; |
|
| 909 | + case ($fonc == 'yes') or ($fonc == 'oui'): |
|
| 910 | + return "(($code) ?' ' :'')"; |
|
| 911 | + } |
|
| 912 | + |
|
| 913 | + return ''; |
|
| 914 | 914 | } |
| 915 | 915 | |
| 916 | 916 | function compose_filtres_args($p, $args, $sep) { |
| 917 | - $arglist = ''; |
|
| 918 | - foreach ($args as $arg) { |
|
| 919 | - $arglist .= $sep . |
|
| 920 | - calculer_liste($arg, $p->descr, $p->boucles, $p->id_boucle); |
|
| 921 | - } |
|
| 917 | + $arglist = ''; |
|
| 918 | + foreach ($args as $arg) { |
|
| 919 | + $arglist .= $sep . |
|
| 920 | + calculer_liste($arg, $p->descr, $p->boucles, $p->id_boucle); |
|
| 921 | + } |
|
| 922 | 922 | |
| 923 | - return $arglist; |
|
| 923 | + return $arglist; |
|
| 924 | 924 | } |
| 925 | 925 | |
| 926 | 926 | |
@@ -938,15 +938,15 @@ discard block |
||
| 938 | 938 | **/ |
| 939 | 939 | function calculer_argument_precedent($idb, $nom_champ, &$boucles, $defaut = null) { |
| 940 | 940 | |
| 941 | - // si recursif, forcer l'extraction du champ SQL mais ignorer le code |
|
| 942 | - if ($boucles[$idb]->externe) { |
|
| 943 | - index_pile($idb, $nom_champ, $boucles, '', $defaut); |
|
| 944 | - // retourner $Pile[$SP] et pas $Pile[0] si recursion en 1ere boucle |
|
| 945 | - // on ignore le defaut fourni dans ce cas |
|
| 946 | - $defaut = "(\$Pile[\$SP]['$nom_champ'] ?? null)"; |
|
| 947 | - } |
|
| 941 | + // si recursif, forcer l'extraction du champ SQL mais ignorer le code |
|
| 942 | + if ($boucles[$idb]->externe) { |
|
| 943 | + index_pile($idb, $nom_champ, $boucles, '', $defaut); |
|
| 944 | + // retourner $Pile[$SP] et pas $Pile[0] si recursion en 1ere boucle |
|
| 945 | + // on ignore le defaut fourni dans ce cas |
|
| 946 | + $defaut = "(\$Pile[\$SP]['$nom_champ'] ?? null)"; |
|
| 947 | + } |
|
| 948 | 948 | |
| 949 | - return index_pile($boucles[$idb]->id_parent, $nom_champ, $boucles, '', $defaut); |
|
| 949 | + return index_pile($boucles[$idb]->id_parent, $nom_champ, $boucles, '', $defaut); |
|
| 950 | 950 | } |
| 951 | 951 | |
| 952 | 952 | // |
@@ -960,30 +960,30 @@ discard block |
||
| 960 | 960 | // |
| 961 | 961 | |
| 962 | 962 | function rindex_pile($p, $champ, $motif) { |
| 963 | - $n = 0; |
|
| 964 | - $b = $p->id_boucle; |
|
| 965 | - $p->code = ''; |
|
| 966 | - while ($b != '') { |
|
| 967 | - foreach ($p->boucles[$b]->criteres as $critere) { |
|
| 968 | - if ($critere->op == $motif) { |
|
| 969 | - $p->code = '$Pile[$SP' . (($n == 0) ? '' : "-$n") . |
|
| 970 | - "]['$champ']"; |
|
| 971 | - $b = ''; |
|
| 972 | - break 2; |
|
| 973 | - } |
|
| 974 | - } |
|
| 975 | - $n++; |
|
| 976 | - $b = $p->boucles[$b]->id_parent; |
|
| 977 | - } |
|
| 978 | - |
|
| 979 | - // si on est hors d'une boucle de {recherche}, cette balise est vide |
|
| 980 | - if (!$p->code) { |
|
| 981 | - $p->code = "''"; |
|
| 982 | - } |
|
| 983 | - |
|
| 984 | - $p->interdire_scripts = false; |
|
| 985 | - |
|
| 986 | - return $p; |
|
| 963 | + $n = 0; |
|
| 964 | + $b = $p->id_boucle; |
|
| 965 | + $p->code = ''; |
|
| 966 | + while ($b != '') { |
|
| 967 | + foreach ($p->boucles[$b]->criteres as $critere) { |
|
| 968 | + if ($critere->op == $motif) { |
|
| 969 | + $p->code = '$Pile[$SP' . (($n == 0) ? '' : "-$n") . |
|
| 970 | + "]['$champ']"; |
|
| 971 | + $b = ''; |
|
| 972 | + break 2; |
|
| 973 | + } |
|
| 974 | + } |
|
| 975 | + $n++; |
|
| 976 | + $b = $p->boucles[$b]->id_parent; |
|
| 977 | + } |
|
| 978 | + |
|
| 979 | + // si on est hors d'une boucle de {recherche}, cette balise est vide |
|
| 980 | + if (!$p->code) { |
|
| 981 | + $p->code = "''"; |
|
| 982 | + } |
|
| 983 | + |
|
| 984 | + $p->interdire_scripts = false; |
|
| 985 | + |
|
| 986 | + return $p; |
|
| 987 | 987 | } |
| 988 | 988 | |
| 989 | 989 | /** |
@@ -993,7 +993,7 @@ discard block |
||
| 993 | 993 | * @return string Nom de la balise, avec indication de boucle explicite si présent. |
| 994 | 994 | */ |
| 995 | 995 | function zbug_presenter_champ($p, $champ = '') { |
| 996 | - $balise = $champ ?: $p->nom_champ; |
|
| 997 | - $explicite = $p->nom_boucle ? $p->nom_boucle . ':' : ''; |
|
| 998 | - return "#{$explicite}{$balise}"; |
|
| 996 | + $balise = $champ ?: $p->nom_champ; |
|
| 997 | + $explicite = $p->nom_boucle ? $p->nom_boucle . ':' : ''; |
|
| 998 | + return "#{$explicite}{$balise}"; |
|
| 999 | 999 | } |
@@ -11,187 +11,187 @@ |
||
| 11 | 11 | \***************************************************************************/ |
| 12 | 12 | |
| 13 | 13 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 14 | - return; |
|
| 14 | + return; |
|
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | function trace_query_start() { |
| 18 | - static $trace = '?'; |
|
| 19 | - if ($trace === '?' or defined('_DEBUG_TRACE_QUERIES')) { |
|
| 20 | - if (defined('_DEBUG_TRACE_QUERIES') and _DEBUG_TRACE_QUERIES) { |
|
| 21 | - $trace = true; |
|
| 22 | - } |
|
| 23 | - else { |
|
| 24 | - if (empty($GLOBALS['visiteur_session'])) { |
|
| 25 | - // si un anonyme fait un var_profile on est oblige de remplir le tableau des temps en attendant de savoir |
|
| 26 | - // car ici on ne sait pas si c'est un hit anonyme |
|
| 27 | - // ou une requete SQL faite avant chargement de la session |
|
| 28 | - $trace = (!empty($_GET['var_profile']) ? '?' : false); |
|
| 29 | - } |
|
| 30 | - else { |
|
| 31 | - include_spip('inc/autoriser'); |
|
| 32 | - // gare au bouclage sur calcul de droits au premier appel |
|
| 33 | - // A fortiori quand on demande une trace |
|
| 34 | - $trace = false; // on ne trace pas la requete provoquee par autoriser('debug') |
|
| 35 | - $trace = (!empty($_GET['var_profile']) and autoriser('debug')); |
|
| 36 | - } |
|
| 37 | - } |
|
| 38 | - } |
|
| 39 | - |
|
| 40 | - return $trace ? microtime() : 0; |
|
| 18 | + static $trace = '?'; |
|
| 19 | + if ($trace === '?' or defined('_DEBUG_TRACE_QUERIES')) { |
|
| 20 | + if (defined('_DEBUG_TRACE_QUERIES') and _DEBUG_TRACE_QUERIES) { |
|
| 21 | + $trace = true; |
|
| 22 | + } |
|
| 23 | + else { |
|
| 24 | + if (empty($GLOBALS['visiteur_session'])) { |
|
| 25 | + // si un anonyme fait un var_profile on est oblige de remplir le tableau des temps en attendant de savoir |
|
| 26 | + // car ici on ne sait pas si c'est un hit anonyme |
|
| 27 | + // ou une requete SQL faite avant chargement de la session |
|
| 28 | + $trace = (!empty($_GET['var_profile']) ? '?' : false); |
|
| 29 | + } |
|
| 30 | + else { |
|
| 31 | + include_spip('inc/autoriser'); |
|
| 32 | + // gare au bouclage sur calcul de droits au premier appel |
|
| 33 | + // A fortiori quand on demande une trace |
|
| 34 | + $trace = false; // on ne trace pas la requete provoquee par autoriser('debug') |
|
| 35 | + $trace = (!empty($_GET['var_profile']) and autoriser('debug')); |
|
| 36 | + } |
|
| 37 | + } |
|
| 38 | + } |
|
| 39 | + |
|
| 40 | + return $trace ? microtime() : 0; |
|
| 41 | 41 | } |
| 42 | 42 | |
| 43 | 43 | function trace_query_end($query, $start, $result, $erreur, $serveur = '') { |
| 44 | - static $trace = '?'; |
|
| 45 | - if ($trace === '?') { |
|
| 46 | - if (empty($GLOBALS['visiteur_session'])) { |
|
| 47 | - // si un anonyme fait un var_profile on est oblige de remplir le tableau des temps en attendant de savoir |
|
| 48 | - // car ici on ne sait pas si c'est un hit anonyme |
|
| 49 | - // ou une requete SQL faite avant chargement de la session |
|
| 50 | - $trace = (!empty($_GET['var_profile']) ? '?' : false); |
|
| 51 | - } |
|
| 52 | - else { |
|
| 53 | - include_spip('inc/autoriser'); |
|
| 54 | - // gare au bouclage sur calcul de droits au premier appel |
|
| 55 | - // A fortiori quand on demande une trace |
|
| 56 | - $trace = false; // on ne trace pas la requete provoquee par autoriser('debug') |
|
| 57 | - $trace = (!empty($_GET['var_profile']) and autoriser('debug')); |
|
| 58 | - } |
|
| 59 | - } |
|
| 60 | - if ($start) { |
|
| 61 | - $end = microtime(); |
|
| 62 | - [$usec, $sec] = explode(' ', $start); |
|
| 63 | - [$usec2, $sec2] = explode(' ', $end); |
|
| 64 | - $dt = $sec2 + $usec2 - $sec - $usec; |
|
| 65 | - pipeline('trig_trace_query', ['query' => $query, 'start' => $start, 'end' => $end, 'time' => $dt, 'result' => $result, 'erreur' => $erreur, 'serveur' => $serveur]); |
|
| 66 | - if ($trace) { |
|
| 67 | - trace_query_chrono($dt, $query, $result, $serveur); |
|
| 68 | - } |
|
| 69 | - } |
|
| 70 | - // tracer les erreurs, sauf pour select, c'est fait dans abstract_sql |
|
| 71 | - if ($trace and $erreur and !preg_match('/^select\b/i', $query)) { |
|
| 72 | - erreur_squelette([sql_errno($serveur), $erreur, $query]); |
|
| 73 | - } |
|
| 74 | - |
|
| 75 | - return $result; |
|
| 44 | + static $trace = '?'; |
|
| 45 | + if ($trace === '?') { |
|
| 46 | + if (empty($GLOBALS['visiteur_session'])) { |
|
| 47 | + // si un anonyme fait un var_profile on est oblige de remplir le tableau des temps en attendant de savoir |
|
| 48 | + // car ici on ne sait pas si c'est un hit anonyme |
|
| 49 | + // ou une requete SQL faite avant chargement de la session |
|
| 50 | + $trace = (!empty($_GET['var_profile']) ? '?' : false); |
|
| 51 | + } |
|
| 52 | + else { |
|
| 53 | + include_spip('inc/autoriser'); |
|
| 54 | + // gare au bouclage sur calcul de droits au premier appel |
|
| 55 | + // A fortiori quand on demande une trace |
|
| 56 | + $trace = false; // on ne trace pas la requete provoquee par autoriser('debug') |
|
| 57 | + $trace = (!empty($_GET['var_profile']) and autoriser('debug')); |
|
| 58 | + } |
|
| 59 | + } |
|
| 60 | + if ($start) { |
|
| 61 | + $end = microtime(); |
|
| 62 | + [$usec, $sec] = explode(' ', $start); |
|
| 63 | + [$usec2, $sec2] = explode(' ', $end); |
|
| 64 | + $dt = $sec2 + $usec2 - $sec - $usec; |
|
| 65 | + pipeline('trig_trace_query', ['query' => $query, 'start' => $start, 'end' => $end, 'time' => $dt, 'result' => $result, 'erreur' => $erreur, 'serveur' => $serveur]); |
|
| 66 | + if ($trace) { |
|
| 67 | + trace_query_chrono($dt, $query, $result, $serveur); |
|
| 68 | + } |
|
| 69 | + } |
|
| 70 | + // tracer les erreurs, sauf pour select, c'est fait dans abstract_sql |
|
| 71 | + if ($trace and $erreur and !preg_match('/^select\b/i', $query)) { |
|
| 72 | + erreur_squelette([sql_errno($serveur), $erreur, $query]); |
|
| 73 | + } |
|
| 74 | + |
|
| 75 | + return $result; |
|
| 76 | 76 | } |
| 77 | 77 | |
| 78 | 78 | function trace_query_chrono($dt, $query, $result, $serveur = '') { |
| 79 | - include_spip('inc/filtres_mini'); |
|
| 80 | - static $tt = 0, $nb = 0; |
|
| 81 | - |
|
| 82 | - $x = _request('var_mode_objet'); |
|
| 83 | - if (isset($GLOBALS['debug']['aucasou'])) { |
|
| 84 | - [, $boucle, $serveur, $contexte] = $GLOBALS['debug']['aucasou']; |
|
| 85 | - if ($x and !preg_match("/$boucle\$/", $x)) { |
|
| 86 | - return; |
|
| 87 | - } |
|
| 88 | - if ($serveur) { |
|
| 89 | - $boucle .= " ($serveur)"; |
|
| 90 | - } |
|
| 91 | - $boucle = "<b>$boucle</b>"; |
|
| 92 | - } else { |
|
| 93 | - if ($x) { |
|
| 94 | - return; |
|
| 95 | - } |
|
| 96 | - $boucle = $contexte = ''; |
|
| 97 | - } |
|
| 98 | - |
|
| 99 | - $tt += $dt; |
|
| 100 | - $nb++; |
|
| 101 | - |
|
| 102 | - $q = preg_replace('/([a-z)`])\s+([A-Z])/', "$1\n<br />$2", spip_htmlentities($query)); |
|
| 103 | - $e = sql_explain($query, $serveur); |
|
| 104 | - $r = str_replace('Resource id ', '', (is_object($result) ? get_class($result) : $result)); |
|
| 105 | - $GLOBALS['tableau_des_temps'][] = [$dt, $nb, $boucle, $q, $e, $r, $contexte]; |
|
| 79 | + include_spip('inc/filtres_mini'); |
|
| 80 | + static $tt = 0, $nb = 0; |
|
| 81 | + |
|
| 82 | + $x = _request('var_mode_objet'); |
|
| 83 | + if (isset($GLOBALS['debug']['aucasou'])) { |
|
| 84 | + [, $boucle, $serveur, $contexte] = $GLOBALS['debug']['aucasou']; |
|
| 85 | + if ($x and !preg_match("/$boucle\$/", $x)) { |
|
| 86 | + return; |
|
| 87 | + } |
|
| 88 | + if ($serveur) { |
|
| 89 | + $boucle .= " ($serveur)"; |
|
| 90 | + } |
|
| 91 | + $boucle = "<b>$boucle</b>"; |
|
| 92 | + } else { |
|
| 93 | + if ($x) { |
|
| 94 | + return; |
|
| 95 | + } |
|
| 96 | + $boucle = $contexte = ''; |
|
| 97 | + } |
|
| 98 | + |
|
| 99 | + $tt += $dt; |
|
| 100 | + $nb++; |
|
| 101 | + |
|
| 102 | + $q = preg_replace('/([a-z)`])\s+([A-Z])/', "$1\n<br />$2", spip_htmlentities($query)); |
|
| 103 | + $e = sql_explain($query, $serveur); |
|
| 104 | + $r = str_replace('Resource id ', '', (is_object($result) ? get_class($result) : $result)); |
|
| 105 | + $GLOBALS['tableau_des_temps'][] = [$dt, $nb, $boucle, $q, $e, $r, $contexte]; |
|
| 106 | 106 | } |
| 107 | 107 | |
| 108 | 108 | |
| 109 | 109 | function chrono_requete($temps) { |
| 110 | - $total = 0; |
|
| 111 | - $hors = '<i>' . _T('zbug_hors_compilation') . '</i>'; |
|
| 112 | - $t = $q = $n = $d = []; |
|
| 113 | - // Totaliser les temps et completer le Explain |
|
| 114 | - foreach ($temps as $key => $v) { |
|
| 115 | - [$dt, $nb, $boucle, $query, $explain, $res, $contexte] = $v; |
|
| 116 | - if (is_array($contexte)) { |
|
| 117 | - $k = ($contexte[0] . " $boucle"); |
|
| 118 | - include_spip('public/compiler'); |
|
| 119 | - $env = reconstruire_contexte_compil($contexte); |
|
| 120 | - } else { |
|
| 121 | - $k = $env = $boucle; |
|
| 122 | - } |
|
| 123 | - |
|
| 124 | - $total += $dt; |
|
| 125 | - $t[$key] = $dt; |
|
| 126 | - $q[$key] = $nb; |
|
| 127 | - if (!isset($d[$k])) { |
|
| 128 | - $d[$k] = 0; |
|
| 129 | - $n[$k] = 0; |
|
| 130 | - } |
|
| 131 | - $d[$k] += $dt; |
|
| 132 | - ++$n[$k]; |
|
| 133 | - |
|
| 134 | - if (!is_array($explain)) { |
|
| 135 | - $explain = []; |
|
| 136 | - } |
|
| 137 | - foreach ($explain as $j => $v) { |
|
| 138 | - $explain[$j] = "<tr><th>$j</th><td>" |
|
| 139 | - . str_replace(';', '<br />', $v) |
|
| 140 | - . '</td></tr>'; |
|
| 141 | - } |
|
| 142 | - $e = "<table class='explain'>" |
|
| 143 | - . '<caption>' |
|
| 144 | - . $query |
|
| 145 | - . '</caption>' |
|
| 146 | - . "<tr><th>Time</th><td>$dt</td></tr>" |
|
| 147 | - . "<tr><th>Order</th><td>$nb</td></tr>" |
|
| 148 | - . "<tr><th>Res</th><td>$res</td></tr>" |
|
| 149 | - . join('', $explain) |
|
| 150 | - . '</table>'; |
|
| 151 | - |
|
| 152 | - $temps[$key] = [$e, $env, $k]; |
|
| 153 | - } |
|
| 154 | - // Trier par temps d'execution decroissant |
|
| 155 | - array_multisort($t, SORT_DESC, $q, $temps); |
|
| 156 | - arsort($d); |
|
| 157 | - $i = 1; |
|
| 158 | - $t = []; |
|
| 159 | - // Fabriquer les liens de navigations dans le tableau des temps |
|
| 160 | - foreach ($temps as $k => $v) { |
|
| 161 | - $titre = strip_tags($v[2]); |
|
| 162 | - $href = quote_amp($GLOBALS['REQUEST_URI']) . "#req$i"; |
|
| 163 | - $href = str_replace("\\'", ''', $href); |
|
| 164 | - |
|
| 165 | - if (!isset($t[$v[2]])) { |
|
| 166 | - $t[$v[2]] = []; |
|
| 167 | - } |
|
| 168 | - $t[$v[2]][] = "<span class='spip-debug-arg'> " |
|
| 169 | - . "<a title='$titre' href='$href'>$i</a>" |
|
| 170 | - . '</span>' |
|
| 171 | - . ((count($t[$v[2]]) % 10 == 9) ? '<br />' : ''); |
|
| 172 | - $i++; |
|
| 173 | - } |
|
| 174 | - |
|
| 175 | - if ($d['']) { |
|
| 176 | - $d[$hors] = $d['']; |
|
| 177 | - $n[$hors] = $n['']; |
|
| 178 | - $t[$hors] = $t['']; |
|
| 179 | - } |
|
| 180 | - unset($d['']); |
|
| 181 | - // Fabriquer le tableau des liens de navigation dans le grand tableau |
|
| 182 | - foreach ($d as $k => $v) { |
|
| 183 | - $d[$k] = $n[$k] . "</td><td>$k</td><td class='time'>$v</td><td class='liste-reqs'>" |
|
| 184 | - . join('', $t[$k]); |
|
| 185 | - } |
|
| 186 | - |
|
| 187 | - $navigation = [ |
|
| 188 | - _T('zbug_statistiques'), |
|
| 189 | - '<tr><td>' |
|
| 190 | - . join("</td></tr>\n<tr><td>", $d) |
|
| 191 | - . "</td></tr>\n" |
|
| 192 | - . (# _request('var_mode_objet') ? '' : |
|
| 193 | - ('<tr><td>' . (is_countable($temps) ? count($temps) : 0) . '</td><td>' . _T('info_total') . '</td><td class="time">' . $total . '</td><td></td></tr>')) |
|
| 194 | - ]; |
|
| 195 | - |
|
| 196 | - return [$temps, $navigation]; |
|
| 110 | + $total = 0; |
|
| 111 | + $hors = '<i>' . _T('zbug_hors_compilation') . '</i>'; |
|
| 112 | + $t = $q = $n = $d = []; |
|
| 113 | + // Totaliser les temps et completer le Explain |
|
| 114 | + foreach ($temps as $key => $v) { |
|
| 115 | + [$dt, $nb, $boucle, $query, $explain, $res, $contexte] = $v; |
|
| 116 | + if (is_array($contexte)) { |
|
| 117 | + $k = ($contexte[0] . " $boucle"); |
|
| 118 | + include_spip('public/compiler'); |
|
| 119 | + $env = reconstruire_contexte_compil($contexte); |
|
| 120 | + } else { |
|
| 121 | + $k = $env = $boucle; |
|
| 122 | + } |
|
| 123 | + |
|
| 124 | + $total += $dt; |
|
| 125 | + $t[$key] = $dt; |
|
| 126 | + $q[$key] = $nb; |
|
| 127 | + if (!isset($d[$k])) { |
|
| 128 | + $d[$k] = 0; |
|
| 129 | + $n[$k] = 0; |
|
| 130 | + } |
|
| 131 | + $d[$k] += $dt; |
|
| 132 | + ++$n[$k]; |
|
| 133 | + |
|
| 134 | + if (!is_array($explain)) { |
|
| 135 | + $explain = []; |
|
| 136 | + } |
|
| 137 | + foreach ($explain as $j => $v) { |
|
| 138 | + $explain[$j] = "<tr><th>$j</th><td>" |
|
| 139 | + . str_replace(';', '<br />', $v) |
|
| 140 | + . '</td></tr>'; |
|
| 141 | + } |
|
| 142 | + $e = "<table class='explain'>" |
|
| 143 | + . '<caption>' |
|
| 144 | + . $query |
|
| 145 | + . '</caption>' |
|
| 146 | + . "<tr><th>Time</th><td>$dt</td></tr>" |
|
| 147 | + . "<tr><th>Order</th><td>$nb</td></tr>" |
|
| 148 | + . "<tr><th>Res</th><td>$res</td></tr>" |
|
| 149 | + . join('', $explain) |
|
| 150 | + . '</table>'; |
|
| 151 | + |
|
| 152 | + $temps[$key] = [$e, $env, $k]; |
|
| 153 | + } |
|
| 154 | + // Trier par temps d'execution decroissant |
|
| 155 | + array_multisort($t, SORT_DESC, $q, $temps); |
|
| 156 | + arsort($d); |
|
| 157 | + $i = 1; |
|
| 158 | + $t = []; |
|
| 159 | + // Fabriquer les liens de navigations dans le tableau des temps |
|
| 160 | + foreach ($temps as $k => $v) { |
|
| 161 | + $titre = strip_tags($v[2]); |
|
| 162 | + $href = quote_amp($GLOBALS['REQUEST_URI']) . "#req$i"; |
|
| 163 | + $href = str_replace("\\'", ''', $href); |
|
| 164 | + |
|
| 165 | + if (!isset($t[$v[2]])) { |
|
| 166 | + $t[$v[2]] = []; |
|
| 167 | + } |
|
| 168 | + $t[$v[2]][] = "<span class='spip-debug-arg'> " |
|
| 169 | + . "<a title='$titre' href='$href'>$i</a>" |
|
| 170 | + . '</span>' |
|
| 171 | + . ((count($t[$v[2]]) % 10 == 9) ? '<br />' : ''); |
|
| 172 | + $i++; |
|
| 173 | + } |
|
| 174 | + |
|
| 175 | + if ($d['']) { |
|
| 176 | + $d[$hors] = $d['']; |
|
| 177 | + $n[$hors] = $n['']; |
|
| 178 | + $t[$hors] = $t['']; |
|
| 179 | + } |
|
| 180 | + unset($d['']); |
|
| 181 | + // Fabriquer le tableau des liens de navigation dans le grand tableau |
|
| 182 | + foreach ($d as $k => $v) { |
|
| 183 | + $d[$k] = $n[$k] . "</td><td>$k</td><td class='time'>$v</td><td class='liste-reqs'>" |
|
| 184 | + . join('', $t[$k]); |
|
| 185 | + } |
|
| 186 | + |
|
| 187 | + $navigation = [ |
|
| 188 | + _T('zbug_statistiques'), |
|
| 189 | + '<tr><td>' |
|
| 190 | + . join("</td></tr>\n<tr><td>", $d) |
|
| 191 | + . "</td></tr>\n" |
|
| 192 | + . (# _request('var_mode_objet') ? '' : |
|
| 193 | + ('<tr><td>' . (is_countable($temps) ? count($temps) : 0) . '</td><td>' . _T('info_total') . '</td><td class="time">' . $total . '</td><td></td></tr>')) |
|
| 194 | + ]; |
|
| 195 | + |
|
| 196 | + return [$temps, $navigation]; |
|
| 197 | 197 | } |
@@ -18,7 +18,7 @@ discard block |
||
| 18 | 18 | **/ |
| 19 | 19 | |
| 20 | 20 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 21 | - return; |
|
| 21 | + return; |
|
| 22 | 22 | } |
| 23 | 23 | |
| 24 | 24 | include_spip('inc/texte'); |
@@ -42,233 +42,233 @@ discard block |
||
| 42 | 42 | |
| 43 | 43 | function public_composer_dist($squelette, $mime_type, $gram, $source, string $connect = '') { |
| 44 | 44 | |
| 45 | - $skel = null; |
|
| 46 | - $boucle = null; |
|
| 47 | - $nom = calculer_nom_fonction_squel($squelette, $mime_type, $connect); |
|
| 48 | - |
|
| 49 | - // si deja en memoire (INCLURE a repetition) c'est bon. |
|
| 50 | - if (function_exists($nom)) { |
|
| 51 | - return $nom; |
|
| 52 | - } |
|
| 53 | - |
|
| 54 | - if (defined('_VAR_MODE') and _VAR_MODE == 'debug') { |
|
| 55 | - $GLOBALS['debug_objets']['courant'] = $nom; |
|
| 56 | - } |
|
| 57 | - |
|
| 58 | - $phpfile = sous_repertoire(_DIR_SKELS, '', false, true) . $nom . '.php'; |
|
| 59 | - |
|
| 60 | - // si squelette est deja compile et perenne, le charger |
|
| 61 | - if (!squelette_obsolete($phpfile, $source)) { |
|
| 62 | - include_once $phpfile; |
|
| 63 | - #if (!squelette_obsolete($phpfile, $source) |
|
| 64 | - # AND lire_fichier ($phpfile, $skel_code, |
|
| 65 | - # array('critique' => 'oui', 'phpcheck' => 'oui'))){ |
|
| 66 | - ## eval('?'.'>'.$skel_code); |
|
| 67 | - # spip_log($skel_code, 'comp') |
|
| 68 | - #} |
|
| 69 | - } |
|
| 70 | - |
|
| 71 | - if (file_exists($lib = $squelette . '_fonctions' . '.php')) { |
|
| 72 | - include_once $lib; |
|
| 73 | - } |
|
| 74 | - |
|
| 75 | - // tester si le eval ci-dessus a mis le squelette en memoire |
|
| 76 | - |
|
| 77 | - if (function_exists($nom)) { |
|
| 78 | - return $nom; |
|
| 79 | - } |
|
| 80 | - |
|
| 81 | - // charger le source, si possible, et compiler |
|
| 82 | - $skel_code = ''; |
|
| 83 | - if (lire_fichier($source, $skel)) { |
|
| 84 | - $compiler = charger_fonction('compiler', 'public'); |
|
| 85 | - $skel_code = $compiler($skel, $nom, $gram, $source, $connect); |
|
| 86 | - } |
|
| 87 | - |
|
| 88 | - // Ne plus rien faire si le compilateur n'a pas pu operer. |
|
| 89 | - if (!$skel_code) { |
|
| 90 | - return false; |
|
| 91 | - } |
|
| 92 | - |
|
| 93 | - foreach ($skel_code as $id => $boucle) { |
|
| 94 | - $f = $boucle->return; |
|
| 95 | - try { |
|
| 96 | - eval("return true; $f ;"); |
|
| 97 | - } catch (\ParseError $e) { |
|
| 98 | - // Code syntaxiquement faux (critere etc mal programme') |
|
| 99 | - $msg = _T('zbug_erreur_compilation') . ' | Line ' . $e->getLine() . ' : ' . $e->getMessage(); |
|
| 100 | - erreur_squelette($msg, $boucle); |
|
| 101 | - // continuer pour trouver d'autres fautes eventuelles |
|
| 102 | - // mais prevenir que c'est mort |
|
| 103 | - $nom = ''; |
|
| 104 | - } |
|
| 105 | - |
|
| 106 | - // Contexte de compil inutile a present |
|
| 107 | - // (mais la derniere valeur de $boucle est utilisee ci-dessous) |
|
| 108 | - $skel_code[$id] = $f; |
|
| 109 | - } |
|
| 110 | - |
|
| 111 | - $code = ''; |
|
| 112 | - if ($nom) { |
|
| 113 | - // Si le code est bon, concatener et mettre en cache |
|
| 114 | - if (function_exists($nom)) { |
|
| 115 | - $code = squelette_traduit($skel, $source, $phpfile, $skel_code); |
|
| 116 | - } else { |
|
| 117 | - // code semantiquement faux: bug du compilateur |
|
| 118 | - // $boucle est en fait ici la fct principale du squelette |
|
| 119 | - $msg = _T('zbug_erreur_compilation'); |
|
| 120 | - erreur_squelette($msg, $boucle); |
|
| 121 | - $nom = ''; |
|
| 122 | - } |
|
| 123 | - } |
|
| 124 | - |
|
| 125 | - if (defined('_VAR_MODE') and _VAR_MODE == 'debug') { |
|
| 126 | - // Tracer ce qui vient d'etre compile |
|
| 127 | - $GLOBALS['debug_objets']['code'][$nom . 'tout'] = $code; |
|
| 128 | - |
|
| 129 | - // si c'est ce que demande le debusqueur, lui passer la main |
|
| 130 | - if ( |
|
| 131 | - $GLOBALS['debug_objets']['sourcefile'] |
|
| 132 | - and (_request('var_mode_objet') == $nom) |
|
| 133 | - and (_request('var_mode_affiche') == 'code') |
|
| 134 | - ) { |
|
| 135 | - erreur_squelette(); |
|
| 136 | - } |
|
| 137 | - } |
|
| 138 | - |
|
| 139 | - return $nom ?: false; |
|
| 45 | + $skel = null; |
|
| 46 | + $boucle = null; |
|
| 47 | + $nom = calculer_nom_fonction_squel($squelette, $mime_type, $connect); |
|
| 48 | + |
|
| 49 | + // si deja en memoire (INCLURE a repetition) c'est bon. |
|
| 50 | + if (function_exists($nom)) { |
|
| 51 | + return $nom; |
|
| 52 | + } |
|
| 53 | + |
|
| 54 | + if (defined('_VAR_MODE') and _VAR_MODE == 'debug') { |
|
| 55 | + $GLOBALS['debug_objets']['courant'] = $nom; |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + $phpfile = sous_repertoire(_DIR_SKELS, '', false, true) . $nom . '.php'; |
|
| 59 | + |
|
| 60 | + // si squelette est deja compile et perenne, le charger |
|
| 61 | + if (!squelette_obsolete($phpfile, $source)) { |
|
| 62 | + include_once $phpfile; |
|
| 63 | + #if (!squelette_obsolete($phpfile, $source) |
|
| 64 | + # AND lire_fichier ($phpfile, $skel_code, |
|
| 65 | + # array('critique' => 'oui', 'phpcheck' => 'oui'))){ |
|
| 66 | + ## eval('?'.'>'.$skel_code); |
|
| 67 | + # spip_log($skel_code, 'comp') |
|
| 68 | + #} |
|
| 69 | + } |
|
| 70 | + |
|
| 71 | + if (file_exists($lib = $squelette . '_fonctions' . '.php')) { |
|
| 72 | + include_once $lib; |
|
| 73 | + } |
|
| 74 | + |
|
| 75 | + // tester si le eval ci-dessus a mis le squelette en memoire |
|
| 76 | + |
|
| 77 | + if (function_exists($nom)) { |
|
| 78 | + return $nom; |
|
| 79 | + } |
|
| 80 | + |
|
| 81 | + // charger le source, si possible, et compiler |
|
| 82 | + $skel_code = ''; |
|
| 83 | + if (lire_fichier($source, $skel)) { |
|
| 84 | + $compiler = charger_fonction('compiler', 'public'); |
|
| 85 | + $skel_code = $compiler($skel, $nom, $gram, $source, $connect); |
|
| 86 | + } |
|
| 87 | + |
|
| 88 | + // Ne plus rien faire si le compilateur n'a pas pu operer. |
|
| 89 | + if (!$skel_code) { |
|
| 90 | + return false; |
|
| 91 | + } |
|
| 92 | + |
|
| 93 | + foreach ($skel_code as $id => $boucle) { |
|
| 94 | + $f = $boucle->return; |
|
| 95 | + try { |
|
| 96 | + eval("return true; $f ;"); |
|
| 97 | + } catch (\ParseError $e) { |
|
| 98 | + // Code syntaxiquement faux (critere etc mal programme') |
|
| 99 | + $msg = _T('zbug_erreur_compilation') . ' | Line ' . $e->getLine() . ' : ' . $e->getMessage(); |
|
| 100 | + erreur_squelette($msg, $boucle); |
|
| 101 | + // continuer pour trouver d'autres fautes eventuelles |
|
| 102 | + // mais prevenir que c'est mort |
|
| 103 | + $nom = ''; |
|
| 104 | + } |
|
| 105 | + |
|
| 106 | + // Contexte de compil inutile a present |
|
| 107 | + // (mais la derniere valeur de $boucle est utilisee ci-dessous) |
|
| 108 | + $skel_code[$id] = $f; |
|
| 109 | + } |
|
| 110 | + |
|
| 111 | + $code = ''; |
|
| 112 | + if ($nom) { |
|
| 113 | + // Si le code est bon, concatener et mettre en cache |
|
| 114 | + if (function_exists($nom)) { |
|
| 115 | + $code = squelette_traduit($skel, $source, $phpfile, $skel_code); |
|
| 116 | + } else { |
|
| 117 | + // code semantiquement faux: bug du compilateur |
|
| 118 | + // $boucle est en fait ici la fct principale du squelette |
|
| 119 | + $msg = _T('zbug_erreur_compilation'); |
|
| 120 | + erreur_squelette($msg, $boucle); |
|
| 121 | + $nom = ''; |
|
| 122 | + } |
|
| 123 | + } |
|
| 124 | + |
|
| 125 | + if (defined('_VAR_MODE') and _VAR_MODE == 'debug') { |
|
| 126 | + // Tracer ce qui vient d'etre compile |
|
| 127 | + $GLOBALS['debug_objets']['code'][$nom . 'tout'] = $code; |
|
| 128 | + |
|
| 129 | + // si c'est ce que demande le debusqueur, lui passer la main |
|
| 130 | + if ( |
|
| 131 | + $GLOBALS['debug_objets']['sourcefile'] |
|
| 132 | + and (_request('var_mode_objet') == $nom) |
|
| 133 | + and (_request('var_mode_affiche') == 'code') |
|
| 134 | + ) { |
|
| 135 | + erreur_squelette(); |
|
| 136 | + } |
|
| 137 | + } |
|
| 138 | + |
|
| 139 | + return $nom ?: false; |
|
| 140 | 140 | } |
| 141 | 141 | |
| 142 | 142 | function squelette_traduit($squelette, $sourcefile, $phpfile, $boucles) { |
| 143 | 143 | |
| 144 | - $code = null; |
|
| 145 | - // Le dernier index est '' (fonction principale) |
|
| 146 | - $noms = substr(join(', ', array_keys($boucles)), 0, -2); |
|
| 147 | - if (CODE_COMMENTE) { |
|
| 148 | - $code = " |
|
| 144 | + $code = null; |
|
| 145 | + // Le dernier index est '' (fonction principale) |
|
| 146 | + $noms = substr(join(', ', array_keys($boucles)), 0, -2); |
|
| 147 | + if (CODE_COMMENTE) { |
|
| 148 | + $code = " |
|
| 149 | 149 | /* |
| 150 | 150 | * Squelette : $sourcefile |
| 151 | 151 | * Date : " . gmdate('D, d M Y H:i:s', @filemtime($sourcefile)) . ' GMT |
| 152 | 152 | * Compile : ' . gmdate('D, d M Y H:i:s', time()) . ' GMT |
| 153 | 153 | * ' . (!$boucles ? 'Pas de boucle' : ('Boucles : ' . $noms)) . ' |
| 154 | 154 | */ '; |
| 155 | - } |
|
| 155 | + } |
|
| 156 | 156 | |
| 157 | - $code = '<' . "?php\n" . $code . join('', $boucles) . "\n?" . '>'; |
|
| 158 | - if (!defined('_VAR_NOCACHE') or !_VAR_NOCACHE) { |
|
| 159 | - ecrire_fichier($phpfile, $code); |
|
| 160 | - } |
|
| 157 | + $code = '<' . "?php\n" . $code . join('', $boucles) . "\n?" . '>'; |
|
| 158 | + if (!defined('_VAR_NOCACHE') or !_VAR_NOCACHE) { |
|
| 159 | + ecrire_fichier($phpfile, $code); |
|
| 160 | + } |
|
| 161 | 161 | |
| 162 | - return $code; |
|
| 162 | + return $code; |
|
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | // Le squelette compile est-il trop vieux ? |
| 166 | 166 | function squelette_obsolete($skel, $squelette) { |
| 167 | - static $date_change = null; |
|
| 168 | - // ne verifier la date de mes_fonctions et mes_options qu'une seule fois |
|
| 169 | - // par hit |
|
| 170 | - if (is_null($date_change)) { |
|
| 171 | - if (@file_exists($fonc = 'mes_fonctions.php')) { |
|
| 172 | - $date_change = @filemtime($fonc); |
|
| 173 | - } # compatibilite |
|
| 174 | - if (defined('_FILE_OPTIONS')) { |
|
| 175 | - $date_change = max($date_change, @filemtime(_FILE_OPTIONS)); |
|
| 176 | - } |
|
| 177 | - } |
|
| 178 | - |
|
| 179 | - return ( |
|
| 180 | - (defined('_VAR_MODE') and in_array(_VAR_MODE, ['recalcul', 'preview', 'debug'])) |
|
| 181 | - or !@file_exists($skel) |
|
| 182 | - or ((@file_exists($squelette) ? @filemtime($squelette) : 0) |
|
| 183 | - > ($date = @filemtime($skel))) |
|
| 184 | - or ($date_change > $date) |
|
| 185 | - ); |
|
| 167 | + static $date_change = null; |
|
| 168 | + // ne verifier la date de mes_fonctions et mes_options qu'une seule fois |
|
| 169 | + // par hit |
|
| 170 | + if (is_null($date_change)) { |
|
| 171 | + if (@file_exists($fonc = 'mes_fonctions.php')) { |
|
| 172 | + $date_change = @filemtime($fonc); |
|
| 173 | + } # compatibilite |
|
| 174 | + if (defined('_FILE_OPTIONS')) { |
|
| 175 | + $date_change = max($date_change, @filemtime(_FILE_OPTIONS)); |
|
| 176 | + } |
|
| 177 | + } |
|
| 178 | + |
|
| 179 | + return ( |
|
| 180 | + (defined('_VAR_MODE') and in_array(_VAR_MODE, ['recalcul', 'preview', 'debug'])) |
|
| 181 | + or !@file_exists($skel) |
|
| 182 | + or ((@file_exists($squelette) ? @filemtime($squelette) : 0) |
|
| 183 | + > ($date = @filemtime($skel))) |
|
| 184 | + or ($date_change > $date) |
|
| 185 | + ); |
|
| 186 | 186 | } |
| 187 | 187 | |
| 188 | 188 | // Activer l'invalideur de session |
| 189 | 189 | function invalideur_session(&$Cache, $code = null) { |
| 190 | - $Cache['session'] = spip_session(); |
|
| 190 | + $Cache['session'] = spip_session(); |
|
| 191 | 191 | |
| 192 | - return $code; |
|
| 192 | + return $code; |
|
| 193 | 193 | } |
| 194 | 194 | |
| 195 | 195 | |
| 196 | 196 | function analyse_resultat_skel($nom, $cache, $corps, $source = '') { |
| 197 | - static $filtres = []; |
|
| 198 | - $headers = []; |
|
| 199 | - |
|
| 200 | - // Recupere les < ?php header('Xx: y'); ? > pour $page['headers'] |
|
| 201 | - // note: on essaie d'attrapper aussi certains de ces entetes codes |
|
| 202 | - // "a la main" dans les squelettes, mais evidemment sans exhaustivite |
|
| 203 | - if ( |
|
| 204 | - stripos($corps, 'header') !== false |
|
| 205 | - and preg_match_all( |
|
| 206 | - '/(<[?]php\s+)@?header\s*\(\s*.([^:\'"]*):?\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims', |
|
| 207 | - $corps, |
|
| 208 | - $regs, |
|
| 209 | - PREG_SET_ORDER |
|
| 210 | - ) |
|
| 211 | - ) { |
|
| 212 | - foreach ($regs as $r) { |
|
| 213 | - $corps = str_replace($r[0], '', $corps); |
|
| 214 | - # $j = Content-Type, et pas content-TYPE. |
|
| 215 | - $j = join('-', array_map('ucwords', explode('-', strtolower($r[2])))); |
|
| 216 | - |
|
| 217 | - if ($j == 'X-Spip-Filtre' and isset($headers[$j])) { |
|
| 218 | - $headers[$j] .= '|' . $r[3]; |
|
| 219 | - } else { |
|
| 220 | - $headers[$j] = $r[3]; |
|
| 221 | - } |
|
| 222 | - } |
|
| 223 | - } |
|
| 224 | - // S'agit-il d'un resultat constant ou contenant du code php |
|
| 225 | - $process_ins = ( |
|
| 226 | - strpos($corps, '<' . '?') === false |
|
| 227 | - or |
|
| 228 | - (strpos($corps, '<' . '?xml') !== false and |
|
| 229 | - strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false) |
|
| 230 | - ) |
|
| 231 | - ? 'html' |
|
| 232 | - : 'php'; |
|
| 233 | - |
|
| 234 | - $skel = [ |
|
| 235 | - 'squelette' => $nom, |
|
| 236 | - 'source' => $source, |
|
| 237 | - 'process_ins' => $process_ins, |
|
| 238 | - 'invalideurs' => $cache, |
|
| 239 | - 'entetes' => $headers, |
|
| 240 | - 'duree' => isset($headers['X-Spip-Cache']) ? intval($headers['X-Spip-Cache']) : 0 |
|
| 241 | - ]; |
|
| 242 | - |
|
| 243 | - // traiter #FILTRE{} et filtres |
|
| 244 | - if (!isset($filtres[$nom])) { |
|
| 245 | - $filtres[$nom] = pipeline('declarer_filtres_squelettes', ['args' => $skel, 'data' => []]); |
|
| 246 | - } |
|
| 247 | - $filtres_headers = []; |
|
| 248 | - if (isset($headers['X-Spip-Filtre']) and strlen($headers['X-Spip-Filtre'])) { |
|
| 249 | - $filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre'])); |
|
| 250 | - unset($headers['X-Spip-Filtre']); |
|
| 251 | - } |
|
| 252 | - if (is_array($filtres[$nom]) || $filtres[$nom] instanceof \Countable ? count($filtres[$nom]) : 0 or count($filtres_headers)) { |
|
| 253 | - include_spip('public/sandbox'); |
|
| 254 | - $corps = sandbox_filtrer_squelette($skel, $corps, $filtres_headers, $filtres[$nom]); |
|
| 255 | - |
|
| 256 | - if ($process_ins == 'html') { |
|
| 257 | - $skel['process_ins'] = ( |
|
| 258 | - strpos($corps, '<' . '?') === false |
|
| 259 | - or |
|
| 260 | - (strpos($corps, '<' . '?xml') !== false and |
|
| 261 | - strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false) |
|
| 262 | - ) |
|
| 263 | - ? 'html' |
|
| 264 | - : 'php'; |
|
| 265 | - } |
|
| 266 | - } |
|
| 267 | - |
|
| 268 | - $skel['entetes'] = $headers; |
|
| 269 | - $skel['texte'] = $corps; |
|
| 270 | - |
|
| 271 | - return $skel; |
|
| 197 | + static $filtres = []; |
|
| 198 | + $headers = []; |
|
| 199 | + |
|
| 200 | + // Recupere les < ?php header('Xx: y'); ? > pour $page['headers'] |
|
| 201 | + // note: on essaie d'attrapper aussi certains de ces entetes codes |
|
| 202 | + // "a la main" dans les squelettes, mais evidemment sans exhaustivite |
|
| 203 | + if ( |
|
| 204 | + stripos($corps, 'header') !== false |
|
| 205 | + and preg_match_all( |
|
| 206 | + '/(<[?]php\s+)@?header\s*\(\s*.([^:\'"]*):?\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims', |
|
| 207 | + $corps, |
|
| 208 | + $regs, |
|
| 209 | + PREG_SET_ORDER |
|
| 210 | + ) |
|
| 211 | + ) { |
|
| 212 | + foreach ($regs as $r) { |
|
| 213 | + $corps = str_replace($r[0], '', $corps); |
|
| 214 | + # $j = Content-Type, et pas content-TYPE. |
|
| 215 | + $j = join('-', array_map('ucwords', explode('-', strtolower($r[2])))); |
|
| 216 | + |
|
| 217 | + if ($j == 'X-Spip-Filtre' and isset($headers[$j])) { |
|
| 218 | + $headers[$j] .= '|' . $r[3]; |
|
| 219 | + } else { |
|
| 220 | + $headers[$j] = $r[3]; |
|
| 221 | + } |
|
| 222 | + } |
|
| 223 | + } |
|
| 224 | + // S'agit-il d'un resultat constant ou contenant du code php |
|
| 225 | + $process_ins = ( |
|
| 226 | + strpos($corps, '<' . '?') === false |
|
| 227 | + or |
|
| 228 | + (strpos($corps, '<' . '?xml') !== false and |
|
| 229 | + strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false) |
|
| 230 | + ) |
|
| 231 | + ? 'html' |
|
| 232 | + : 'php'; |
|
| 233 | + |
|
| 234 | + $skel = [ |
|
| 235 | + 'squelette' => $nom, |
|
| 236 | + 'source' => $source, |
|
| 237 | + 'process_ins' => $process_ins, |
|
| 238 | + 'invalideurs' => $cache, |
|
| 239 | + 'entetes' => $headers, |
|
| 240 | + 'duree' => isset($headers['X-Spip-Cache']) ? intval($headers['X-Spip-Cache']) : 0 |
|
| 241 | + ]; |
|
| 242 | + |
|
| 243 | + // traiter #FILTRE{} et filtres |
|
| 244 | + if (!isset($filtres[$nom])) { |
|
| 245 | + $filtres[$nom] = pipeline('declarer_filtres_squelettes', ['args' => $skel, 'data' => []]); |
|
| 246 | + } |
|
| 247 | + $filtres_headers = []; |
|
| 248 | + if (isset($headers['X-Spip-Filtre']) and strlen($headers['X-Spip-Filtre'])) { |
|
| 249 | + $filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre'])); |
|
| 250 | + unset($headers['X-Spip-Filtre']); |
|
| 251 | + } |
|
| 252 | + if (is_array($filtres[$nom]) || $filtres[$nom] instanceof \Countable ? count($filtres[$nom]) : 0 or count($filtres_headers)) { |
|
| 253 | + include_spip('public/sandbox'); |
|
| 254 | + $corps = sandbox_filtrer_squelette($skel, $corps, $filtres_headers, $filtres[$nom]); |
|
| 255 | + |
|
| 256 | + if ($process_ins == 'html') { |
|
| 257 | + $skel['process_ins'] = ( |
|
| 258 | + strpos($corps, '<' . '?') === false |
|
| 259 | + or |
|
| 260 | + (strpos($corps, '<' . '?xml') !== false and |
|
| 261 | + strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false) |
|
| 262 | + ) |
|
| 263 | + ? 'html' |
|
| 264 | + : 'php'; |
|
| 265 | + } |
|
| 266 | + } |
|
| 267 | + |
|
| 268 | + $skel['entetes'] = $headers; |
|
| 269 | + $skel['texte'] = $corps; |
|
| 270 | + |
|
| 271 | + return $skel; |
|
| 272 | 272 | } |
| 273 | 273 | |
| 274 | 274 | // |
@@ -282,7 +282,7 @@ discard block |
||
| 282 | 282 | inserer_balise_dynamique(balise_%s_dyn(%s), array(%s)); |
| 283 | 283 | if ($lang_select) lang_select(); |
| 284 | 284 | ?' |
| 285 | - . '>'); |
|
| 285 | + . '>'); |
|
| 286 | 286 | |
| 287 | 287 | /** |
| 288 | 288 | * Synthétise une balise dynamique : crée l'appel à l'inclusion |
@@ -302,35 +302,35 @@ discard block |
||
| 302 | 302 | * Code PHP pour inclure le squelette de la balise dynamique |
| 303 | 303 | **/ |
| 304 | 304 | function synthetiser_balise_dynamique($nom, $args, $file, $context_compil) { |
| 305 | - if ( |
|
| 306 | - strncmp($file, '/', 1) !== 0 |
|
| 307 | - // pas de lien symbolique sous Windows |
|
| 308 | - and !(stristr(PHP_OS, 'WIN') and strpos($file, ':') !== false) |
|
| 309 | - ) { |
|
| 310 | - $file = './" . _DIR_RACINE . "' . $file; |
|
| 311 | - } |
|
| 312 | - |
|
| 313 | - $lang = $context_compil[4]; |
|
| 314 | - if (preg_match(',\W,', $lang)) { |
|
| 315 | - $lang = ''; |
|
| 316 | - } |
|
| 317 | - |
|
| 318 | - $args = array_map('argumenter_squelette', $args); |
|
| 319 | - if (!empty($context_compil['appel_php_depuis_modele'])) { |
|
| 320 | - $args[0] = 'arguments_balise_dyn_depuis_modele(' . $args[0] . ')'; |
|
| 321 | - } |
|
| 322 | - $args = join(', ', $args); |
|
| 323 | - |
|
| 324 | - $r = sprintf( |
|
| 325 | - CODE_INCLURE_BALISE, |
|
| 326 | - $file, |
|
| 327 | - $lang, |
|
| 328 | - $nom, |
|
| 329 | - $args, |
|
| 330 | - join(', ', array_map('_q', $context_compil)) |
|
| 331 | - ); |
|
| 332 | - |
|
| 333 | - return $r; |
|
| 305 | + if ( |
|
| 306 | + strncmp($file, '/', 1) !== 0 |
|
| 307 | + // pas de lien symbolique sous Windows |
|
| 308 | + and !(stristr(PHP_OS, 'WIN') and strpos($file, ':') !== false) |
|
| 309 | + ) { |
|
| 310 | + $file = './" . _DIR_RACINE . "' . $file; |
|
| 311 | + } |
|
| 312 | + |
|
| 313 | + $lang = $context_compil[4]; |
|
| 314 | + if (preg_match(',\W,', $lang)) { |
|
| 315 | + $lang = ''; |
|
| 316 | + } |
|
| 317 | + |
|
| 318 | + $args = array_map('argumenter_squelette', $args); |
|
| 319 | + if (!empty($context_compil['appel_php_depuis_modele'])) { |
|
| 320 | + $args[0] = 'arguments_balise_dyn_depuis_modele(' . $args[0] . ')'; |
|
| 321 | + } |
|
| 322 | + $args = join(', ', $args); |
|
| 323 | + |
|
| 324 | + $r = sprintf( |
|
| 325 | + CODE_INCLURE_BALISE, |
|
| 326 | + $file, |
|
| 327 | + $lang, |
|
| 328 | + $nom, |
|
| 329 | + $args, |
|
| 330 | + join(', ', array_map('_q', $context_compil)) |
|
| 331 | + ); |
|
| 332 | + |
|
| 333 | + return $r; |
|
| 334 | 334 | } |
| 335 | 335 | |
| 336 | 336 | /** |
@@ -348,18 +348,18 @@ discard block |
||
| 348 | 348 | **/ |
| 349 | 349 | function argumenter_squelette($v) { |
| 350 | 350 | |
| 351 | - if (is_object($v)) { |
|
| 352 | - return var_export($v, true); |
|
| 353 | - } elseif (!is_array($v)) { |
|
| 354 | - return "'" . texte_script((string) $v) . "'"; |
|
| 355 | - } else { |
|
| 356 | - $out = []; |
|
| 357 | - foreach ($v as $k => $val) { |
|
| 358 | - $out [] = argumenter_squelette($k) . '=>' . argumenter_squelette($val); |
|
| 359 | - } |
|
| 360 | - |
|
| 361 | - return 'array(' . join(', ', $out) . ')'; |
|
| 362 | - } |
|
| 351 | + if (is_object($v)) { |
|
| 352 | + return var_export($v, true); |
|
| 353 | + } elseif (!is_array($v)) { |
|
| 354 | + return "'" . texte_script((string) $v) . "'"; |
|
| 355 | + } else { |
|
| 356 | + $out = []; |
|
| 357 | + foreach ($v as $k => $val) { |
|
| 358 | + $out [] = argumenter_squelette($k) . '=>' . argumenter_squelette($val); |
|
| 359 | + } |
|
| 360 | + |
|
| 361 | + return 'array(' . join(', ', $out) . ')'; |
|
| 362 | + } |
|
| 363 | 363 | } |
| 364 | 364 | |
| 365 | 365 | |
@@ -390,87 +390,87 @@ discard block |
||
| 390 | 390 | * Code PHP d'exécutant l'inclusion du squelette (ou texte) de la balise dynamique |
| 391 | 391 | **/ |
| 392 | 392 | function executer_balise_dynamique($nom, $args, $context_compil) { |
| 393 | - /** @var string Nom de la balise à charger (balise demandée ou balise générique) */ |
|
| 394 | - $nom_balise = $nom; |
|
| 395 | - /** @var string Nom de la balise générique (si utilisée) */ |
|
| 396 | - $nom_balise_generique = ''; |
|
| 397 | - |
|
| 398 | - $appel_php_depuis_modele = false; |
|
| 399 | - if ( |
|
| 400 | - is_array($context_compil) |
|
| 401 | - and !is_numeric($context_compil[3]) |
|
| 402 | - and empty($context_compil[0]) |
|
| 403 | - and empty($context_compil[1]) |
|
| 404 | - and empty($context_compil[2]) |
|
| 405 | - and empty($context_compil[3]) |
|
| 406 | - ) { |
|
| 407 | - $appel_php_depuis_modele = true; |
|
| 408 | - } |
|
| 409 | - |
|
| 410 | - if (!$fonction_balise = charger_fonction($nom_balise, 'balise', true)) { |
|
| 411 | - // Calculer un nom générique (ie. 'formulaire_' dans 'formulaire_editer_article') |
|
| 412 | - if ($balise_generique = chercher_balise_generique($nom)) { |
|
| 413 | - // injecter en premier arg le nom de la balise |
|
| 414 | - array_unshift($args, $nom); |
|
| 415 | - $nom_balise_generique = $balise_generique['nom_generique']; |
|
| 416 | - $fonction_balise = $balise_generique['fonction_generique']; |
|
| 417 | - $nom_balise = $nom_balise_generique; |
|
| 418 | - } |
|
| 419 | - unset($balise_generique); |
|
| 420 | - } |
|
| 421 | - |
|
| 422 | - if (!$fonction_balise) { |
|
| 423 | - $msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]]; |
|
| 424 | - erreur_squelette($msg, $context_compil); |
|
| 425 | - |
|
| 426 | - return ''; |
|
| 427 | - } |
|
| 428 | - |
|
| 429 | - // retrouver le fichier qui a déclaré la fonction |
|
| 430 | - // même si la fonction dynamique est déclarée dans un fichier de fonctions. |
|
| 431 | - // Attention sous windows, getFileName() retourne un antislash. |
|
| 432 | - $reflector = new ReflectionFunction($fonction_balise); |
|
| 433 | - $file = str_replace('\\', '/', $reflector->getFileName()); |
|
| 434 | - if (strncmp($file, str_replace('\\', '/', _ROOT_RACINE), strlen(_ROOT_RACINE)) === 0) { |
|
| 435 | - $file = substr($file, strlen(_ROOT_RACINE)); |
|
| 436 | - } |
|
| 437 | - |
|
| 438 | - // Y a-t-il une fonction de traitement des arguments ? |
|
| 439 | - $f = 'balise_' . $nom_balise . '_stat'; |
|
| 440 | - |
|
| 441 | - $r = !function_exists($f) ? $args : $f($args, $context_compil); |
|
| 442 | - |
|
| 443 | - if (!is_array($r)) { |
|
| 444 | - return $r; |
|
| 445 | - } |
|
| 446 | - |
|
| 447 | - // verifier que la fonction dyn est la, |
|
| 448 | - // sinon se replier sur la generique si elle existe |
|
| 449 | - if (!function_exists('balise_' . $nom_balise . '_dyn')) { |
|
| 450 | - if ( |
|
| 451 | - $balise_generique = chercher_balise_generique($nom) |
|
| 452 | - and $nom_balise_generique = $balise_generique['nom_generique'] |
|
| 453 | - and $file = include_spip('balise/' . strtolower($nom_balise_generique)) |
|
| 454 | - and function_exists('balise_' . $nom_balise_generique . '_dyn') |
|
| 455 | - ) { |
|
| 456 | - // et lui injecter en premier arg le nom de la balise |
|
| 457 | - array_unshift($r, $nom); |
|
| 458 | - $nom_balise = $nom_balise_generique; |
|
| 459 | - if (!_DIR_RESTREINT) { |
|
| 460 | - $file = _DIR_RESTREINT_ABS . $file; |
|
| 461 | - } |
|
| 462 | - } else { |
|
| 463 | - $msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]]; |
|
| 464 | - erreur_squelette($msg, $context_compil); |
|
| 465 | - |
|
| 466 | - return ''; |
|
| 467 | - } |
|
| 468 | - } |
|
| 469 | - |
|
| 470 | - if ($appel_php_depuis_modele) { |
|
| 471 | - $context_compil['appel_php_depuis_modele'] = true; |
|
| 472 | - } |
|
| 473 | - return synthetiser_balise_dynamique($nom_balise, $r, $file, $context_compil); |
|
| 393 | + /** @var string Nom de la balise à charger (balise demandée ou balise générique) */ |
|
| 394 | + $nom_balise = $nom; |
|
| 395 | + /** @var string Nom de la balise générique (si utilisée) */ |
|
| 396 | + $nom_balise_generique = ''; |
|
| 397 | + |
|
| 398 | + $appel_php_depuis_modele = false; |
|
| 399 | + if ( |
|
| 400 | + is_array($context_compil) |
|
| 401 | + and !is_numeric($context_compil[3]) |
|
| 402 | + and empty($context_compil[0]) |
|
| 403 | + and empty($context_compil[1]) |
|
| 404 | + and empty($context_compil[2]) |
|
| 405 | + and empty($context_compil[3]) |
|
| 406 | + ) { |
|
| 407 | + $appel_php_depuis_modele = true; |
|
| 408 | + } |
|
| 409 | + |
|
| 410 | + if (!$fonction_balise = charger_fonction($nom_balise, 'balise', true)) { |
|
| 411 | + // Calculer un nom générique (ie. 'formulaire_' dans 'formulaire_editer_article') |
|
| 412 | + if ($balise_generique = chercher_balise_generique($nom)) { |
|
| 413 | + // injecter en premier arg le nom de la balise |
|
| 414 | + array_unshift($args, $nom); |
|
| 415 | + $nom_balise_generique = $balise_generique['nom_generique']; |
|
| 416 | + $fonction_balise = $balise_generique['fonction_generique']; |
|
| 417 | + $nom_balise = $nom_balise_generique; |
|
| 418 | + } |
|
| 419 | + unset($balise_generique); |
|
| 420 | + } |
|
| 421 | + |
|
| 422 | + if (!$fonction_balise) { |
|
| 423 | + $msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]]; |
|
| 424 | + erreur_squelette($msg, $context_compil); |
|
| 425 | + |
|
| 426 | + return ''; |
|
| 427 | + } |
|
| 428 | + |
|
| 429 | + // retrouver le fichier qui a déclaré la fonction |
|
| 430 | + // même si la fonction dynamique est déclarée dans un fichier de fonctions. |
|
| 431 | + // Attention sous windows, getFileName() retourne un antislash. |
|
| 432 | + $reflector = new ReflectionFunction($fonction_balise); |
|
| 433 | + $file = str_replace('\\', '/', $reflector->getFileName()); |
|
| 434 | + if (strncmp($file, str_replace('\\', '/', _ROOT_RACINE), strlen(_ROOT_RACINE)) === 0) { |
|
| 435 | + $file = substr($file, strlen(_ROOT_RACINE)); |
|
| 436 | + } |
|
| 437 | + |
|
| 438 | + // Y a-t-il une fonction de traitement des arguments ? |
|
| 439 | + $f = 'balise_' . $nom_balise . '_stat'; |
|
| 440 | + |
|
| 441 | + $r = !function_exists($f) ? $args : $f($args, $context_compil); |
|
| 442 | + |
|
| 443 | + if (!is_array($r)) { |
|
| 444 | + return $r; |
|
| 445 | + } |
|
| 446 | + |
|
| 447 | + // verifier que la fonction dyn est la, |
|
| 448 | + // sinon se replier sur la generique si elle existe |
|
| 449 | + if (!function_exists('balise_' . $nom_balise . '_dyn')) { |
|
| 450 | + if ( |
|
| 451 | + $balise_generique = chercher_balise_generique($nom) |
|
| 452 | + and $nom_balise_generique = $balise_generique['nom_generique'] |
|
| 453 | + and $file = include_spip('balise/' . strtolower($nom_balise_generique)) |
|
| 454 | + and function_exists('balise_' . $nom_balise_generique . '_dyn') |
|
| 455 | + ) { |
|
| 456 | + // et lui injecter en premier arg le nom de la balise |
|
| 457 | + array_unshift($r, $nom); |
|
| 458 | + $nom_balise = $nom_balise_generique; |
|
| 459 | + if (!_DIR_RESTREINT) { |
|
| 460 | + $file = _DIR_RESTREINT_ABS . $file; |
|
| 461 | + } |
|
| 462 | + } else { |
|
| 463 | + $msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]]; |
|
| 464 | + erreur_squelette($msg, $context_compil); |
|
| 465 | + |
|
| 466 | + return ''; |
|
| 467 | + } |
|
| 468 | + } |
|
| 469 | + |
|
| 470 | + if ($appel_php_depuis_modele) { |
|
| 471 | + $context_compil['appel_php_depuis_modele'] = true; |
|
| 472 | + } |
|
| 473 | + return synthetiser_balise_dynamique($nom_balise, $r, $file, $context_compil); |
|
| 474 | 474 | } |
| 475 | 475 | |
| 476 | 476 | /** |
@@ -485,23 +485,23 @@ discard block |
||
| 485 | 485 | * @return array|null |
| 486 | 486 | */ |
| 487 | 487 | function chercher_balise_generique($nom) { |
| 488 | - if (false === strpos($nom, '_')) { |
|
| 489 | - return null; |
|
| 490 | - } |
|
| 491 | - $nom_generique = $nom; |
|
| 492 | - while (false !== ($p = strrpos($nom_generique, '_'))) { |
|
| 493 | - $nom_generique = substr($nom_generique, 0, $p + 1); |
|
| 494 | - $fonction_generique = charger_fonction($nom_generique, 'balise', true); |
|
| 495 | - if ($fonction_generique) { |
|
| 496 | - return [ |
|
| 497 | - 'nom' => $nom, |
|
| 498 | - 'nom_generique' => $nom_generique, |
|
| 499 | - 'fonction_generique' => $fonction_generique, |
|
| 500 | - ]; |
|
| 501 | - } |
|
| 502 | - $nom_generique = substr($nom_generique, 0, -1); |
|
| 503 | - } |
|
| 504 | - return null; |
|
| 488 | + if (false === strpos($nom, '_')) { |
|
| 489 | + return null; |
|
| 490 | + } |
|
| 491 | + $nom_generique = $nom; |
|
| 492 | + while (false !== ($p = strrpos($nom_generique, '_'))) { |
|
| 493 | + $nom_generique = substr($nom_generique, 0, $p + 1); |
|
| 494 | + $fonction_generique = charger_fonction($nom_generique, 'balise', true); |
|
| 495 | + if ($fonction_generique) { |
|
| 496 | + return [ |
|
| 497 | + 'nom' => $nom, |
|
| 498 | + 'nom_generique' => $nom_generique, |
|
| 499 | + 'fonction_generique' => $fonction_generique, |
|
| 500 | + ]; |
|
| 501 | + } |
|
| 502 | + $nom_generique = substr($nom_generique, 0, -1); |
|
| 503 | + } |
|
| 504 | + return null; |
|
| 505 | 505 | } |
| 506 | 506 | |
| 507 | 507 | |
@@ -525,50 +525,50 @@ discard block |
||
| 525 | 525 | * @return null; |
| 526 | 526 | **/ |
| 527 | 527 | function lang_select_public($lang, $lang_select, $titre = null) { |
| 528 | - // Cas 1. forcer_lang = true et pas de critere {lang_select} |
|
| 529 | - if ( |
|
| 530 | - isset($GLOBALS['forcer_lang']) and $GLOBALS['forcer_lang'] |
|
| 531 | - and $lang_select !== 'oui' |
|
| 532 | - ) { |
|
| 533 | - $lang = $GLOBALS['spip_lang']; |
|
| 534 | - } // Cas 2. l'objet n'a pas de langue definie (ou definie a '') |
|
| 535 | - elseif (!strlen($lang)) { |
|
| 536 | - $lang = $GLOBALS['spip_lang']; |
|
| 537 | - } // Cas 3. l'objet est multilingue ! |
|
| 538 | - elseif ( |
|
| 539 | - $lang_select !== 'oui' |
|
| 540 | - and strlen($titre) > 10 |
|
| 541 | - and strpos($titre, '<multi>') !== false |
|
| 542 | - and strpos(echappe_html($titre), '<multi>') !== false |
|
| 543 | - ) { |
|
| 544 | - $lang = $GLOBALS['spip_lang']; |
|
| 545 | - } |
|
| 546 | - |
|
| 547 | - // faire un lang_select() eventuellement sur la langue inchangee |
|
| 548 | - lang_select($lang); |
|
| 549 | - |
|
| 550 | - return; |
|
| 528 | + // Cas 1. forcer_lang = true et pas de critere {lang_select} |
|
| 529 | + if ( |
|
| 530 | + isset($GLOBALS['forcer_lang']) and $GLOBALS['forcer_lang'] |
|
| 531 | + and $lang_select !== 'oui' |
|
| 532 | + ) { |
|
| 533 | + $lang = $GLOBALS['spip_lang']; |
|
| 534 | + } // Cas 2. l'objet n'a pas de langue definie (ou definie a '') |
|
| 535 | + elseif (!strlen($lang)) { |
|
| 536 | + $lang = $GLOBALS['spip_lang']; |
|
| 537 | + } // Cas 3. l'objet est multilingue ! |
|
| 538 | + elseif ( |
|
| 539 | + $lang_select !== 'oui' |
|
| 540 | + and strlen($titre) > 10 |
|
| 541 | + and strpos($titre, '<multi>') !== false |
|
| 542 | + and strpos(echappe_html($titre), '<multi>') !== false |
|
| 543 | + ) { |
|
| 544 | + $lang = $GLOBALS['spip_lang']; |
|
| 545 | + } |
|
| 546 | + |
|
| 547 | + // faire un lang_select() eventuellement sur la langue inchangee |
|
| 548 | + lang_select($lang); |
|
| 549 | + |
|
| 550 | + return; |
|
| 551 | 551 | } |
| 552 | 552 | |
| 553 | 553 | |
| 554 | 554 | // Si un tableau &doublons[articles] est passe en parametre, |
| 555 | 555 | // il faut le nettoyer car il pourrait etre injecte en SQL |
| 556 | 556 | function nettoyer_env_doublons($envd) { |
| 557 | - foreach ($envd as $table => $liste) { |
|
| 558 | - $n = ''; |
|
| 559 | - foreach (explode(',', $liste) as $val) { |
|
| 560 | - if ($a = intval($val) and $val === strval($a)) { |
|
| 561 | - $n .= ',' . $val; |
|
| 562 | - } |
|
| 563 | - } |
|
| 564 | - if (strlen($n)) { |
|
| 565 | - $envd[$table] = $n; |
|
| 566 | - } else { |
|
| 567 | - unset($envd[$table]); |
|
| 568 | - } |
|
| 569 | - } |
|
| 570 | - |
|
| 571 | - return $envd; |
|
| 557 | + foreach ($envd as $table => $liste) { |
|
| 558 | + $n = ''; |
|
| 559 | + foreach (explode(',', $liste) as $val) { |
|
| 560 | + if ($a = intval($val) and $val === strval($a)) { |
|
| 561 | + $n .= ',' . $val; |
|
| 562 | + } |
|
| 563 | + } |
|
| 564 | + if (strlen($n)) { |
|
| 565 | + $envd[$table] = $n; |
|
| 566 | + } else { |
|
| 567 | + unset($envd[$table]); |
|
| 568 | + } |
|
| 569 | + } |
|
| 570 | + |
|
| 571 | + return $envd; |
|
| 572 | 572 | } |
| 573 | 573 | |
| 574 | 574 | /** |
@@ -587,21 +587,21 @@ discard block |
||
| 587 | 587 | * Opérateur trouvé (SELF ou SUBSELECT) sinon false. |
| 588 | 588 | **/ |
| 589 | 589 | function match_self($w) { |
| 590 | - if (is_string($w)) { |
|
| 591 | - return false; |
|
| 592 | - } |
|
| 593 | - if (is_array($w)) { |
|
| 594 | - if (in_array(reset($w), ['SELF', 'SUBSELECT'])) { |
|
| 595 | - return $w; |
|
| 596 | - } |
|
| 597 | - foreach (array_filter($w, 'is_array') as $sw) { |
|
| 598 | - if ($m = match_self($sw)) { |
|
| 599 | - return $m; |
|
| 600 | - } |
|
| 601 | - } |
|
| 602 | - } |
|
| 603 | - |
|
| 604 | - return false; |
|
| 590 | + if (is_string($w)) { |
|
| 591 | + return false; |
|
| 592 | + } |
|
| 593 | + if (is_array($w)) { |
|
| 594 | + if (in_array(reset($w), ['SELF', 'SUBSELECT'])) { |
|
| 595 | + return $w; |
|
| 596 | + } |
|
| 597 | + foreach (array_filter($w, 'is_array') as $sw) { |
|
| 598 | + if ($m = match_self($sw)) { |
|
| 599 | + return $m; |
|
| 600 | + } |
|
| 601 | + } |
|
| 602 | + } |
|
| 603 | + |
|
| 604 | + return false; |
|
| 605 | 605 | } |
| 606 | 606 | |
| 607 | 607 | /** |
@@ -617,16 +617,16 @@ discard block |
||
| 617 | 617 | * est remplacée par son code. |
| 618 | 618 | **/ |
| 619 | 619 | function remplace_sous_requete($w, $sousrequete) { |
| 620 | - if (is_array($w)) { |
|
| 621 | - if (in_array(reset($w), ['SELF', 'SUBSELECT'])) { |
|
| 622 | - return $sousrequete; |
|
| 623 | - } |
|
| 624 | - foreach ($w as $k => $sw) { |
|
| 625 | - $w[$k] = remplace_sous_requete($sw, $sousrequete); |
|
| 626 | - } |
|
| 627 | - } |
|
| 628 | - |
|
| 629 | - return $w; |
|
| 620 | + if (is_array($w)) { |
|
| 621 | + if (in_array(reset($w), ['SELF', 'SUBSELECT'])) { |
|
| 622 | + return $sousrequete; |
|
| 623 | + } |
|
| 624 | + foreach ($w as $k => $sw) { |
|
| 625 | + $w[$k] = remplace_sous_requete($sw, $sousrequete); |
|
| 626 | + } |
|
| 627 | + } |
|
| 628 | + |
|
| 629 | + return $w; |
|
| 630 | 630 | } |
| 631 | 631 | |
| 632 | 632 | /** |
@@ -640,17 +640,17 @@ discard block |
||
| 640 | 640 | * - Conditions avec des sous requêtes |
| 641 | 641 | **/ |
| 642 | 642 | function trouver_sous_requetes($where) { |
| 643 | - $where_simples = []; |
|
| 644 | - $where_sous = []; |
|
| 645 | - foreach ($where as $k => $w) { |
|
| 646 | - if (match_self($w)) { |
|
| 647 | - $where_sous[$k] = $w; |
|
| 648 | - } else { |
|
| 649 | - $where_simples[$k] = $w; |
|
| 650 | - } |
|
| 651 | - } |
|
| 652 | - |
|
| 653 | - return [$where_simples, $where_sous]; |
|
| 643 | + $where_simples = []; |
|
| 644 | + $where_sous = []; |
|
| 645 | + foreach ($where as $k => $w) { |
|
| 646 | + if (match_self($w)) { |
|
| 647 | + $where_sous[$k] = $w; |
|
| 648 | + } else { |
|
| 649 | + $where_simples[$k] = $w; |
|
| 650 | + } |
|
| 651 | + } |
|
| 652 | + |
|
| 653 | + return [$where_simples, $where_sous]; |
|
| 654 | 654 | } |
| 655 | 655 | |
| 656 | 656 | |
@@ -676,292 +676,292 @@ discard block |
||
| 676 | 676 | * @return resource |
| 677 | 677 | */ |
| 678 | 678 | function calculer_select( |
| 679 | - $select = [], |
|
| 680 | - $from = [], |
|
| 681 | - $from_type = [], |
|
| 682 | - $where = [], |
|
| 683 | - $join = [], |
|
| 684 | - $groupby = [], |
|
| 685 | - $orderby = [], |
|
| 686 | - $limit = '', |
|
| 687 | - $having = [], |
|
| 688 | - $table = '', |
|
| 689 | - $id = '', |
|
| 690 | - $serveur = '', |
|
| 691 | - $requeter = true |
|
| 679 | + $select = [], |
|
| 680 | + $from = [], |
|
| 681 | + $from_type = [], |
|
| 682 | + $where = [], |
|
| 683 | + $join = [], |
|
| 684 | + $groupby = [], |
|
| 685 | + $orderby = [], |
|
| 686 | + $limit = '', |
|
| 687 | + $having = [], |
|
| 688 | + $table = '', |
|
| 689 | + $id = '', |
|
| 690 | + $serveur = '', |
|
| 691 | + $requeter = true |
|
| 692 | 692 | ) { |
| 693 | 693 | |
| 694 | - // retirer les criteres vides: |
|
| 695 | - // {X ?} avec X absent de l'URL |
|
| 696 | - // {par #ENV{X}} avec X absent de l'URL |
|
| 697 | - // IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil) |
|
| 698 | - $menage = false; |
|
| 699 | - foreach ($where as $k => $v) { |
|
| 700 | - if (is_array($v)) { |
|
| 701 | - if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) { |
|
| 702 | - $op = false; |
|
| 703 | - } elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) { |
|
| 704 | - $op = false; |
|
| 705 | - } else { |
|
| 706 | - $op = $v[0] ?: $v; |
|
| 707 | - } |
|
| 708 | - } else { |
|
| 709 | - $op = $v; |
|
| 710 | - } |
|
| 711 | - if ((!$op) or ($op == 1) or ($op == '0=0')) { |
|
| 712 | - unset($where[$k]); |
|
| 713 | - $menage = true; |
|
| 714 | - } |
|
| 715 | - } |
|
| 716 | - |
|
| 717 | - // evacuer les eventuels groupby vide issus d'un calcul dynamique |
|
| 718 | - $groupby = array_diff($groupby, ['']); |
|
| 719 | - |
|
| 720 | - // remplacer les sous requetes recursives au calcul |
|
| 721 | - [$where_simples, $where_sous] = trouver_sous_requetes($where); |
|
| 722 | - foreach ($where_sous as $k => $w) { |
|
| 723 | - $menage = true; |
|
| 724 | - // on recupere la sous requete |
|
| 725 | - $sous = match_self($w); |
|
| 726 | - if ($sous[0] == 'SELF') { |
|
| 727 | - // c'est une sous requete identique a elle meme sous la forme (SELF,$select,$where) |
|
| 728 | - array_push($where_simples, $sous[2]); |
|
| 729 | - $wheresub = [ |
|
| 730 | - $sous[2], |
|
| 731 | - '0=0' |
|
| 732 | - ]; // pour accepter une string et forcer a faire le menage car on a surement simplifie select et where |
|
| 733 | - $jsub = $join; |
|
| 734 | - // trouver les jointures utiles a |
|
| 735 | - // reinjecter dans le where de la sous requete les conditions supplementaires des jointures qui y sont mentionnees |
|
| 736 | - // ie L1.objet='article' |
|
| 737 | - // on construit le where une fois, puis on ajoute les where complentaires si besoin, et on reconstruit le where en fonction |
|
| 738 | - $i = 0; |
|
| 739 | - do { |
|
| 740 | - $where[$k] = remplace_sous_requete($w, '(' . calculer_select( |
|
| 741 | - [$sous[1] . ' AS id'], |
|
| 742 | - $from, |
|
| 743 | - $from_type, |
|
| 744 | - $wheresub, |
|
| 745 | - $jsub, |
|
| 746 | - [], |
|
| 747 | - [], |
|
| 748 | - '', |
|
| 749 | - $having, |
|
| 750 | - $table, |
|
| 751 | - $id, |
|
| 752 | - $serveur, |
|
| 753 | - false |
|
| 754 | - ) . ')'); |
|
| 755 | - if (!$i) { |
|
| 756 | - $i = 1; |
|
| 757 | - $wherestring = calculer_where_to_string($where[$k]); |
|
| 758 | - foreach ($join as $cle => $wj) { |
|
| 759 | - if ( |
|
| 760 | - (is_countable($wj) ? count($wj) : 0) == 4 |
|
| 761 | - and strpos($wherestring, (string) "{$cle}.") !== false |
|
| 762 | - ) { |
|
| 763 | - $i = 0; |
|
| 764 | - $wheresub[] = $wj[3]; |
|
| 765 | - unset($jsub[$cle][3]); |
|
| 766 | - } |
|
| 767 | - } |
|
| 768 | - } |
|
| 769 | - } while ($i++ < 1); |
|
| 770 | - } |
|
| 771 | - if ($sous[0] == 'SUBSELECT') { |
|
| 772 | - // c'est une sous requete explicite sous la forme identique a sql_select : (SUBSELECT,$select,$from,$where,$groupby,$orderby,$limit,$having) |
|
| 773 | - array_push($where_simples, $sous[3]); // est-ce utile dans ce cas ? |
|
| 774 | - $where[$k] = remplace_sous_requete($w, '(' . calculer_select( |
|
| 775 | - $sous[1], # select |
|
| 776 | - $sous[2], #from |
|
| 777 | - [], #from_type |
|
| 778 | - $sous[3] ? (is_array($sous[3]) ? $sous[3] : [$sous[3]]) : [], |
|
| 779 | - #where, qui peut etre de la forme string comme dans sql_select |
|
| 780 | - [], #join |
|
| 781 | - $sous[4] ?: [], #groupby |
|
| 782 | - $sous[5] ?: [], #orderby |
|
| 783 | - $sous[6], #limit |
|
| 784 | - $sous[7] ?: [], #having |
|
| 785 | - $table, |
|
| 786 | - $id, |
|
| 787 | - $serveur, |
|
| 788 | - false |
|
| 789 | - ) . ')'); |
|
| 790 | - } |
|
| 791 | - array_pop($where_simples); |
|
| 792 | - } |
|
| 793 | - |
|
| 794 | - foreach ($having as $k => $v) { |
|
| 795 | - if ((!$v) or ($v == 1) or ($v == '0=0')) { |
|
| 796 | - unset($having[$k]); |
|
| 797 | - } |
|
| 798 | - } |
|
| 799 | - |
|
| 800 | - // Installer les jointures. |
|
| 801 | - // Retirer celles seulement utiles aux criteres finalement absents mais |
|
| 802 | - // parcourir de la plus recente a la moins recente pour pouvoir eliminer Ln |
|
| 803 | - // si elle est seulement utile a Ln+1 elle meme inutile |
|
| 804 | - |
|
| 805 | - $afrom = []; |
|
| 806 | - $equiv = []; |
|
| 807 | - $k = count($join); |
|
| 808 | - foreach (array_reverse($join, true) as $cledef => $j) { |
|
| 809 | - $cle = $cledef; |
|
| 810 | - // le format de join est : |
|
| 811 | - // array(table depart, cle depart [,cle arrivee[,condition optionnelle and ...]]) |
|
| 812 | - $join[$cle] = array_values($join[$cle]); // recalculer les cles car des unset ont pu perturber |
|
| 813 | - if (count($join[$cle]) == 2) { |
|
| 814 | - $join[$cle][] = $join[$cle][1]; |
|
| 815 | - } |
|
| 816 | - if ((is_array($join[$cle]) || $join[$cle] instanceof \Countable ? count($join[$cle]) : 0) == 3) { |
|
| 817 | - $join[$cle][] = ''; |
|
| 818 | - } |
|
| 819 | - [$t, $c, $carr, $and] = $join[$cle]; |
|
| 820 | - // si le nom de la jointure n'a pas ete specifiee, on prend Lx avec x sont rang dans la liste |
|
| 821 | - // pour compat avec ancienne convention |
|
| 822 | - if (is_numeric($cle)) { |
|
| 823 | - $cle = "L$k"; |
|
| 824 | - } |
|
| 825 | - $cle_where_lie = "JOIN-$cle"; |
|
| 826 | - if ( |
|
| 827 | - !$menage |
|
| 828 | - or isset($afrom[$cle]) |
|
| 829 | - or calculer_jointnul($cle, $select) |
|
| 830 | - or calculer_jointnul($cle, array_diff_key($join, [$cle => $join[$cle]])) |
|
| 831 | - or calculer_jointnul($cle, $having) |
|
| 832 | - or calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => ''])) |
|
| 833 | - ) { |
|
| 834 | - // corriger les references non explicites dans select |
|
| 835 | - // ou groupby |
|
| 836 | - foreach ($select as $i => $s) { |
|
| 837 | - if ($s == $c) { |
|
| 838 | - $select[$i] = "$cle.$c AS $c"; |
|
| 839 | - break; |
|
| 840 | - } |
|
| 841 | - } |
|
| 842 | - foreach ($groupby as $i => $g) { |
|
| 843 | - if ($g == $c) { |
|
| 844 | - $groupby[$i] = "$cle.$c"; |
|
| 845 | - break; |
|
| 846 | - } |
|
| 847 | - } |
|
| 848 | - // on garde une ecriture decomposee pour permettre une simplification ulterieure si besoin |
|
| 849 | - // sans recours a preg_match |
|
| 850 | - // un implode(' ',..) est fait dans reinjecte_joint un peu plus bas |
|
| 851 | - $afrom[$t][$cle] = [ |
|
| 852 | - "\n" . |
|
| 853 | - ($from_type[$cle] ?? 'INNER') . ' JOIN', |
|
| 854 | - $from[$cle], |
|
| 855 | - "AS $cle", |
|
| 856 | - 'ON (', |
|
| 857 | - "$cle.$c", |
|
| 858 | - '=', |
|
| 859 | - "$t.$carr", |
|
| 860 | - ($and ? 'AND ' . $and : '') . |
|
| 861 | - ')' |
|
| 862 | - ]; |
|
| 863 | - if (isset($afrom[$cle])) { |
|
| 864 | - $afrom[$t] = $afrom[$t] + $afrom[$cle]; |
|
| 865 | - unset($afrom[$cle]); |
|
| 866 | - } |
|
| 867 | - $equiv[] = $carr; |
|
| 868 | - } else { |
|
| 869 | - unset($join[$cledef]); |
|
| 870 | - if (isset($where_simples[$cle_where_lie])) { |
|
| 871 | - unset($where_simples[$cle_where_lie]); |
|
| 872 | - unset($where[$cle_where_lie]); |
|
| 873 | - } |
|
| 874 | - } |
|
| 875 | - unset($from[$cle]); |
|
| 876 | - $k--; |
|
| 877 | - } |
|
| 878 | - |
|
| 879 | - if (count($afrom)) { |
|
| 880 | - // Regarder si la table principale ne sert finalement a rien comme dans |
|
| 881 | - //<BOUCLE3(MOTS){id_article}{id_mot}> class='on'</BOUCLE3> |
|
| 882 | - //<BOUCLE2(MOTS){id_article} />#TOTAL_BOUCLE<//B2> |
|
| 883 | - //<BOUCLE5(RUBRIQUES){id_mot}{tout} />#TOTAL_BOUCLE<//B5> |
|
| 884 | - // ou dans |
|
| 885 | - //<BOUCLE8(HIERARCHIE){id_rubrique}{tout}{type='Squelette'}{inverse}{0,1}{lang_select=non} />#TOTAL_BOUCLE<//B8> |
|
| 886 | - // qui comporte plusieurs jointures |
|
| 887 | - // ou dans |
|
| 888 | - // <BOUCLE6(ARTICLES){id_mot=2}{statut==.*} />#TOTAL_BOUCLE<//B6> |
|
| 889 | - // <BOUCLE7(ARTICLES){id_mot>0}{statut?} />#TOTAL_BOUCLE<//B7> |
|
| 890 | - // penser a regarder aussi la clause orderby pour ne pas simplifier abusivement |
|
| 891 | - // <BOUCLE9(ARTICLES){recherche truc}{par titre}>#ID_ARTICLE</BOUCLE9> |
|
| 892 | - // penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement |
|
| 893 | - // <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10> |
|
| 894 | - |
|
| 895 | - $t = key($from); |
|
| 896 | - $c = current($from); |
|
| 897 | - reset($from); |
|
| 898 | - $e = '/\b(' . "$t\\." . join('|' . $t . '\.', $equiv) . ')\b/'; |
|
| 899 | - if ( |
|
| 900 | - !(strpos($t, ' ') or // jointure des le depart cf boucle_doc |
|
| 901 | - calculer_jointnul($t, $select, $e) or |
|
| 902 | - calculer_jointnul($t, $join, $e) or |
|
| 903 | - calculer_jointnul($t, $where, $e) or |
|
| 904 | - calculer_jointnul($t, $orderby, $e) or |
|
| 905 | - calculer_jointnul($t, $groupby, $e) or |
|
| 906 | - calculer_jointnul($t, $having, $e)) |
|
| 907 | - && count($afrom[$t]) |
|
| 908 | - ) { |
|
| 909 | - $nfrom = reset($afrom[$t]); |
|
| 910 | - $nt = array_key_first($afrom[$t]); |
|
| 911 | - unset($from[$t]); |
|
| 912 | - $from[$nt] = $nfrom[1]; |
|
| 913 | - unset($afrom[$t][$nt]); |
|
| 914 | - $afrom[$nt] = $afrom[$t]; |
|
| 915 | - unset($afrom[$t]); |
|
| 916 | - $e = '/\b' . preg_quote($nfrom[6]) . '\b/'; |
|
| 917 | - $t = $nfrom[4]; |
|
| 918 | - $alias = ''; |
|
| 919 | - // verifier que les deux cles sont homonymes, sinon installer un alias dans le select |
|
| 920 | - $oldcle = explode('.', $nfrom[6]); |
|
| 921 | - $oldcle = end($oldcle); |
|
| 922 | - $newcle = explode('.', $nfrom[4]); |
|
| 923 | - $newcle = end($newcle); |
|
| 924 | - if ($newcle != $oldcle) { |
|
| 925 | - // si l'ancienne cle etait deja dans le select avec un AS |
|
| 926 | - // reprendre simplement ce AS |
|
| 927 | - $as = '/\b' . preg_quote($nfrom[6]) . '\s+(AS\s+\w+)\b/'; |
|
| 928 | - if (preg_match($as, implode(',', $select), $m)) { |
|
| 929 | - $alias = ''; |
|
| 930 | - } else { |
|
| 931 | - $alias = ', ' . $nfrom[4] . " AS $oldcle"; |
|
| 932 | - } |
|
| 933 | - } |
|
| 934 | - $select = remplacer_jointnul($t . $alias, $select, $e); |
|
| 935 | - $join = remplacer_jointnul($t, $join, $e); |
|
| 936 | - $where = remplacer_jointnul($t, $where, $e); |
|
| 937 | - $having = remplacer_jointnul($t, $having, $e); |
|
| 938 | - $groupby = remplacer_jointnul($t, $groupby, $e); |
|
| 939 | - $orderby = remplacer_jointnul($t, $orderby, $e); |
|
| 940 | - } |
|
| 941 | - $from = reinjecte_joint($afrom, $from); |
|
| 942 | - } |
|
| 943 | - if (empty($GLOBALS['debug']) or !is_array($GLOBALS['debug'])) { |
|
| 944 | - $wasdebug = empty($GLOBALS['debug']) ? false : $GLOBALS['debug']; |
|
| 945 | - $GLOBALS['debug'] = []; |
|
| 946 | - if ($wasdebug) { |
|
| 947 | - $GLOBALS['debug']['debug'] = true; |
|
| 948 | - } |
|
| 949 | - } |
|
| 950 | - $GLOBALS['debug']['aucasou'] = [$table, $id, $serveur, $requeter]; |
|
| 951 | - $r = sql_select( |
|
| 952 | - $select, |
|
| 953 | - $from, |
|
| 954 | - $where, |
|
| 955 | - $groupby, |
|
| 956 | - array_filter($orderby), |
|
| 957 | - $limit, |
|
| 958 | - $having, |
|
| 959 | - $serveur, |
|
| 960 | - $requeter |
|
| 961 | - ); |
|
| 962 | - unset($GLOBALS['debug']['aucasou']); |
|
| 963 | - |
|
| 964 | - return $r; |
|
| 694 | + // retirer les criteres vides: |
|
| 695 | + // {X ?} avec X absent de l'URL |
|
| 696 | + // {par #ENV{X}} avec X absent de l'URL |
|
| 697 | + // IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil) |
|
| 698 | + $menage = false; |
|
| 699 | + foreach ($where as $k => $v) { |
|
| 700 | + if (is_array($v)) { |
|
| 701 | + if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) { |
|
| 702 | + $op = false; |
|
| 703 | + } elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) { |
|
| 704 | + $op = false; |
|
| 705 | + } else { |
|
| 706 | + $op = $v[0] ?: $v; |
|
| 707 | + } |
|
| 708 | + } else { |
|
| 709 | + $op = $v; |
|
| 710 | + } |
|
| 711 | + if ((!$op) or ($op == 1) or ($op == '0=0')) { |
|
| 712 | + unset($where[$k]); |
|
| 713 | + $menage = true; |
|
| 714 | + } |
|
| 715 | + } |
|
| 716 | + |
|
| 717 | + // evacuer les eventuels groupby vide issus d'un calcul dynamique |
|
| 718 | + $groupby = array_diff($groupby, ['']); |
|
| 719 | + |
|
| 720 | + // remplacer les sous requetes recursives au calcul |
|
| 721 | + [$where_simples, $where_sous] = trouver_sous_requetes($where); |
|
| 722 | + foreach ($where_sous as $k => $w) { |
|
| 723 | + $menage = true; |
|
| 724 | + // on recupere la sous requete |
|
| 725 | + $sous = match_self($w); |
|
| 726 | + if ($sous[0] == 'SELF') { |
|
| 727 | + // c'est une sous requete identique a elle meme sous la forme (SELF,$select,$where) |
|
| 728 | + array_push($where_simples, $sous[2]); |
|
| 729 | + $wheresub = [ |
|
| 730 | + $sous[2], |
|
| 731 | + '0=0' |
|
| 732 | + ]; // pour accepter une string et forcer a faire le menage car on a surement simplifie select et where |
|
| 733 | + $jsub = $join; |
|
| 734 | + // trouver les jointures utiles a |
|
| 735 | + // reinjecter dans le where de la sous requete les conditions supplementaires des jointures qui y sont mentionnees |
|
| 736 | + // ie L1.objet='article' |
|
| 737 | + // on construit le where une fois, puis on ajoute les where complentaires si besoin, et on reconstruit le where en fonction |
|
| 738 | + $i = 0; |
|
| 739 | + do { |
|
| 740 | + $where[$k] = remplace_sous_requete($w, '(' . calculer_select( |
|
| 741 | + [$sous[1] . ' AS id'], |
|
| 742 | + $from, |
|
| 743 | + $from_type, |
|
| 744 | + $wheresub, |
|
| 745 | + $jsub, |
|
| 746 | + [], |
|
| 747 | + [], |
|
| 748 | + '', |
|
| 749 | + $having, |
|
| 750 | + $table, |
|
| 751 | + $id, |
|
| 752 | + $serveur, |
|
| 753 | + false |
|
| 754 | + ) . ')'); |
|
| 755 | + if (!$i) { |
|
| 756 | + $i = 1; |
|
| 757 | + $wherestring = calculer_where_to_string($where[$k]); |
|
| 758 | + foreach ($join as $cle => $wj) { |
|
| 759 | + if ( |
|
| 760 | + (is_countable($wj) ? count($wj) : 0) == 4 |
|
| 761 | + and strpos($wherestring, (string) "{$cle}.") !== false |
|
| 762 | + ) { |
|
| 763 | + $i = 0; |
|
| 764 | + $wheresub[] = $wj[3]; |
|
| 765 | + unset($jsub[$cle][3]); |
|
| 766 | + } |
|
| 767 | + } |
|
| 768 | + } |
|
| 769 | + } while ($i++ < 1); |
|
| 770 | + } |
|
| 771 | + if ($sous[0] == 'SUBSELECT') { |
|
| 772 | + // c'est une sous requete explicite sous la forme identique a sql_select : (SUBSELECT,$select,$from,$where,$groupby,$orderby,$limit,$having) |
|
| 773 | + array_push($where_simples, $sous[3]); // est-ce utile dans ce cas ? |
|
| 774 | + $where[$k] = remplace_sous_requete($w, '(' . calculer_select( |
|
| 775 | + $sous[1], # select |
|
| 776 | + $sous[2], #from |
|
| 777 | + [], #from_type |
|
| 778 | + $sous[3] ? (is_array($sous[3]) ? $sous[3] : [$sous[3]]) : [], |
|
| 779 | + #where, qui peut etre de la forme string comme dans sql_select |
|
| 780 | + [], #join |
|
| 781 | + $sous[4] ?: [], #groupby |
|
| 782 | + $sous[5] ?: [], #orderby |
|
| 783 | + $sous[6], #limit |
|
| 784 | + $sous[7] ?: [], #having |
|
| 785 | + $table, |
|
| 786 | + $id, |
|
| 787 | + $serveur, |
|
| 788 | + false |
|
| 789 | + ) . ')'); |
|
| 790 | + } |
|
| 791 | + array_pop($where_simples); |
|
| 792 | + } |
|
| 793 | + |
|
| 794 | + foreach ($having as $k => $v) { |
|
| 795 | + if ((!$v) or ($v == 1) or ($v == '0=0')) { |
|
| 796 | + unset($having[$k]); |
|
| 797 | + } |
|
| 798 | + } |
|
| 799 | + |
|
| 800 | + // Installer les jointures. |
|
| 801 | + // Retirer celles seulement utiles aux criteres finalement absents mais |
|
| 802 | + // parcourir de la plus recente a la moins recente pour pouvoir eliminer Ln |
|
| 803 | + // si elle est seulement utile a Ln+1 elle meme inutile |
|
| 804 | + |
|
| 805 | + $afrom = []; |
|
| 806 | + $equiv = []; |
|
| 807 | + $k = count($join); |
|
| 808 | + foreach (array_reverse($join, true) as $cledef => $j) { |
|
| 809 | + $cle = $cledef; |
|
| 810 | + // le format de join est : |
|
| 811 | + // array(table depart, cle depart [,cle arrivee[,condition optionnelle and ...]]) |
|
| 812 | + $join[$cle] = array_values($join[$cle]); // recalculer les cles car des unset ont pu perturber |
|
| 813 | + if (count($join[$cle]) == 2) { |
|
| 814 | + $join[$cle][] = $join[$cle][1]; |
|
| 815 | + } |
|
| 816 | + if ((is_array($join[$cle]) || $join[$cle] instanceof \Countable ? count($join[$cle]) : 0) == 3) { |
|
| 817 | + $join[$cle][] = ''; |
|
| 818 | + } |
|
| 819 | + [$t, $c, $carr, $and] = $join[$cle]; |
|
| 820 | + // si le nom de la jointure n'a pas ete specifiee, on prend Lx avec x sont rang dans la liste |
|
| 821 | + // pour compat avec ancienne convention |
|
| 822 | + if (is_numeric($cle)) { |
|
| 823 | + $cle = "L$k"; |
|
| 824 | + } |
|
| 825 | + $cle_where_lie = "JOIN-$cle"; |
|
| 826 | + if ( |
|
| 827 | + !$menage |
|
| 828 | + or isset($afrom[$cle]) |
|
| 829 | + or calculer_jointnul($cle, $select) |
|
| 830 | + or calculer_jointnul($cle, array_diff_key($join, [$cle => $join[$cle]])) |
|
| 831 | + or calculer_jointnul($cle, $having) |
|
| 832 | + or calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => ''])) |
|
| 833 | + ) { |
|
| 834 | + // corriger les references non explicites dans select |
|
| 835 | + // ou groupby |
|
| 836 | + foreach ($select as $i => $s) { |
|
| 837 | + if ($s == $c) { |
|
| 838 | + $select[$i] = "$cle.$c AS $c"; |
|
| 839 | + break; |
|
| 840 | + } |
|
| 841 | + } |
|
| 842 | + foreach ($groupby as $i => $g) { |
|
| 843 | + if ($g == $c) { |
|
| 844 | + $groupby[$i] = "$cle.$c"; |
|
| 845 | + break; |
|
| 846 | + } |
|
| 847 | + } |
|
| 848 | + // on garde une ecriture decomposee pour permettre une simplification ulterieure si besoin |
|
| 849 | + // sans recours a preg_match |
|
| 850 | + // un implode(' ',..) est fait dans reinjecte_joint un peu plus bas |
|
| 851 | + $afrom[$t][$cle] = [ |
|
| 852 | + "\n" . |
|
| 853 | + ($from_type[$cle] ?? 'INNER') . ' JOIN', |
|
| 854 | + $from[$cle], |
|
| 855 | + "AS $cle", |
|
| 856 | + 'ON (', |
|
| 857 | + "$cle.$c", |
|
| 858 | + '=', |
|
| 859 | + "$t.$carr", |
|
| 860 | + ($and ? 'AND ' . $and : '') . |
|
| 861 | + ')' |
|
| 862 | + ]; |
|
| 863 | + if (isset($afrom[$cle])) { |
|
| 864 | + $afrom[$t] = $afrom[$t] + $afrom[$cle]; |
|
| 865 | + unset($afrom[$cle]); |
|
| 866 | + } |
|
| 867 | + $equiv[] = $carr; |
|
| 868 | + } else { |
|
| 869 | + unset($join[$cledef]); |
|
| 870 | + if (isset($where_simples[$cle_where_lie])) { |
|
| 871 | + unset($where_simples[$cle_where_lie]); |
|
| 872 | + unset($where[$cle_where_lie]); |
|
| 873 | + } |
|
| 874 | + } |
|
| 875 | + unset($from[$cle]); |
|
| 876 | + $k--; |
|
| 877 | + } |
|
| 878 | + |
|
| 879 | + if (count($afrom)) { |
|
| 880 | + // Regarder si la table principale ne sert finalement a rien comme dans |
|
| 881 | + //<BOUCLE3(MOTS){id_article}{id_mot}> class='on'</BOUCLE3> |
|
| 882 | + //<BOUCLE2(MOTS){id_article} />#TOTAL_BOUCLE<//B2> |
|
| 883 | + //<BOUCLE5(RUBRIQUES){id_mot}{tout} />#TOTAL_BOUCLE<//B5> |
|
| 884 | + // ou dans |
|
| 885 | + //<BOUCLE8(HIERARCHIE){id_rubrique}{tout}{type='Squelette'}{inverse}{0,1}{lang_select=non} />#TOTAL_BOUCLE<//B8> |
|
| 886 | + // qui comporte plusieurs jointures |
|
| 887 | + // ou dans |
|
| 888 | + // <BOUCLE6(ARTICLES){id_mot=2}{statut==.*} />#TOTAL_BOUCLE<//B6> |
|
| 889 | + // <BOUCLE7(ARTICLES){id_mot>0}{statut?} />#TOTAL_BOUCLE<//B7> |
|
| 890 | + // penser a regarder aussi la clause orderby pour ne pas simplifier abusivement |
|
| 891 | + // <BOUCLE9(ARTICLES){recherche truc}{par titre}>#ID_ARTICLE</BOUCLE9> |
|
| 892 | + // penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement |
|
| 893 | + // <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10> |
|
| 894 | + |
|
| 895 | + $t = key($from); |
|
| 896 | + $c = current($from); |
|
| 897 | + reset($from); |
|
| 898 | + $e = '/\b(' . "$t\\." . join('|' . $t . '\.', $equiv) . ')\b/'; |
|
| 899 | + if ( |
|
| 900 | + !(strpos($t, ' ') or // jointure des le depart cf boucle_doc |
|
| 901 | + calculer_jointnul($t, $select, $e) or |
|
| 902 | + calculer_jointnul($t, $join, $e) or |
|
| 903 | + calculer_jointnul($t, $where, $e) or |
|
| 904 | + calculer_jointnul($t, $orderby, $e) or |
|
| 905 | + calculer_jointnul($t, $groupby, $e) or |
|
| 906 | + calculer_jointnul($t, $having, $e)) |
|
| 907 | + && count($afrom[$t]) |
|
| 908 | + ) { |
|
| 909 | + $nfrom = reset($afrom[$t]); |
|
| 910 | + $nt = array_key_first($afrom[$t]); |
|
| 911 | + unset($from[$t]); |
|
| 912 | + $from[$nt] = $nfrom[1]; |
|
| 913 | + unset($afrom[$t][$nt]); |
|
| 914 | + $afrom[$nt] = $afrom[$t]; |
|
| 915 | + unset($afrom[$t]); |
|
| 916 | + $e = '/\b' . preg_quote($nfrom[6]) . '\b/'; |
|
| 917 | + $t = $nfrom[4]; |
|
| 918 | + $alias = ''; |
|
| 919 | + // verifier que les deux cles sont homonymes, sinon installer un alias dans le select |
|
| 920 | + $oldcle = explode('.', $nfrom[6]); |
|
| 921 | + $oldcle = end($oldcle); |
|
| 922 | + $newcle = explode('.', $nfrom[4]); |
|
| 923 | + $newcle = end($newcle); |
|
| 924 | + if ($newcle != $oldcle) { |
|
| 925 | + // si l'ancienne cle etait deja dans le select avec un AS |
|
| 926 | + // reprendre simplement ce AS |
|
| 927 | + $as = '/\b' . preg_quote($nfrom[6]) . '\s+(AS\s+\w+)\b/'; |
|
| 928 | + if (preg_match($as, implode(',', $select), $m)) { |
|
| 929 | + $alias = ''; |
|
| 930 | + } else { |
|
| 931 | + $alias = ', ' . $nfrom[4] . " AS $oldcle"; |
|
| 932 | + } |
|
| 933 | + } |
|
| 934 | + $select = remplacer_jointnul($t . $alias, $select, $e); |
|
| 935 | + $join = remplacer_jointnul($t, $join, $e); |
|
| 936 | + $where = remplacer_jointnul($t, $where, $e); |
|
| 937 | + $having = remplacer_jointnul($t, $having, $e); |
|
| 938 | + $groupby = remplacer_jointnul($t, $groupby, $e); |
|
| 939 | + $orderby = remplacer_jointnul($t, $orderby, $e); |
|
| 940 | + } |
|
| 941 | + $from = reinjecte_joint($afrom, $from); |
|
| 942 | + } |
|
| 943 | + if (empty($GLOBALS['debug']) or !is_array($GLOBALS['debug'])) { |
|
| 944 | + $wasdebug = empty($GLOBALS['debug']) ? false : $GLOBALS['debug']; |
|
| 945 | + $GLOBALS['debug'] = []; |
|
| 946 | + if ($wasdebug) { |
|
| 947 | + $GLOBALS['debug']['debug'] = true; |
|
| 948 | + } |
|
| 949 | + } |
|
| 950 | + $GLOBALS['debug']['aucasou'] = [$table, $id, $serveur, $requeter]; |
|
| 951 | + $r = sql_select( |
|
| 952 | + $select, |
|
| 953 | + $from, |
|
| 954 | + $where, |
|
| 955 | + $groupby, |
|
| 956 | + array_filter($orderby), |
|
| 957 | + $limit, |
|
| 958 | + $having, |
|
| 959 | + $serveur, |
|
| 960 | + $requeter |
|
| 961 | + ); |
|
| 962 | + unset($GLOBALS['debug']['aucasou']); |
|
| 963 | + |
|
| 964 | + return $r; |
|
| 965 | 965 | } |
| 966 | 966 | |
| 967 | 967 | /** |
@@ -972,79 +972,79 @@ discard block |
||
| 972 | 972 | * @return string |
| 973 | 973 | */ |
| 974 | 974 | function calculer_where_to_string($v, $join = 'AND') { |
| 975 | - if (empty($v)) { |
|
| 976 | - return ''; |
|
| 977 | - } |
|
| 978 | - |
|
| 979 | - if (!is_array($v)) { |
|
| 980 | - return $v; |
|
| 981 | - } else { |
|
| 982 | - $exp = ''; |
|
| 983 | - if (strtoupper($join) === 'AND') { |
|
| 984 | - return $exp . join(" $join ", array_map('calculer_where_to_string', $v)); |
|
| 985 | - } else { |
|
| 986 | - return $exp . join($join, $v); |
|
| 987 | - } |
|
| 988 | - } |
|
| 975 | + if (empty($v)) { |
|
| 976 | + return ''; |
|
| 977 | + } |
|
| 978 | + |
|
| 979 | + if (!is_array($v)) { |
|
| 980 | + return $v; |
|
| 981 | + } else { |
|
| 982 | + $exp = ''; |
|
| 983 | + if (strtoupper($join) === 'AND') { |
|
| 984 | + return $exp . join(" $join ", array_map('calculer_where_to_string', $v)); |
|
| 985 | + } else { |
|
| 986 | + return $exp . join($join, $v); |
|
| 987 | + } |
|
| 988 | + } |
|
| 989 | 989 | } |
| 990 | 990 | |
| 991 | 991 | |
| 992 | 992 | //condition suffisante (mais non necessaire) pour qu'une table soit utile |
| 993 | 993 | |
| 994 | 994 | function calculer_jointnul($cle, $exp, $equiv = '') { |
| 995 | - if (!is_array($exp)) { |
|
| 996 | - if ($equiv) { |
|
| 997 | - $exp = preg_replace($equiv, '', $exp); |
|
| 998 | - } |
|
| 999 | - |
|
| 1000 | - return preg_match("/\\b$cle\\./", $exp); |
|
| 1001 | - } else { |
|
| 1002 | - foreach ($exp as $v) { |
|
| 1003 | - if (calculer_jointnul($cle, $v, $equiv)) { |
|
| 1004 | - return true; |
|
| 1005 | - } |
|
| 1006 | - } |
|
| 1007 | - |
|
| 1008 | - return false; |
|
| 1009 | - } |
|
| 995 | + if (!is_array($exp)) { |
|
| 996 | + if ($equiv) { |
|
| 997 | + $exp = preg_replace($equiv, '', $exp); |
|
| 998 | + } |
|
| 999 | + |
|
| 1000 | + return preg_match("/\\b$cle\\./", $exp); |
|
| 1001 | + } else { |
|
| 1002 | + foreach ($exp as $v) { |
|
| 1003 | + if (calculer_jointnul($cle, $v, $equiv)) { |
|
| 1004 | + return true; |
|
| 1005 | + } |
|
| 1006 | + } |
|
| 1007 | + |
|
| 1008 | + return false; |
|
| 1009 | + } |
|
| 1010 | 1010 | } |
| 1011 | 1011 | |
| 1012 | 1012 | function reinjecte_joint($afrom, $from) { |
| 1013 | - $from_synth = []; |
|
| 1014 | - foreach ($from as $k => $v) { |
|
| 1015 | - $from_synth[$k] = $from[$k]; |
|
| 1016 | - if (isset($afrom[$k])) { |
|
| 1017 | - foreach ($afrom[$k] as $kk => $vv) { |
|
| 1018 | - $afrom[$k][$kk] = implode(' ', $afrom[$k][$kk]); |
|
| 1019 | - } |
|
| 1020 | - $from_synth["$k@"] = implode(' ', $afrom[$k]); |
|
| 1021 | - unset($afrom[$k]); |
|
| 1022 | - } |
|
| 1023 | - } |
|
| 1024 | - |
|
| 1025 | - return $from_synth; |
|
| 1013 | + $from_synth = []; |
|
| 1014 | + foreach ($from as $k => $v) { |
|
| 1015 | + $from_synth[$k] = $from[$k]; |
|
| 1016 | + if (isset($afrom[$k])) { |
|
| 1017 | + foreach ($afrom[$k] as $kk => $vv) { |
|
| 1018 | + $afrom[$k][$kk] = implode(' ', $afrom[$k][$kk]); |
|
| 1019 | + } |
|
| 1020 | + $from_synth["$k@"] = implode(' ', $afrom[$k]); |
|
| 1021 | + unset($afrom[$k]); |
|
| 1022 | + } |
|
| 1023 | + } |
|
| 1024 | + |
|
| 1025 | + return $from_synth; |
|
| 1026 | 1026 | } |
| 1027 | 1027 | |
| 1028 | 1028 | function remplacer_jointnul($cle, $exp, $equiv = '') { |
| 1029 | - if (!is_array($exp)) { |
|
| 1030 | - return preg_replace($equiv, $cle, $exp); |
|
| 1031 | - } else { |
|
| 1032 | - foreach ($exp as $k => $v) { |
|
| 1033 | - $exp[$k] = remplacer_jointnul($cle, $v, $equiv); |
|
| 1034 | - } |
|
| 1035 | - |
|
| 1036 | - return $exp; |
|
| 1037 | - } |
|
| 1029 | + if (!is_array($exp)) { |
|
| 1030 | + return preg_replace($equiv, $cle, $exp); |
|
| 1031 | + } else { |
|
| 1032 | + foreach ($exp as $k => $v) { |
|
| 1033 | + $exp[$k] = remplacer_jointnul($cle, $v, $equiv); |
|
| 1034 | + } |
|
| 1035 | + |
|
| 1036 | + return $exp; |
|
| 1037 | + } |
|
| 1038 | 1038 | } |
| 1039 | 1039 | |
| 1040 | 1040 | // calcul du nom du squelette |
| 1041 | 1041 | function calculer_nom_fonction_squel($skel, $mime_type = 'html', string $connect = '') { |
| 1042 | - // ne pas doublonner les squelette selon qu'ils sont calcules depuis ecrire/ ou depuis la racine |
|
| 1043 | - if ($l = strlen(_DIR_RACINE) and strncmp($skel, _DIR_RACINE, $l) == 0) { |
|
| 1044 | - $skel = substr($skel, strlen(_DIR_RACINE)); |
|
| 1045 | - } |
|
| 1046 | - |
|
| 1047 | - return $mime_type |
|
| 1048 | - . (!$connect ? '' : preg_replace('/\W/', '_', $connect)) . '_' |
|
| 1049 | - . md5($GLOBALS['spip_version_code'] . ' * ' . $skel . (isset($GLOBALS['marqueur_skel']) ? '*' . $GLOBALS['marqueur_skel'] : '')); |
|
| 1042 | + // ne pas doublonner les squelette selon qu'ils sont calcules depuis ecrire/ ou depuis la racine |
|
| 1043 | + if ($l = strlen(_DIR_RACINE) and strncmp($skel, _DIR_RACINE, $l) == 0) { |
|
| 1044 | + $skel = substr($skel, strlen(_DIR_RACINE)); |
|
| 1045 | + } |
|
| 1046 | + |
|
| 1047 | + return $mime_type |
|
| 1048 | + . (!$connect ? '' : preg_replace('/\W/', '_', $connect)) . '_' |
|
| 1049 | + . md5($GLOBALS['spip_version_code'] . ' * ' . $skel . (isset($GLOBALS['marqueur_skel']) ? '*' . $GLOBALS['marqueur_skel'] : '')); |
|
| 1050 | 1050 | } |
@@ -11,7 +11,7 @@ discard block |
||
| 11 | 11 | \***************************************************************************/ |
| 12 | 12 | |
| 13 | 13 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 14 | - return; |
|
| 14 | + return; |
|
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | include_spip('public/decompiler'); |
@@ -66,136 +66,136 @@ discard block |
||
| 66 | 66 | * - string si $message à false. |
| 67 | 67 | **/ |
| 68 | 68 | function public_debusquer_dist($message = '', $lieu = '', $opt = []) { |
| 69 | - static $tableau_des_erreurs = []; |
|
| 70 | - |
|
| 71 | - // Pour des tests unitaires, pouvoir récupérer les erreurs générées |
|
| 72 | - if (isset($opt['erreurs'])) { |
|
| 73 | - if ($opt['erreurs'] == 'get') { |
|
| 74 | - return $tableau_des_erreurs; |
|
| 75 | - } |
|
| 76 | - if ($opt['erreurs'] == 'reset') { |
|
| 77 | - $tableau_des_erreurs = []; |
|
| 78 | - |
|
| 79 | - return true; |
|
| 80 | - } |
|
| 81 | - } |
|
| 82 | - |
|
| 83 | - // Erreur ou appel final ? |
|
| 84 | - if ($message) { |
|
| 85 | - $message = debusquer_compose_message($message); |
|
| 86 | - $tableau_des_erreurs[] = [$message, $lieu]; |
|
| 87 | - set_request('var_mode', 'debug'); |
|
| 88 | - $GLOBALS['bouton_admin_debug'] = true; |
|
| 89 | - // Permettre a la compil de continuer |
|
| 90 | - if (is_object($lieu) and (!isset($lieu->code) or !$lieu->code)) { |
|
| 91 | - $lieu->code = "''"; |
|
| 92 | - } |
|
| 93 | - // forcer l'appel au debusqueur en cas de boucles infernales |
|
| 94 | - $urgence = (_DEBUG_MAX_SQUELETTE_ERREURS and (is_countable($tableau_des_erreurs) ? count($tableau_des_erreurs) : 0) > _DEBUG_MAX_SQUELETTE_ERREURS); |
|
| 95 | - if (!$urgence) { |
|
| 96 | - return; |
|
| 97 | - } |
|
| 98 | - } |
|
| 99 | - if (empty($GLOBALS['debug_objets']['principal'])) { |
|
| 100 | - // espace public ? |
|
| 101 | - if (isset($GLOBALS['fond'])) { |
|
| 102 | - $GLOBALS['debug_objets']['principal'] = $GLOBALS['fond']; |
|
| 103 | - } |
|
| 104 | - } |
|
| 105 | - |
|
| 106 | - include_spip('inc/autoriser'); |
|
| 107 | - if (!autoriser('debug')) { |
|
| 108 | - return; |
|
| 109 | - } |
|
| 110 | - include_spip('inc/headers'); |
|
| 111 | - include_spip('inc/filtres'); |
|
| 112 | - |
|
| 113 | - // en cas de squelette inclus, virer le code de l'incluant: |
|
| 114 | - // - il contient souvent une Div restreignant la largeur a 3 fois rien |
|
| 115 | - // - ca fait 2 headers ! |
|
| 116 | - // sauf si l'on se trouve deja dans un flux compresse (plugin compresseur |
|
| 117 | - // actif par exemple) |
|
| 118 | - if ( |
|
| 119 | - ob_get_length() |
|
| 120 | - and |
|
| 121 | - !in_array('ob_gzhandler', ob_get_status()) |
|
| 122 | - ) { |
|
| 123 | - ob_end_clean(); |
|
| 124 | - } |
|
| 125 | - |
|
| 126 | - lang_select($GLOBALS['visiteur_session']['lang']); |
|
| 127 | - $fonc = _request('var_mode_objet'); |
|
| 128 | - $mode = _request('var_mode_affiche'); |
|
| 129 | - $self = str_replace("\\'", ''', self()); |
|
| 130 | - $self = parametre_url($self, 'var_mode', 'debug'); |
|
| 131 | - |
|
| 132 | - $res = debusquer_bandeau($tableau_des_erreurs) |
|
| 133 | - . '<br />' |
|
| 134 | - . debusquer_squelette($fonc, $mode, $self); |
|
| 135 | - |
|
| 136 | - if (!_DIR_RESTREINT or headers_sent()) { |
|
| 137 | - return $res; |
|
| 138 | - } |
|
| 139 | - if ($tableau_des_erreurs) { |
|
| 140 | - http_response_code(503); |
|
| 141 | - } |
|
| 142 | - |
|
| 143 | - http_no_cache(); |
|
| 144 | - if (isset($_GET['var_profile'])) { |
|
| 145 | - $titre = parametre_url($GLOBALS['REQUEST_URI'], 'var_profile', ''); |
|
| 146 | - $titre = parametre_url($titre, 'var_mode', ''); |
|
| 147 | - } else { |
|
| 148 | - if (!$fonc) { |
|
| 149 | - $fonc = $GLOBALS['debug_objets']['principal']; |
|
| 150 | - } |
|
| 151 | - $titre = !$mode ? $fonc : ($mode . (isset($GLOBALS['debug_objets']['sourcefile'][$fonc]) ? ' ' . $GLOBALS['debug_objets']['sourcefile'][$fonc] : '')); |
|
| 152 | - } |
|
| 153 | - if ($message === false) { |
|
| 154 | - lang_select(); |
|
| 155 | - |
|
| 156 | - return debusquer_entete($titre, $res); |
|
| 157 | - } else { |
|
| 158 | - echo debusquer_entete($titre, $res); |
|
| 159 | - } |
|
| 160 | - exit; |
|
| 69 | + static $tableau_des_erreurs = []; |
|
| 70 | + |
|
| 71 | + // Pour des tests unitaires, pouvoir récupérer les erreurs générées |
|
| 72 | + if (isset($opt['erreurs'])) { |
|
| 73 | + if ($opt['erreurs'] == 'get') { |
|
| 74 | + return $tableau_des_erreurs; |
|
| 75 | + } |
|
| 76 | + if ($opt['erreurs'] == 'reset') { |
|
| 77 | + $tableau_des_erreurs = []; |
|
| 78 | + |
|
| 79 | + return true; |
|
| 80 | + } |
|
| 81 | + } |
|
| 82 | + |
|
| 83 | + // Erreur ou appel final ? |
|
| 84 | + if ($message) { |
|
| 85 | + $message = debusquer_compose_message($message); |
|
| 86 | + $tableau_des_erreurs[] = [$message, $lieu]; |
|
| 87 | + set_request('var_mode', 'debug'); |
|
| 88 | + $GLOBALS['bouton_admin_debug'] = true; |
|
| 89 | + // Permettre a la compil de continuer |
|
| 90 | + if (is_object($lieu) and (!isset($lieu->code) or !$lieu->code)) { |
|
| 91 | + $lieu->code = "''"; |
|
| 92 | + } |
|
| 93 | + // forcer l'appel au debusqueur en cas de boucles infernales |
|
| 94 | + $urgence = (_DEBUG_MAX_SQUELETTE_ERREURS and (is_countable($tableau_des_erreurs) ? count($tableau_des_erreurs) : 0) > _DEBUG_MAX_SQUELETTE_ERREURS); |
|
| 95 | + if (!$urgence) { |
|
| 96 | + return; |
|
| 97 | + } |
|
| 98 | + } |
|
| 99 | + if (empty($GLOBALS['debug_objets']['principal'])) { |
|
| 100 | + // espace public ? |
|
| 101 | + if (isset($GLOBALS['fond'])) { |
|
| 102 | + $GLOBALS['debug_objets']['principal'] = $GLOBALS['fond']; |
|
| 103 | + } |
|
| 104 | + } |
|
| 105 | + |
|
| 106 | + include_spip('inc/autoriser'); |
|
| 107 | + if (!autoriser('debug')) { |
|
| 108 | + return; |
|
| 109 | + } |
|
| 110 | + include_spip('inc/headers'); |
|
| 111 | + include_spip('inc/filtres'); |
|
| 112 | + |
|
| 113 | + // en cas de squelette inclus, virer le code de l'incluant: |
|
| 114 | + // - il contient souvent une Div restreignant la largeur a 3 fois rien |
|
| 115 | + // - ca fait 2 headers ! |
|
| 116 | + // sauf si l'on se trouve deja dans un flux compresse (plugin compresseur |
|
| 117 | + // actif par exemple) |
|
| 118 | + if ( |
|
| 119 | + ob_get_length() |
|
| 120 | + and |
|
| 121 | + !in_array('ob_gzhandler', ob_get_status()) |
|
| 122 | + ) { |
|
| 123 | + ob_end_clean(); |
|
| 124 | + } |
|
| 125 | + |
|
| 126 | + lang_select($GLOBALS['visiteur_session']['lang']); |
|
| 127 | + $fonc = _request('var_mode_objet'); |
|
| 128 | + $mode = _request('var_mode_affiche'); |
|
| 129 | + $self = str_replace("\\'", ''', self()); |
|
| 130 | + $self = parametre_url($self, 'var_mode', 'debug'); |
|
| 131 | + |
|
| 132 | + $res = debusquer_bandeau($tableau_des_erreurs) |
|
| 133 | + . '<br />' |
|
| 134 | + . debusquer_squelette($fonc, $mode, $self); |
|
| 135 | + |
|
| 136 | + if (!_DIR_RESTREINT or headers_sent()) { |
|
| 137 | + return $res; |
|
| 138 | + } |
|
| 139 | + if ($tableau_des_erreurs) { |
|
| 140 | + http_response_code(503); |
|
| 141 | + } |
|
| 142 | + |
|
| 143 | + http_no_cache(); |
|
| 144 | + if (isset($_GET['var_profile'])) { |
|
| 145 | + $titre = parametre_url($GLOBALS['REQUEST_URI'], 'var_profile', ''); |
|
| 146 | + $titre = parametre_url($titre, 'var_mode', ''); |
|
| 147 | + } else { |
|
| 148 | + if (!$fonc) { |
|
| 149 | + $fonc = $GLOBALS['debug_objets']['principal']; |
|
| 150 | + } |
|
| 151 | + $titre = !$mode ? $fonc : ($mode . (isset($GLOBALS['debug_objets']['sourcefile'][$fonc]) ? ' ' . $GLOBALS['debug_objets']['sourcefile'][$fonc] : '')); |
|
| 152 | + } |
|
| 153 | + if ($message === false) { |
|
| 154 | + lang_select(); |
|
| 155 | + |
|
| 156 | + return debusquer_entete($titre, $res); |
|
| 157 | + } else { |
|
| 158 | + echo debusquer_entete($titre, $res); |
|
| 159 | + } |
|
| 160 | + exit; |
|
| 161 | 161 | } |
| 162 | 162 | |
| 163 | 163 | function debusquer_compose_message($msg) { |
| 164 | - if (is_array($msg)) { |
|
| 165 | - // si c'est un texte, c'est une traduction a faire, mais |
|
| 166 | - // sqlite renvoit aussi des erreurs alpha num (mais avec 3 arguments) |
|
| 167 | - if (!is_numeric($msg[0]) and count($msg) == 2) { |
|
| 168 | - // message avec argument: instancier |
|
| 169 | - $msg = _T($msg[0], $msg[1], 'spip-debug-arg'); |
|
| 170 | - } else { |
|
| 171 | - // message SQL: interpreter |
|
| 172 | - $msg = debusquer_requete($msg); |
|
| 173 | - } |
|
| 174 | - } |
|
| 175 | - // FIXME: le fond n'est pas la si on n'est pas dans un squelette |
|
| 176 | - // cela dit, ca serait bien d'indiquer tout de meme d'ou vient l'erreur |
|
| 177 | - $fond = $GLOBALS['fond'] ?? ''; |
|
| 178 | - // une erreur critique sort $message en array |
|
| 179 | - $debug = is_array($msg) ? $msg[1] : $msg; |
|
| 180 | - spip_log('Debug: ' . $debug . ' (' . $fond . ')'); |
|
| 181 | - |
|
| 182 | - return $msg; |
|
| 164 | + if (is_array($msg)) { |
|
| 165 | + // si c'est un texte, c'est une traduction a faire, mais |
|
| 166 | + // sqlite renvoit aussi des erreurs alpha num (mais avec 3 arguments) |
|
| 167 | + if (!is_numeric($msg[0]) and count($msg) == 2) { |
|
| 168 | + // message avec argument: instancier |
|
| 169 | + $msg = _T($msg[0], $msg[1], 'spip-debug-arg'); |
|
| 170 | + } else { |
|
| 171 | + // message SQL: interpreter |
|
| 172 | + $msg = debusquer_requete($msg); |
|
| 173 | + } |
|
| 174 | + } |
|
| 175 | + // FIXME: le fond n'est pas la si on n'est pas dans un squelette |
|
| 176 | + // cela dit, ca serait bien d'indiquer tout de meme d'ou vient l'erreur |
|
| 177 | + $fond = $GLOBALS['fond'] ?? ''; |
|
| 178 | + // une erreur critique sort $message en array |
|
| 179 | + $debug = is_array($msg) ? $msg[1] : $msg; |
|
| 180 | + spip_log('Debug: ' . $debug . ' (' . $fond . ')'); |
|
| 181 | + |
|
| 182 | + return $msg; |
|
| 183 | 183 | } |
| 184 | 184 | |
| 185 | 185 | function debusquer_bandeau($erreurs) { |
| 186 | 186 | |
| 187 | - if (!empty($erreurs)) { |
|
| 188 | - $n = [(is_countable($erreurs) ? count($erreurs) : 0) . ' ' . _T('zbug_erreur_squelette')]; |
|
| 187 | + if (!empty($erreurs)) { |
|
| 188 | + $n = [(is_countable($erreurs) ? count($erreurs) : 0) . ' ' . _T('zbug_erreur_squelette')]; |
|
| 189 | 189 | |
| 190 | - return debusquer_navigation($erreurs, $n); |
|
| 191 | - } elseif (!empty($GLOBALS['tableau_des_temps'])) { |
|
| 192 | - include_spip('public/tracer'); |
|
| 193 | - [$temps, $nav] = chrono_requete($GLOBALS['tableau_des_temps']); |
|
| 190 | + return debusquer_navigation($erreurs, $n); |
|
| 191 | + } elseif (!empty($GLOBALS['tableau_des_temps'])) { |
|
| 192 | + include_spip('public/tracer'); |
|
| 193 | + [$temps, $nav] = chrono_requete($GLOBALS['tableau_des_temps']); |
|
| 194 | 194 | |
| 195 | - return debusquer_navigation($temps, $nav, 'debug-profile'); |
|
| 196 | - } else { |
|
| 197 | - return ''; |
|
| 198 | - } |
|
| 195 | + return debusquer_navigation($temps, $nav, 'debug-profile'); |
|
| 196 | + } else { |
|
| 197 | + return ''; |
|
| 198 | + } |
|
| 199 | 199 | } |
| 200 | 200 | |
| 201 | 201 | /** |
@@ -205,42 +205,42 @@ discard block |
||
| 205 | 205 | * @return string Code HTML |
| 206 | 206 | **/ |
| 207 | 207 | function debusquer_contexte($env) { |
| 208 | - if (is_string($env) and is_array($env_tab = @unserialize($env))) { |
|
| 209 | - $env = $env_tab; |
|
| 210 | - } |
|
| 211 | - |
|
| 212 | - if (!$env) { |
|
| 213 | - return ''; |
|
| 214 | - } |
|
| 215 | - $res = ''; |
|
| 216 | - foreach ($env as $nom => $valeur) { |
|
| 217 | - if (is_array($valeur)) { |
|
| 218 | - $valeur_simple = []; |
|
| 219 | - foreach ($valeur as $v) { |
|
| 220 | - if (is_array($v)) { |
|
| 221 | - $valeur_simple[] = 'array:' . count($v); |
|
| 222 | - } elseif (is_object($v)) { |
|
| 223 | - $valeur_simple[] = get_class($v); |
|
| 224 | - } elseif (is_string($v)) { |
|
| 225 | - $valeur_simple[] = "'" . $v . "'"; |
|
| 226 | - } else { |
|
| 227 | - $valeur_simple[] = $v; |
|
| 228 | - } |
|
| 229 | - } |
|
| 230 | - $n = count($valeur); |
|
| 231 | - $valeur = (($n > 3) ? 'array:' . $n . ' ' : ''); |
|
| 232 | - $valeur .= '[' . join(', ', $valeur_simple) . ']'; |
|
| 233 | - } elseif (is_object($valeur)) { |
|
| 234 | - $valeur = get_class($valeur); |
|
| 235 | - } elseif (is_string($valeur)) { |
|
| 236 | - $valeur = "'" . $valeur . "'"; |
|
| 237 | - } |
|
| 238 | - $res .= "\n<tr><td><strong>" . nl2br(entites_html($nom)) |
|
| 239 | - . '</strong></td><td>: ' . nl2br(entites_html($valeur)) |
|
| 240 | - . "</td></tr>\n"; |
|
| 241 | - } |
|
| 242 | - |
|
| 243 | - return "<div class='spip-env'><fieldset><legend onclick=\"this.parentElement.classList.toggle('expanded');\">#ENV</legend>\n<div><table>$res</table></div></fieldset></div>\n"; |
|
| 208 | + if (is_string($env) and is_array($env_tab = @unserialize($env))) { |
|
| 209 | + $env = $env_tab; |
|
| 210 | + } |
|
| 211 | + |
|
| 212 | + if (!$env) { |
|
| 213 | + return ''; |
|
| 214 | + } |
|
| 215 | + $res = ''; |
|
| 216 | + foreach ($env as $nom => $valeur) { |
|
| 217 | + if (is_array($valeur)) { |
|
| 218 | + $valeur_simple = []; |
|
| 219 | + foreach ($valeur as $v) { |
|
| 220 | + if (is_array($v)) { |
|
| 221 | + $valeur_simple[] = 'array:' . count($v); |
|
| 222 | + } elseif (is_object($v)) { |
|
| 223 | + $valeur_simple[] = get_class($v); |
|
| 224 | + } elseif (is_string($v)) { |
|
| 225 | + $valeur_simple[] = "'" . $v . "'"; |
|
| 226 | + } else { |
|
| 227 | + $valeur_simple[] = $v; |
|
| 228 | + } |
|
| 229 | + } |
|
| 230 | + $n = count($valeur); |
|
| 231 | + $valeur = (($n > 3) ? 'array:' . $n . ' ' : ''); |
|
| 232 | + $valeur .= '[' . join(', ', $valeur_simple) . ']'; |
|
| 233 | + } elseif (is_object($valeur)) { |
|
| 234 | + $valeur = get_class($valeur); |
|
| 235 | + } elseif (is_string($valeur)) { |
|
| 236 | + $valeur = "'" . $valeur . "'"; |
|
| 237 | + } |
|
| 238 | + $res .= "\n<tr><td><strong>" . nl2br(entites_html($nom)) |
|
| 239 | + . '</strong></td><td>: ' . nl2br(entites_html($valeur)) |
|
| 240 | + . "</td></tr>\n"; |
|
| 241 | + } |
|
| 242 | + |
|
| 243 | + return "<div class='spip-env'><fieldset><legend onclick=\"this.parentElement.classList.toggle('expanded');\">#ENV</legend>\n<div><table>$res</table></div></fieldset></div>\n"; |
|
| 244 | 244 | } |
| 245 | 245 | |
| 246 | 246 | // Affichage du tableau des erreurs ou des temps de calcul |
@@ -248,66 +248,66 @@ discard block |
||
| 248 | 248 | |
| 249 | 249 | function debusquer_navigation($tableau, $caption = [], $id = 'debug-nav') { |
| 250 | 250 | |
| 251 | - if (_request('exec') == 'valider_xml') { |
|
| 252 | - return ''; |
|
| 253 | - } |
|
| 254 | - $GLOBALS['bouton_admin_debug'] = true; |
|
| 255 | - $res = ''; |
|
| 256 | - $href = quote_amp(parametre_url($GLOBALS['REQUEST_URI'], 'var_mode', 'debug')); |
|
| 257 | - foreach ($tableau as $i => $err) { |
|
| 258 | - $boucle = $ligne = $skel = ''; |
|
| 259 | - [$msg, $lieu] = $err; |
|
| 260 | - if (is_object($lieu)) { |
|
| 261 | - $ligne = $lieu->ligne; |
|
| 262 | - $boucle = !empty($lieu->id_boucle) ? $lieu->id_boucle : ''; |
|
| 263 | - if (isset($lieu->descr['nom'])) { |
|
| 264 | - $nom_code = $lieu->descr['nom']; |
|
| 265 | - $skel = $lieu->descr['sourcefile']; |
|
| 266 | - $h2 = parametre_url($href, 'var_mode_objet', $nom_code); |
|
| 267 | - $h3 = parametre_url($h2, 'var_mode_affiche', 'squelette') . '#L' . $ligne; |
|
| 268 | - $skel = "<a href='$h3'><b>$skel</b></a>"; |
|
| 269 | - if ($boucle) { |
|
| 270 | - $h3 = parametre_url($h2 . $boucle, 'var_mode_affiche', 'boucle'); |
|
| 271 | - $boucle = "<a href='$h3'><b>$boucle</b></a>"; |
|
| 272 | - } |
|
| 273 | - } |
|
| 274 | - } |
|
| 275 | - |
|
| 276 | - $j = ($i + 1); |
|
| 277 | - $res .= "<tr id='req$j'><td style='text-align: right'>" |
|
| 278 | - . $j |
|
| 279 | - . " </td><td style='text-align: left'>" |
|
| 280 | - . (is_array($msg) ? implode('', $msg) : $msg) |
|
| 281 | - . "</td><td style='text-align: left'>" |
|
| 282 | - . ($skel ?: ' / ') |
|
| 283 | - . "</td><td class='spip-debug-arg' style='text-align: left'>" |
|
| 284 | - . ($boucle ?: ' / ') |
|
| 285 | - . "</td><td style='text-align: right'>" |
|
| 286 | - . $ligne |
|
| 287 | - . "</td></tr>\n"; |
|
| 288 | - } |
|
| 289 | - |
|
| 290 | - return "\n<table id='$id'>" |
|
| 291 | - . "<caption onclick=\"x = document.getElementById('$id'); (x.style.display == '' ? x.style.display = 'none' : x.style.display = '');\">" |
|
| 292 | - . $caption[0] |
|
| 251 | + if (_request('exec') == 'valider_xml') { |
|
| 252 | + return ''; |
|
| 253 | + } |
|
| 254 | + $GLOBALS['bouton_admin_debug'] = true; |
|
| 255 | + $res = ''; |
|
| 256 | + $href = quote_amp(parametre_url($GLOBALS['REQUEST_URI'], 'var_mode', 'debug')); |
|
| 257 | + foreach ($tableau as $i => $err) { |
|
| 258 | + $boucle = $ligne = $skel = ''; |
|
| 259 | + [$msg, $lieu] = $err; |
|
| 260 | + if (is_object($lieu)) { |
|
| 261 | + $ligne = $lieu->ligne; |
|
| 262 | + $boucle = !empty($lieu->id_boucle) ? $lieu->id_boucle : ''; |
|
| 263 | + if (isset($lieu->descr['nom'])) { |
|
| 264 | + $nom_code = $lieu->descr['nom']; |
|
| 265 | + $skel = $lieu->descr['sourcefile']; |
|
| 266 | + $h2 = parametre_url($href, 'var_mode_objet', $nom_code); |
|
| 267 | + $h3 = parametre_url($h2, 'var_mode_affiche', 'squelette') . '#L' . $ligne; |
|
| 268 | + $skel = "<a href='$h3'><b>$skel</b></a>"; |
|
| 269 | + if ($boucle) { |
|
| 270 | + $h3 = parametre_url($h2 . $boucle, 'var_mode_affiche', 'boucle'); |
|
| 271 | + $boucle = "<a href='$h3'><b>$boucle</b></a>"; |
|
| 272 | + } |
|
| 273 | + } |
|
| 274 | + } |
|
| 275 | + |
|
| 276 | + $j = ($i + 1); |
|
| 277 | + $res .= "<tr id='req$j'><td style='text-align: right'>" |
|
| 278 | + . $j |
|
| 279 | + . " </td><td style='text-align: left'>" |
|
| 280 | + . (is_array($msg) ? implode('', $msg) : $msg) |
|
| 281 | + . "</td><td style='text-align: left'>" |
|
| 282 | + . ($skel ?: ' / ') |
|
| 283 | + . "</td><td class='spip-debug-arg' style='text-align: left'>" |
|
| 284 | + . ($boucle ?: ' / ') |
|
| 285 | + . "</td><td style='text-align: right'>" |
|
| 286 | + . $ligne |
|
| 287 | + . "</td></tr>\n"; |
|
| 288 | + } |
|
| 289 | + |
|
| 290 | + return "\n<table id='$id'>" |
|
| 291 | + . "<caption onclick=\"x = document.getElementById('$id'); (x.style.display == '' ? x.style.display = 'none' : x.style.display = '');\">" |
|
| 292 | + . $caption[0] |
|
| 293 | 293 | ## aide locale courte a ecrire, avec lien vers une grosse page de documentation |
| 294 | 294 | # aider('erreur_compilation'), |
| 295 | - . '</caption>' |
|
| 296 | - // fausse caption du chrono (mais vraie nav) |
|
| 297 | - . (!empty($caption[1]) ? $caption[1] : '') |
|
| 298 | - . '<tr><th>' |
|
| 299 | - . _T('numero') |
|
| 300 | - . '</th><th>' |
|
| 301 | - . _T('public:message') |
|
| 302 | - . '</th><th>' |
|
| 303 | - . _T('squelette') |
|
| 304 | - . '</th><th>' |
|
| 305 | - . _T('zbug_boucle') |
|
| 306 | - . '</th><th>' |
|
| 307 | - . _T('ligne') |
|
| 308 | - . '</th></tr>' |
|
| 309 | - . $res |
|
| 310 | - . '</table>'; |
|
| 295 | + . '</caption>' |
|
| 296 | + // fausse caption du chrono (mais vraie nav) |
|
| 297 | + . (!empty($caption[1]) ? $caption[1] : '') |
|
| 298 | + . '<tr><th>' |
|
| 299 | + . _T('numero') |
|
| 300 | + . '</th><th>' |
|
| 301 | + . _T('public:message') |
|
| 302 | + . '</th><th>' |
|
| 303 | + . _T('squelette') |
|
| 304 | + . '</th><th>' |
|
| 305 | + . _T('zbug_boucle') |
|
| 306 | + . '</th><th>' |
|
| 307 | + . _T('ligne') |
|
| 308 | + . '</th></tr>' |
|
| 309 | + . $res |
|
| 310 | + . '</table>'; |
|
| 311 | 311 | } |
| 312 | 312 | |
| 313 | 313 | |
@@ -327,514 +327,514 @@ discard block |
||
| 327 | 327 | * ou un tableau si l'erreur est critique |
| 328 | 328 | **/ |
| 329 | 329 | function debusquer_requete($message) { |
| 330 | - [$errno, $msg, $query] = $message; |
|
| 331 | - |
|
| 332 | - // FIXME: ces écritures mélangent divers syntaxe des moteurs SQL |
|
| 333 | - // il serait plus prudent certainement d'avoir une fonction d'analyse par moteur |
|
| 334 | - if (preg_match(',err(no|code):?[[:space:]]*([0-9]+),i', $msg, $regs)) { |
|
| 335 | - $errno = $regs[2]; |
|
| 336 | - } elseif ( |
|
| 337 | - is_numeric($errno) and ($errno == 1030 or $errno <= 1026) |
|
| 338 | - and preg_match(',[^[:alnum:]]([0-9]+)[^[:alnum:]],', $msg, $regs) |
|
| 339 | - ) { |
|
| 340 | - $errno = $regs[1]; |
|
| 341 | - } |
|
| 342 | - |
|
| 343 | - // Erreur systeme |
|
| 344 | - if (is_numeric($errno) and $errno > 0 and $errno < 200) { |
|
| 345 | - $retour = '<tt><br /><br /><blink>' |
|
| 346 | - . _T('info_erreur_systeme', ['errsys' => $errno]) |
|
| 347 | - . "</blink><br />\n<b>" |
|
| 348 | - . _T( |
|
| 349 | - 'info_erreur_systeme2', |
|
| 350 | - ['script' => generer_url_ecrire('base_repair')] |
|
| 351 | - ) |
|
| 352 | - . '</b><br />'; |
|
| 353 | - spip_log("Erreur systeme $errno"); |
|
| 354 | - |
|
| 355 | - return [$retour, '']; |
|
| 356 | - } |
|
| 357 | - |
|
| 358 | - // Requete erronee |
|
| 359 | - $err = '<b>' . _T('avis_erreur_mysql') . " $errno</b><br /><tt>\n" |
|
| 360 | - . spip_htmlspecialchars($msg) |
|
| 361 | - . "\n<br /><span style='color: red'><b>" |
|
| 362 | - . spip_htmlspecialchars($query) |
|
| 363 | - . '</b></span></tt><br />'; |
|
| 364 | - |
|
| 365 | - //. aider('erreur_mysql'); |
|
| 366 | - |
|
| 367 | - return $err; |
|
| 330 | + [$errno, $msg, $query] = $message; |
|
| 331 | + |
|
| 332 | + // FIXME: ces écritures mélangent divers syntaxe des moteurs SQL |
|
| 333 | + // il serait plus prudent certainement d'avoir une fonction d'analyse par moteur |
|
| 334 | + if (preg_match(',err(no|code):?[[:space:]]*([0-9]+),i', $msg, $regs)) { |
|
| 335 | + $errno = $regs[2]; |
|
| 336 | + } elseif ( |
|
| 337 | + is_numeric($errno) and ($errno == 1030 or $errno <= 1026) |
|
| 338 | + and preg_match(',[^[:alnum:]]([0-9]+)[^[:alnum:]],', $msg, $regs) |
|
| 339 | + ) { |
|
| 340 | + $errno = $regs[1]; |
|
| 341 | + } |
|
| 342 | + |
|
| 343 | + // Erreur systeme |
|
| 344 | + if (is_numeric($errno) and $errno > 0 and $errno < 200) { |
|
| 345 | + $retour = '<tt><br /><br /><blink>' |
|
| 346 | + . _T('info_erreur_systeme', ['errsys' => $errno]) |
|
| 347 | + . "</blink><br />\n<b>" |
|
| 348 | + . _T( |
|
| 349 | + 'info_erreur_systeme2', |
|
| 350 | + ['script' => generer_url_ecrire('base_repair')] |
|
| 351 | + ) |
|
| 352 | + . '</b><br />'; |
|
| 353 | + spip_log("Erreur systeme $errno"); |
|
| 354 | + |
|
| 355 | + return [$retour, '']; |
|
| 356 | + } |
|
| 357 | + |
|
| 358 | + // Requete erronee |
|
| 359 | + $err = '<b>' . _T('avis_erreur_mysql') . " $errno</b><br /><tt>\n" |
|
| 360 | + . spip_htmlspecialchars($msg) |
|
| 361 | + . "\n<br /><span style='color: red'><b>" |
|
| 362 | + . spip_htmlspecialchars($query) |
|
| 363 | + . '</b></span></tt><br />'; |
|
| 364 | + |
|
| 365 | + //. aider('erreur_mysql'); |
|
| 366 | + |
|
| 367 | + return $err; |
|
| 368 | 368 | } |
| 369 | 369 | |
| 370 | 370 | |
| 371 | 371 | function trouve_boucle_debug($n, $nom, $debut = 0, $boucle = '') { |
| 372 | 372 | |
| 373 | - $id = $nom . $boucle; |
|
| 374 | - if (is_array($GLOBALS['debug_objets']['sequence'][$id])) { |
|
| 375 | - foreach ($GLOBALS['debug_objets']['sequence'][$id] as $v) { |
|
| 376 | - if (!preg_match('/^(.*)(<\?.*\?>)(.*)$/s', $v[0], $r)) { |
|
| 377 | - $y = substr_count($v[0], "\n"); |
|
| 378 | - } else { |
|
| 379 | - if ($v[1][0] == '#') { // balise dynamique |
|
| 380 | - $incl = $GLOBALS['debug_objets']['resultat'][$v[2]]; |
|
| 381 | - } else // inclusion |
|
| 382 | - { |
|
| 383 | - $incl = $GLOBALS['debug_objets']['squelette'][trouve_squelette_inclus($v[0])]; |
|
| 384 | - } |
|
| 385 | - $y = substr_count($incl, "\n") |
|
| 386 | - + substr_count($r[1], "\n") |
|
| 387 | - + substr_count($r[3], "\n"); |
|
| 388 | - } |
|
| 389 | - if ($n <= ($y + $debut)) { |
|
| 390 | - if ($v[1][0] == '?') { |
|
| 391 | - return trouve_boucle_debug($n, $nom, $debut, substr($v[1], 1)); |
|
| 392 | - } elseif ($v[1][0] == '!') { |
|
| 393 | - if ($incl = trouve_squelette_inclus($v[1])) { |
|
| 394 | - return trouve_boucle_debug($n, $incl, $debut); |
|
| 395 | - } |
|
| 396 | - } |
|
| 397 | - |
|
| 398 | - return [$nom, $boucle, $v[2] - 1 + $n - $debut]; |
|
| 399 | - } |
|
| 400 | - $debut += $y; |
|
| 401 | - } |
|
| 402 | - } |
|
| 403 | - |
|
| 404 | - return [$nom, $boucle, $n - $debut]; |
|
| 373 | + $id = $nom . $boucle; |
|
| 374 | + if (is_array($GLOBALS['debug_objets']['sequence'][$id])) { |
|
| 375 | + foreach ($GLOBALS['debug_objets']['sequence'][$id] as $v) { |
|
| 376 | + if (!preg_match('/^(.*)(<\?.*\?>)(.*)$/s', $v[0], $r)) { |
|
| 377 | + $y = substr_count($v[0], "\n"); |
|
| 378 | + } else { |
|
| 379 | + if ($v[1][0] == '#') { // balise dynamique |
|
| 380 | + $incl = $GLOBALS['debug_objets']['resultat'][$v[2]]; |
|
| 381 | + } else // inclusion |
|
| 382 | + { |
|
| 383 | + $incl = $GLOBALS['debug_objets']['squelette'][trouve_squelette_inclus($v[0])]; |
|
| 384 | + } |
|
| 385 | + $y = substr_count($incl, "\n") |
|
| 386 | + + substr_count($r[1], "\n") |
|
| 387 | + + substr_count($r[3], "\n"); |
|
| 388 | + } |
|
| 389 | + if ($n <= ($y + $debut)) { |
|
| 390 | + if ($v[1][0] == '?') { |
|
| 391 | + return trouve_boucle_debug($n, $nom, $debut, substr($v[1], 1)); |
|
| 392 | + } elseif ($v[1][0] == '!') { |
|
| 393 | + if ($incl = trouve_squelette_inclus($v[1])) { |
|
| 394 | + return trouve_boucle_debug($n, $incl, $debut); |
|
| 395 | + } |
|
| 396 | + } |
|
| 397 | + |
|
| 398 | + return [$nom, $boucle, $v[2] - 1 + $n - $debut]; |
|
| 399 | + } |
|
| 400 | + $debut += $y; |
|
| 401 | + } |
|
| 402 | + } |
|
| 403 | + |
|
| 404 | + return [$nom, $boucle, $n - $debut]; |
|
| 405 | 405 | } |
| 406 | 406 | |
| 407 | 407 | function trouve_squelette_inclus($script) { |
| 408 | 408 | |
| 409 | - preg_match('/include\(.(.*).php3?.\);/', $script, $reg); |
|
| 410 | - // si le script X.php n'est pas ecrire/public.php |
|
| 411 | - // on suppose qu'il prend le squelette X.html (pas sur, mais y a pas mieux) |
|
| 412 | - if ($reg[1] == 'ecrire/public') { // si c'est bien ecrire/public on cherche le param 'fond' |
|
| 413 | - if (!preg_match("/'fond' => '([^']*)'/", $script, $reg)) { // a defaut on cherche le param 'page' |
|
| 414 | - if (!preg_match("/'param' => '([^']*)'/", $script, $reg)) { |
|
| 415 | - $reg[1] = 'inconnu'; |
|
| 416 | - } |
|
| 417 | - } |
|
| 418 | - } |
|
| 419 | - $incl = ',' . $reg[1] . '[.]\w$,'; |
|
| 420 | - |
|
| 421 | - foreach ($GLOBALS['debug_objets']['sourcefile'] as $k => $v) { |
|
| 422 | - if (preg_match($incl, $v)) { |
|
| 423 | - return $k; |
|
| 424 | - } |
|
| 425 | - } |
|
| 426 | - |
|
| 427 | - return ''; |
|
| 409 | + preg_match('/include\(.(.*).php3?.\);/', $script, $reg); |
|
| 410 | + // si le script X.php n'est pas ecrire/public.php |
|
| 411 | + // on suppose qu'il prend le squelette X.html (pas sur, mais y a pas mieux) |
|
| 412 | + if ($reg[1] == 'ecrire/public') { // si c'est bien ecrire/public on cherche le param 'fond' |
|
| 413 | + if (!preg_match("/'fond' => '([^']*)'/", $script, $reg)) { // a defaut on cherche le param 'page' |
|
| 414 | + if (!preg_match("/'param' => '([^']*)'/", $script, $reg)) { |
|
| 415 | + $reg[1] = 'inconnu'; |
|
| 416 | + } |
|
| 417 | + } |
|
| 418 | + } |
|
| 419 | + $incl = ',' . $reg[1] . '[.]\w$,'; |
|
| 420 | + |
|
| 421 | + foreach ($GLOBALS['debug_objets']['sourcefile'] as $k => $v) { |
|
| 422 | + if (preg_match($incl, $v)) { |
|
| 423 | + return $k; |
|
| 424 | + } |
|
| 425 | + } |
|
| 426 | + |
|
| 427 | + return ''; |
|
| 428 | 428 | } |
| 429 | 429 | |
| 430 | 430 | function reference_boucle_debug($n, $nom, $self) { |
| 431 | - [$skel, $boucle, $ligne] = trouve_boucle_debug($n, $nom); |
|
| 432 | - |
|
| 433 | - if (!$boucle) { |
|
| 434 | - return !$ligne ? '' : |
|
| 435 | - (' (' . |
|
| 436 | - (($nom != $skel) ? _T('squelette_inclus_ligne') : |
|
| 437 | - _T('squelette_ligne')) . |
|
| 438 | - " <a href='$self&var_mode_objet=$skel&var_mode_affiche=squelette&var_mode_ligne=$ligne#L$ligne'>$ligne</a>)"); |
|
| 439 | - } else { |
|
| 440 | - $self .= "&var_mode_objet=$skel$boucle&var_mode_affiche=boucle"; |
|
| 441 | - |
|
| 442 | - return !$ligne ? " (boucle\n<a href='$self#$skel$boucle'>$boucle</a>)" : |
|
| 443 | - " (boucle $boucle ligne\n<a href='$self&var_mode_ligne=$ligne#L$ligne'>$ligne</a>)"; |
|
| 444 | - } |
|
| 431 | + [$skel, $boucle, $ligne] = trouve_boucle_debug($n, $nom); |
|
| 432 | + |
|
| 433 | + if (!$boucle) { |
|
| 434 | + return !$ligne ? '' : |
|
| 435 | + (' (' . |
|
| 436 | + (($nom != $skel) ? _T('squelette_inclus_ligne') : |
|
| 437 | + _T('squelette_ligne')) . |
|
| 438 | + " <a href='$self&var_mode_objet=$skel&var_mode_affiche=squelette&var_mode_ligne=$ligne#L$ligne'>$ligne</a>)"); |
|
| 439 | + } else { |
|
| 440 | + $self .= "&var_mode_objet=$skel$boucle&var_mode_affiche=boucle"; |
|
| 441 | + |
|
| 442 | + return !$ligne ? " (boucle\n<a href='$self#$skel$boucle'>$boucle</a>)" : |
|
| 443 | + " (boucle $boucle ligne\n<a href='$self&var_mode_ligne=$ligne#L$ligne'>$ligne</a>)"; |
|
| 444 | + } |
|
| 445 | 445 | } |
| 446 | 446 | |
| 447 | 447 | // affiche un texte avec numero de ligne et ancre. |
| 448 | 448 | |
| 449 | 449 | function ancre_texte($texte, $fautifs = [], $nocpt = false) { |
| 450 | 450 | |
| 451 | - $var_mode_ligne = _request('var_mode_ligne'); |
|
| 452 | - if ($var_mode_ligne) { |
|
| 453 | - $fautifs[] = [$var_mode_ligne]; |
|
| 454 | - } |
|
| 455 | - $res = ''; |
|
| 456 | - |
|
| 457 | - $s = highlight_string($texte, true); |
|
| 458 | - if (substr($s, 0, 6) == '<code>') { |
|
| 459 | - $s = substr($s, 6); |
|
| 460 | - $res = '<code>'; |
|
| 461 | - } |
|
| 462 | - |
|
| 463 | - $s = preg_replace( |
|
| 464 | - ',<(\w[^<>]*)>([^<]*)<br />([^<]*)</\1>,', |
|
| 465 | - '<\1>\2</\1><br />' . "\n" . '<\1>\3</\1>', |
|
| 466 | - $s |
|
| 467 | - ); |
|
| 468 | - |
|
| 469 | - |
|
| 470 | - $tableau = explode('<br />', $s); |
|
| 471 | - |
|
| 472 | - $format = "<span style='float:left;display:block;width:50px;height:1px'><a id='L%d' style='background-color: white; visibility: " . ($nocpt ? 'hidden' : 'visible') . ";%s' href='#T%s' title=\"%s\">%0" . strval(@strlen(count($tableau))) . "d</a></span> %s<br />\n"; |
|
| 473 | - |
|
| 474 | - $format10 = str_replace('white', 'lightgrey', $format); |
|
| 475 | - $formaterr = 'color: red;'; |
|
| 476 | - $i = 1; |
|
| 477 | - $flignes = []; |
|
| 478 | - $loc = [0, 0]; |
|
| 479 | - foreach ($fautifs as $lc) { |
|
| 480 | - if (is_array($lc)) { |
|
| 481 | - $l = array_shift($lc); |
|
| 482 | - $flignes[$l] = $lc; |
|
| 483 | - } else { |
|
| 484 | - $flignes[$lc] = $loc; |
|
| 485 | - } |
|
| 486 | - } |
|
| 487 | - |
|
| 488 | - $ancre = md5($texte); |
|
| 489 | - foreach ($tableau as $ligne) { |
|
| 490 | - if (isset($flignes[$i])) { |
|
| 491 | - $ligne = str_replace(' ', ' ', $ligne); |
|
| 492 | - $indexmesg = $flignes[$i][1]; |
|
| 493 | - $err = textebrut($flignes[$i][2]); |
|
| 494 | - // tentative de pointer sur la colonne fautive; |
|
| 495 | - // marche pas car highlight_string rajoute des entites. A revoir. |
|
| 496 | - // $m = $flignes[$i][0]; |
|
| 497 | - // $ligne = substr($ligne, 0, $m-1) . |
|
| 498 | - // sprintf($formaterr, substr($ligne,$m)); |
|
| 499 | - $bg = $formaterr; |
|
| 500 | - } else { |
|
| 501 | - $indexmesg = $ancre; |
|
| 502 | - $err = $bg = ''; |
|
| 503 | - } |
|
| 504 | - $res .= sprintf((($i % 10) ? $format : $format10), $i, $bg, $indexmesg, $err, $i, $ligne); |
|
| 505 | - $i++; |
|
| 506 | - } |
|
| 507 | - |
|
| 508 | - return "<div id='T$ancre'>" |
|
| 509 | - . '<div onclick="' |
|
| 510 | - . "jQuery(this).parent().find('a').toggle();" |
|
| 511 | - . '" title="' |
|
| 512 | - . _T('masquer_colonne') |
|
| 513 | - . '" style="cursor: pointer;">' |
|
| 514 | - . ($nocpt ? '' : _T('info_numero_abbreviation')) |
|
| 515 | - . '</div> |
|
| 451 | + $var_mode_ligne = _request('var_mode_ligne'); |
|
| 452 | + if ($var_mode_ligne) { |
|
| 453 | + $fautifs[] = [$var_mode_ligne]; |
|
| 454 | + } |
|
| 455 | + $res = ''; |
|
| 456 | + |
|
| 457 | + $s = highlight_string($texte, true); |
|
| 458 | + if (substr($s, 0, 6) == '<code>') { |
|
| 459 | + $s = substr($s, 6); |
|
| 460 | + $res = '<code>'; |
|
| 461 | + } |
|
| 462 | + |
|
| 463 | + $s = preg_replace( |
|
| 464 | + ',<(\w[^<>]*)>([^<]*)<br />([^<]*)</\1>,', |
|
| 465 | + '<\1>\2</\1><br />' . "\n" . '<\1>\3</\1>', |
|
| 466 | + $s |
|
| 467 | + ); |
|
| 468 | + |
|
| 469 | + |
|
| 470 | + $tableau = explode('<br />', $s); |
|
| 471 | + |
|
| 472 | + $format = "<span style='float:left;display:block;width:50px;height:1px'><a id='L%d' style='background-color: white; visibility: " . ($nocpt ? 'hidden' : 'visible') . ";%s' href='#T%s' title=\"%s\">%0" . strval(@strlen(count($tableau))) . "d</a></span> %s<br />\n"; |
|
| 473 | + |
|
| 474 | + $format10 = str_replace('white', 'lightgrey', $format); |
|
| 475 | + $formaterr = 'color: red;'; |
|
| 476 | + $i = 1; |
|
| 477 | + $flignes = []; |
|
| 478 | + $loc = [0, 0]; |
|
| 479 | + foreach ($fautifs as $lc) { |
|
| 480 | + if (is_array($lc)) { |
|
| 481 | + $l = array_shift($lc); |
|
| 482 | + $flignes[$l] = $lc; |
|
| 483 | + } else { |
|
| 484 | + $flignes[$lc] = $loc; |
|
| 485 | + } |
|
| 486 | + } |
|
| 487 | + |
|
| 488 | + $ancre = md5($texte); |
|
| 489 | + foreach ($tableau as $ligne) { |
|
| 490 | + if (isset($flignes[$i])) { |
|
| 491 | + $ligne = str_replace(' ', ' ', $ligne); |
|
| 492 | + $indexmesg = $flignes[$i][1]; |
|
| 493 | + $err = textebrut($flignes[$i][2]); |
|
| 494 | + // tentative de pointer sur la colonne fautive; |
|
| 495 | + // marche pas car highlight_string rajoute des entites. A revoir. |
|
| 496 | + // $m = $flignes[$i][0]; |
|
| 497 | + // $ligne = substr($ligne, 0, $m-1) . |
|
| 498 | + // sprintf($formaterr, substr($ligne,$m)); |
|
| 499 | + $bg = $formaterr; |
|
| 500 | + } else { |
|
| 501 | + $indexmesg = $ancre; |
|
| 502 | + $err = $bg = ''; |
|
| 503 | + } |
|
| 504 | + $res .= sprintf((($i % 10) ? $format : $format10), $i, $bg, $indexmesg, $err, $i, $ligne); |
|
| 505 | + $i++; |
|
| 506 | + } |
|
| 507 | + |
|
| 508 | + return "<div id='T$ancre'>" |
|
| 509 | + . '<div onclick="' |
|
| 510 | + . "jQuery(this).parent().find('a').toggle();" |
|
| 511 | + . '" title="' |
|
| 512 | + . _T('masquer_colonne') |
|
| 513 | + . '" style="cursor: pointer;">' |
|
| 514 | + . ($nocpt ? '' : _T('info_numero_abbreviation')) |
|
| 515 | + . '</div> |
|
| 516 | 516 | ' . $res . "</div>\n"; |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | 519 | // l'environnement graphique du debuggueur |
| 520 | 520 | |
| 521 | 521 | function debusquer_squelette($fonc, $mode, $self) { |
| 522 | - $legend = null; |
|
| 523 | - $texte = ''; |
|
| 524 | - |
|
| 525 | - if ($mode !== 'validation') { |
|
| 526 | - if (isset($GLOBALS['debug_objets']['sourcefile']) and $GLOBALS['debug_objets']['sourcefile']) { |
|
| 527 | - $res = "<div id='spip-boucles'>\n" |
|
| 528 | - . debusquer_navigation_squelettes($self) |
|
| 529 | - . '</div>'; |
|
| 530 | - } else { |
|
| 531 | - $res = ''; |
|
| 532 | - } |
|
| 533 | - if ($fonc) { |
|
| 534 | - $id = " id='$fonc'"; |
|
| 535 | - if (!empty($GLOBALS['debug_objets'][$mode][$fonc])) { |
|
| 536 | - [$legend, $texte, $res2] = debusquer_source($fonc, $mode); |
|
| 537 | - $texte .= $res2; |
|
| 538 | - } elseif (!empty($GLOBALS['debug_objets'][$mode][$fonc . 'tout'])) { |
|
| 539 | - $legend = _T('zbug_' . $mode); |
|
| 540 | - $texte = $GLOBALS['debug_objets'][$mode][$fonc . 'tout']; |
|
| 541 | - $texte = ancre_texte($texte, ['', '']); |
|
| 542 | - } |
|
| 543 | - } else { |
|
| 544 | - if (strlen(trim($res))) { |
|
| 545 | - return "<img src='" . chemin_image('debug-xx.svg') . "' alt='afficher-masquer le debug' id='spip-debug-toggle' onclick=\"var x = document.getElementById('spip-debug'); (x.style.display == '' ? x.style.display = 'none' : x.style.display = '');\" /><div id='spip-debug'>$res</div>"; |
|
| 546 | - } else { |
|
| 547 | - // cas de l'appel sur erreur: montre la page |
|
| 548 | - return $GLOBALS['debug_objets']['resultat']['tout'] ?? ''; |
|
| 549 | - } |
|
| 550 | - } |
|
| 551 | - } else { |
|
| 552 | - $valider = charger_fonction('valider', 'xml'); |
|
| 553 | - $val = $valider($GLOBALS['debug_objets']['validation'][$fonc . 'tout']); |
|
| 554 | - // Si erreur, signaler leur nombre dans le formulaire admin |
|
| 555 | - $GLOBALS['debug_objets']['validation'] = $val->err ? count($val->err) : ''; |
|
| 556 | - [$texte, $err] = emboite_texte($val, $fonc, $self); |
|
| 557 | - if ($err === false) { |
|
| 558 | - $err = _T('impossible'); |
|
| 559 | - } elseif ($err === true) { |
|
| 560 | - $err = _T('correcte'); |
|
| 561 | - } else { |
|
| 562 | - $err = ": $err"; |
|
| 563 | - } |
|
| 564 | - $legend = _T('validation') . ' ' . $err; |
|
| 565 | - $res = $id = ''; |
|
| 566 | - } |
|
| 567 | - |
|
| 568 | - return !trim($texte) ? '' : ( |
|
| 569 | - "<img src='" . chemin_image('debug-xx.svg') . "' alt='afficher-masquer le debug' id='spip-debug-toggle' onclick=\"var x = document.getElementById('spip-debug'); (x.style.display == '' ? x.style.display = 'none' : x.style.display = '');\" /><div id='spip-debug'>$res" |
|
| 570 | - . "<div id='debug_boucle'><fieldset$id><legend>" |
|
| 571 | - . "<a href='" . $self . '#f_' . substr($fonc, 0, 37) . "'> ↑ " |
|
| 572 | - . ($legend ?: $mode) |
|
| 573 | - . '</a></legend>' |
|
| 574 | - . $texte |
|
| 575 | - . '</fieldset></div>' |
|
| 576 | - . '</div>'); |
|
| 522 | + $legend = null; |
|
| 523 | + $texte = ''; |
|
| 524 | + |
|
| 525 | + if ($mode !== 'validation') { |
|
| 526 | + if (isset($GLOBALS['debug_objets']['sourcefile']) and $GLOBALS['debug_objets']['sourcefile']) { |
|
| 527 | + $res = "<div id='spip-boucles'>\n" |
|
| 528 | + . debusquer_navigation_squelettes($self) |
|
| 529 | + . '</div>'; |
|
| 530 | + } else { |
|
| 531 | + $res = ''; |
|
| 532 | + } |
|
| 533 | + if ($fonc) { |
|
| 534 | + $id = " id='$fonc'"; |
|
| 535 | + if (!empty($GLOBALS['debug_objets'][$mode][$fonc])) { |
|
| 536 | + [$legend, $texte, $res2] = debusquer_source($fonc, $mode); |
|
| 537 | + $texte .= $res2; |
|
| 538 | + } elseif (!empty($GLOBALS['debug_objets'][$mode][$fonc . 'tout'])) { |
|
| 539 | + $legend = _T('zbug_' . $mode); |
|
| 540 | + $texte = $GLOBALS['debug_objets'][$mode][$fonc . 'tout']; |
|
| 541 | + $texte = ancre_texte($texte, ['', '']); |
|
| 542 | + } |
|
| 543 | + } else { |
|
| 544 | + if (strlen(trim($res))) { |
|
| 545 | + return "<img src='" . chemin_image('debug-xx.svg') . "' alt='afficher-masquer le debug' id='spip-debug-toggle' onclick=\"var x = document.getElementById('spip-debug'); (x.style.display == '' ? x.style.display = 'none' : x.style.display = '');\" /><div id='spip-debug'>$res</div>"; |
|
| 546 | + } else { |
|
| 547 | + // cas de l'appel sur erreur: montre la page |
|
| 548 | + return $GLOBALS['debug_objets']['resultat']['tout'] ?? ''; |
|
| 549 | + } |
|
| 550 | + } |
|
| 551 | + } else { |
|
| 552 | + $valider = charger_fonction('valider', 'xml'); |
|
| 553 | + $val = $valider($GLOBALS['debug_objets']['validation'][$fonc . 'tout']); |
|
| 554 | + // Si erreur, signaler leur nombre dans le formulaire admin |
|
| 555 | + $GLOBALS['debug_objets']['validation'] = $val->err ? count($val->err) : ''; |
|
| 556 | + [$texte, $err] = emboite_texte($val, $fonc, $self); |
|
| 557 | + if ($err === false) { |
|
| 558 | + $err = _T('impossible'); |
|
| 559 | + } elseif ($err === true) { |
|
| 560 | + $err = _T('correcte'); |
|
| 561 | + } else { |
|
| 562 | + $err = ": $err"; |
|
| 563 | + } |
|
| 564 | + $legend = _T('validation') . ' ' . $err; |
|
| 565 | + $res = $id = ''; |
|
| 566 | + } |
|
| 567 | + |
|
| 568 | + return !trim($texte) ? '' : ( |
|
| 569 | + "<img src='" . chemin_image('debug-xx.svg') . "' alt='afficher-masquer le debug' id='spip-debug-toggle' onclick=\"var x = document.getElementById('spip-debug'); (x.style.display == '' ? x.style.display = 'none' : x.style.display = '');\" /><div id='spip-debug'>$res" |
|
| 570 | + . "<div id='debug_boucle'><fieldset$id><legend>" |
|
| 571 | + . "<a href='" . $self . '#f_' . substr($fonc, 0, 37) . "'> ↑ " |
|
| 572 | + . ($legend ?: $mode) |
|
| 573 | + . '</a></legend>' |
|
| 574 | + . $texte |
|
| 575 | + . '</fieldset></div>' |
|
| 576 | + . '</div>'); |
|
| 577 | 577 | } |
| 578 | 578 | |
| 579 | 579 | |
| 580 | 580 | function emboite_texte($res, $fonc = '', $self = '') { |
| 581 | - $errs = $res->err; |
|
| 582 | - $texte = $res->entete . ($errs ? '' : $res->page); |
|
| 583 | - |
|
| 584 | - if (!$texte and !$errs) { |
|
| 585 | - return [ancre_texte('', ['', '']), false]; |
|
| 586 | - } |
|
| 587 | - if (!$errs) { |
|
| 588 | - return [ancre_texte($texte, ['', '']), true]; |
|
| 589 | - } |
|
| 590 | - |
|
| 591 | - if (!isset($GLOBALS['debug_objets'])) { |
|
| 592 | - $colors = ['#e0e0f0', '#f8f8ff']; |
|
| 593 | - $encore = count_occ($errs); |
|
| 594 | - $encore2 = []; |
|
| 595 | - $fautifs = []; |
|
| 596 | - |
|
| 597 | - $err = '<tr><th>' |
|
| 598 | - . _T('numero') |
|
| 599 | - . '</th><th>' |
|
| 600 | - . _T('occurence') |
|
| 601 | - . '</th><th>' |
|
| 602 | - . _T('ligne') |
|
| 603 | - . '</th><th>' |
|
| 604 | - . _T('colonne') |
|
| 605 | - . '</th><th>' |
|
| 606 | - . _T('erreur') |
|
| 607 | - . '</th></tr>'; |
|
| 608 | - |
|
| 609 | - $i = 0; |
|
| 610 | - $style = "style='text-align: right; padding-right: 5px'"; |
|
| 611 | - foreach ($errs as $r) { |
|
| 612 | - $i++; |
|
| 613 | - [$msg, $ligne, $col] = $r; |
|
| 614 | - #spip_log("$r = list($msg, $ligne, $col"); |
|
| 615 | - if (isset($encore2[$msg])) { |
|
| 616 | - $ref = ++$encore2[$msg]; |
|
| 617 | - } else { |
|
| 618 | - $encore2[$msg] = $ref = 1; |
|
| 619 | - } |
|
| 620 | - $err .= "<tr style='background-color: " |
|
| 621 | - . $colors[$i % 2] |
|
| 622 | - . "'><td $style><a href='#debut_err'>" |
|
| 623 | - . $i |
|
| 624 | - . "</a></td><td $style>" |
|
| 625 | - . "$ref/$encore[$msg]</td>" |
|
| 626 | - . "<td $style><a href='#L" |
|
| 627 | - . $ligne |
|
| 628 | - . "' id='T$i'>" |
|
| 629 | - . $ligne |
|
| 630 | - . "</a></td><td $style>" |
|
| 631 | - . $col |
|
| 632 | - . "</td><td>$msg</td></tr>\n"; |
|
| 633 | - $fautifs[] = [$ligne, $col, $i, $msg]; |
|
| 634 | - } |
|
| 635 | - $err = "<h2 style='text-align: center'>" |
|
| 636 | - . $i |
|
| 637 | - . "<a href='#fin_err'>" |
|
| 638 | - . ' ' . _T('erreur_texte') |
|
| 639 | - . "</a></h2><table id='debut_err' style='width: 100%'>" |
|
| 640 | - . $err |
|
| 641 | - . " </table><a id='fin_err'></a>"; |
|
| 642 | - |
|
| 643 | - return [ancre_texte($texte, $fautifs), $err]; |
|
| 644 | - } else { |
|
| 645 | - [$msg, $fermant, $ouvrant] = $errs[0]; |
|
| 646 | - $rf = reference_boucle_debug($fermant, $fonc, $self); |
|
| 647 | - $ro = reference_boucle_debug($ouvrant, $fonc, $self); |
|
| 648 | - $err = $msg . |
|
| 649 | - "<a href='#L" . $fermant . "'>$fermant</a>$rf<br />" . |
|
| 650 | - "<a href='#L" . $ouvrant . "'>$ouvrant</a>$ro"; |
|
| 651 | - |
|
| 652 | - return [ancre_texte($texte, [[$ouvrant], [$fermant]]), $err]; |
|
| 653 | - } |
|
| 581 | + $errs = $res->err; |
|
| 582 | + $texte = $res->entete . ($errs ? '' : $res->page); |
|
| 583 | + |
|
| 584 | + if (!$texte and !$errs) { |
|
| 585 | + return [ancre_texte('', ['', '']), false]; |
|
| 586 | + } |
|
| 587 | + if (!$errs) { |
|
| 588 | + return [ancre_texte($texte, ['', '']), true]; |
|
| 589 | + } |
|
| 590 | + |
|
| 591 | + if (!isset($GLOBALS['debug_objets'])) { |
|
| 592 | + $colors = ['#e0e0f0', '#f8f8ff']; |
|
| 593 | + $encore = count_occ($errs); |
|
| 594 | + $encore2 = []; |
|
| 595 | + $fautifs = []; |
|
| 596 | + |
|
| 597 | + $err = '<tr><th>' |
|
| 598 | + . _T('numero') |
|
| 599 | + . '</th><th>' |
|
| 600 | + . _T('occurence') |
|
| 601 | + . '</th><th>' |
|
| 602 | + . _T('ligne') |
|
| 603 | + . '</th><th>' |
|
| 604 | + . _T('colonne') |
|
| 605 | + . '</th><th>' |
|
| 606 | + . _T('erreur') |
|
| 607 | + . '</th></tr>'; |
|
| 608 | + |
|
| 609 | + $i = 0; |
|
| 610 | + $style = "style='text-align: right; padding-right: 5px'"; |
|
| 611 | + foreach ($errs as $r) { |
|
| 612 | + $i++; |
|
| 613 | + [$msg, $ligne, $col] = $r; |
|
| 614 | + #spip_log("$r = list($msg, $ligne, $col"); |
|
| 615 | + if (isset($encore2[$msg])) { |
|
| 616 | + $ref = ++$encore2[$msg]; |
|
| 617 | + } else { |
|
| 618 | + $encore2[$msg] = $ref = 1; |
|
| 619 | + } |
|
| 620 | + $err .= "<tr style='background-color: " |
|
| 621 | + . $colors[$i % 2] |
|
| 622 | + . "'><td $style><a href='#debut_err'>" |
|
| 623 | + . $i |
|
| 624 | + . "</a></td><td $style>" |
|
| 625 | + . "$ref/$encore[$msg]</td>" |
|
| 626 | + . "<td $style><a href='#L" |
|
| 627 | + . $ligne |
|
| 628 | + . "' id='T$i'>" |
|
| 629 | + . $ligne |
|
| 630 | + . "</a></td><td $style>" |
|
| 631 | + . $col |
|
| 632 | + . "</td><td>$msg</td></tr>\n"; |
|
| 633 | + $fautifs[] = [$ligne, $col, $i, $msg]; |
|
| 634 | + } |
|
| 635 | + $err = "<h2 style='text-align: center'>" |
|
| 636 | + . $i |
|
| 637 | + . "<a href='#fin_err'>" |
|
| 638 | + . ' ' . _T('erreur_texte') |
|
| 639 | + . "</a></h2><table id='debut_err' style='width: 100%'>" |
|
| 640 | + . $err |
|
| 641 | + . " </table><a id='fin_err'></a>"; |
|
| 642 | + |
|
| 643 | + return [ancre_texte($texte, $fautifs), $err]; |
|
| 644 | + } else { |
|
| 645 | + [$msg, $fermant, $ouvrant] = $errs[0]; |
|
| 646 | + $rf = reference_boucle_debug($fermant, $fonc, $self); |
|
| 647 | + $ro = reference_boucle_debug($ouvrant, $fonc, $self); |
|
| 648 | + $err = $msg . |
|
| 649 | + "<a href='#L" . $fermant . "'>$fermant</a>$rf<br />" . |
|
| 650 | + "<a href='#L" . $ouvrant . "'>$ouvrant</a>$ro"; |
|
| 651 | + |
|
| 652 | + return [ancre_texte($texte, [[$ouvrant], [$fermant]]), $err]; |
|
| 653 | + } |
|
| 654 | 654 | } |
| 655 | 655 | |
| 656 | 656 | function count_occ($regs) { |
| 657 | - $encore = []; |
|
| 658 | - foreach ($regs as $r) { |
|
| 659 | - if (isset($encore[$r[0]])) { |
|
| 660 | - $encore[$r[0]]++; |
|
| 661 | - } else { |
|
| 662 | - $encore[$r[0]] = 1; |
|
| 663 | - } |
|
| 664 | - } |
|
| 665 | - |
|
| 666 | - return $encore; |
|
| 657 | + $encore = []; |
|
| 658 | + foreach ($regs as $r) { |
|
| 659 | + if (isset($encore[$r[0]])) { |
|
| 660 | + $encore[$r[0]]++; |
|
| 661 | + } else { |
|
| 662 | + $encore[$r[0]] = 1; |
|
| 663 | + } |
|
| 664 | + } |
|
| 665 | + |
|
| 666 | + return $encore; |
|
| 667 | 667 | } |
| 668 | 668 | |
| 669 | 669 | function debusquer_navigation_squelettes($self) { |
| 670 | 670 | |
| 671 | - $res = ''; |
|
| 672 | - $boucles = !empty($GLOBALS['debug_objets']['boucle']) ? $GLOBALS['debug_objets']['boucle'] : ''; |
|
| 673 | - $contexte = $GLOBALS['debug_objets']['contexte']; |
|
| 674 | - $t_skel = _T('squelette'); |
|
| 675 | - foreach ($GLOBALS['debug_objets']['sourcefile'] as $nom => $sourcefile) { |
|
| 676 | - $self2 = parametre_url($self, 'var_mode_objet', $nom); |
|
| 677 | - $nav = !$boucles ? '' : debusquer_navigation_boucles($boucles, $nom, $self, $sourcefile); |
|
| 678 | - $temps = !isset($GLOBALS['debug_objets']['profile'][$sourcefile]) ? '' : _T( |
|
| 679 | - 'zbug_profile', |
|
| 680 | - ['time' => $GLOBALS['debug_objets']['profile'][$sourcefile]] |
|
| 681 | - ); |
|
| 682 | - |
|
| 683 | - $res .= "<fieldset id='f_" . $nom . "'><legend>" |
|
| 684 | - . $t_skel |
|
| 685 | - . ' ' |
|
| 686 | - . $sourcefile |
|
| 687 | - . " :\n<a href='$self2&var_mode_affiche=squelette#f_$nom'>" |
|
| 688 | - . $t_skel |
|
| 689 | - . "</a>\n<a href='$self2&var_mode_affiche=resultat#f_$nom'>" |
|
| 690 | - . _T('zbug_resultat') |
|
| 691 | - . "</a>\n<a href='$self2&var_mode_affiche=code#f_$nom'>" |
|
| 692 | - . _T('zbug_code') |
|
| 693 | - . "</a>\n<a href='" |
|
| 694 | - . str_replace('var_mode=debug', 'var_profile=1&var_mode=recalcul', $self) |
|
| 695 | - . "'>" |
|
| 696 | - . _T('zbug_calcul') |
|
| 697 | - . '</a></legend>' |
|
| 698 | - . (!$temps ? '' : ("\n<span style='display:block;float:" . $GLOBALS['spip_lang_right'] . "'>$temps</span><br />")) |
|
| 699 | - . debusquer_contexte($contexte[$sourcefile]) |
|
| 700 | - . (!$nav ? '' : ("<table width='100%'>\n$nav</table>\n")) |
|
| 701 | - . "</fieldset>\n"; |
|
| 702 | - } |
|
| 703 | - |
|
| 704 | - return $res; |
|
| 671 | + $res = ''; |
|
| 672 | + $boucles = !empty($GLOBALS['debug_objets']['boucle']) ? $GLOBALS['debug_objets']['boucle'] : ''; |
|
| 673 | + $contexte = $GLOBALS['debug_objets']['contexte']; |
|
| 674 | + $t_skel = _T('squelette'); |
|
| 675 | + foreach ($GLOBALS['debug_objets']['sourcefile'] as $nom => $sourcefile) { |
|
| 676 | + $self2 = parametre_url($self, 'var_mode_objet', $nom); |
|
| 677 | + $nav = !$boucles ? '' : debusquer_navigation_boucles($boucles, $nom, $self, $sourcefile); |
|
| 678 | + $temps = !isset($GLOBALS['debug_objets']['profile'][$sourcefile]) ? '' : _T( |
|
| 679 | + 'zbug_profile', |
|
| 680 | + ['time' => $GLOBALS['debug_objets']['profile'][$sourcefile]] |
|
| 681 | + ); |
|
| 682 | + |
|
| 683 | + $res .= "<fieldset id='f_" . $nom . "'><legend>" |
|
| 684 | + . $t_skel |
|
| 685 | + . ' ' |
|
| 686 | + . $sourcefile |
|
| 687 | + . " :\n<a href='$self2&var_mode_affiche=squelette#f_$nom'>" |
|
| 688 | + . $t_skel |
|
| 689 | + . "</a>\n<a href='$self2&var_mode_affiche=resultat#f_$nom'>" |
|
| 690 | + . _T('zbug_resultat') |
|
| 691 | + . "</a>\n<a href='$self2&var_mode_affiche=code#f_$nom'>" |
|
| 692 | + . _T('zbug_code') |
|
| 693 | + . "</a>\n<a href='" |
|
| 694 | + . str_replace('var_mode=debug', 'var_profile=1&var_mode=recalcul', $self) |
|
| 695 | + . "'>" |
|
| 696 | + . _T('zbug_calcul') |
|
| 697 | + . '</a></legend>' |
|
| 698 | + . (!$temps ? '' : ("\n<span style='display:block;float:" . $GLOBALS['spip_lang_right'] . "'>$temps</span><br />")) |
|
| 699 | + . debusquer_contexte($contexte[$sourcefile]) |
|
| 700 | + . (!$nav ? '' : ("<table width='100%'>\n$nav</table>\n")) |
|
| 701 | + . "</fieldset>\n"; |
|
| 702 | + } |
|
| 703 | + |
|
| 704 | + return $res; |
|
| 705 | 705 | } |
| 706 | 706 | |
| 707 | 707 | function debusquer_navigation_boucles($boucles, $nom_skel, $self, $nom_source) { |
| 708 | - $i = 0; |
|
| 709 | - $res = ''; |
|
| 710 | - $var_mode_objet = _request('var_mode_objet'); |
|
| 711 | - $gram = preg_match('/[.](\w+)$/', $nom_source, $r) ? $r[1] : ''; |
|
| 712 | - |
|
| 713 | - foreach ($boucles as $objet => $boucle) { |
|
| 714 | - if (substr($objet, 0, strlen($nom_skel)) == $nom_skel) { |
|
| 715 | - $i++; |
|
| 716 | - $nom = $boucle->id_boucle; |
|
| 717 | - $req = $boucle->type_requete; |
|
| 718 | - $crit = public_decompiler($boucle, $gram, 0, 'criteres'); |
|
| 719 | - $self2 = $self . '&var_mode_objet=' . $objet; |
|
| 720 | - |
|
| 721 | - $res .= "\n<tr style='background-color: " . |
|
| 722 | - ($i % 2 ? '#e0e0f0' : '#f8f8ff') . |
|
| 723 | - "'><td align='right'>$i</td><td>\n" . |
|
| 724 | - "<a class='debug_link_boucle' href='" . |
|
| 725 | - $self2 . |
|
| 726 | - "&var_mode_affiche=boucle#f_$nom_skel'>" . |
|
| 727 | - _T('zbug_boucle') . |
|
| 728 | - "</a></td><td>\n<a class='debug_link_boucle' href='" . |
|
| 729 | - $self2 . |
|
| 730 | - "&var_mode_affiche=resultat#f_$nom_skel'>" . |
|
| 731 | - _T('zbug_resultat') . |
|
| 732 | - "</a></td><td>\n<a class='debug_link_resultat' href='" . |
|
| 733 | - $self2 . |
|
| 734 | - "&var_mode_affiche=code#f_$nom_skel'>" . |
|
| 735 | - _T('zbug_code') . |
|
| 736 | - "</a></td><td>\n<a class='debug_link_resultat' href='" . |
|
| 737 | - str_replace('var_mode=', 'var_profile=', $self2) . |
|
| 738 | - "'>" . |
|
| 739 | - _T('zbug_calcul') . |
|
| 740 | - "</a></td><td>\n" . |
|
| 741 | - (($var_mode_objet == $objet) ? "<b>$nom</b>" : $nom) . |
|
| 742 | - "</td><td>\n" . |
|
| 743 | - $req . |
|
| 744 | - "</td><td>\n" . |
|
| 745 | - spip_htmlspecialchars($crit) . |
|
| 746 | - '</td></tr>'; |
|
| 747 | - } |
|
| 748 | - } |
|
| 749 | - |
|
| 750 | - return $res; |
|
| 708 | + $i = 0; |
|
| 709 | + $res = ''; |
|
| 710 | + $var_mode_objet = _request('var_mode_objet'); |
|
| 711 | + $gram = preg_match('/[.](\w+)$/', $nom_source, $r) ? $r[1] : ''; |
|
| 712 | + |
|
| 713 | + foreach ($boucles as $objet => $boucle) { |
|
| 714 | + if (substr($objet, 0, strlen($nom_skel)) == $nom_skel) { |
|
| 715 | + $i++; |
|
| 716 | + $nom = $boucle->id_boucle; |
|
| 717 | + $req = $boucle->type_requete; |
|
| 718 | + $crit = public_decompiler($boucle, $gram, 0, 'criteres'); |
|
| 719 | + $self2 = $self . '&var_mode_objet=' . $objet; |
|
| 720 | + |
|
| 721 | + $res .= "\n<tr style='background-color: " . |
|
| 722 | + ($i % 2 ? '#e0e0f0' : '#f8f8ff') . |
|
| 723 | + "'><td align='right'>$i</td><td>\n" . |
|
| 724 | + "<a class='debug_link_boucle' href='" . |
|
| 725 | + $self2 . |
|
| 726 | + "&var_mode_affiche=boucle#f_$nom_skel'>" . |
|
| 727 | + _T('zbug_boucle') . |
|
| 728 | + "</a></td><td>\n<a class='debug_link_boucle' href='" . |
|
| 729 | + $self2 . |
|
| 730 | + "&var_mode_affiche=resultat#f_$nom_skel'>" . |
|
| 731 | + _T('zbug_resultat') . |
|
| 732 | + "</a></td><td>\n<a class='debug_link_resultat' href='" . |
|
| 733 | + $self2 . |
|
| 734 | + "&var_mode_affiche=code#f_$nom_skel'>" . |
|
| 735 | + _T('zbug_code') . |
|
| 736 | + "</a></td><td>\n<a class='debug_link_resultat' href='" . |
|
| 737 | + str_replace('var_mode=', 'var_profile=', $self2) . |
|
| 738 | + "'>" . |
|
| 739 | + _T('zbug_calcul') . |
|
| 740 | + "</a></td><td>\n" . |
|
| 741 | + (($var_mode_objet == $objet) ? "<b>$nom</b>" : $nom) . |
|
| 742 | + "</td><td>\n" . |
|
| 743 | + $req . |
|
| 744 | + "</td><td>\n" . |
|
| 745 | + spip_htmlspecialchars($crit) . |
|
| 746 | + '</td></tr>'; |
|
| 747 | + } |
|
| 748 | + } |
|
| 749 | + |
|
| 750 | + return $res; |
|
| 751 | 751 | } |
| 752 | 752 | |
| 753 | 753 | function debusquer_source($objet, $affiche) { |
| 754 | - $quoi = $GLOBALS['debug_objets'][$affiche][$objet]; |
|
| 755 | - if (!empty($GLOBALS['debug_objets']['boucle'][$objet]->id_boucle)) { |
|
| 756 | - $nom = $GLOBALS['debug_objets']['boucle'][$objet]->id_boucle; |
|
| 757 | - } else { |
|
| 758 | - $nom = $GLOBALS['debug_objets']['sourcefile'][$objet]; |
|
| 759 | - } |
|
| 760 | - $res2 = ''; |
|
| 761 | - |
|
| 762 | - if ($affiche == 'resultat') { |
|
| 763 | - $legend = $nom; |
|
| 764 | - $req = $GLOBALS['debug_objets']['requete'][$objet]; |
|
| 765 | - if (function_exists('_mysql_traite_query')) { |
|
| 766 | - $c = strtolower(_request('connect') ?? ''); |
|
| 767 | - $c = $GLOBALS['connexions'][$c ?: 0]['prefixe']; |
|
| 768 | - $req = _mysql_traite_query($req, '', $c); |
|
| 769 | - } |
|
| 770 | - // permettre le copier/coller facile |
|
| 771 | - // $res = ancre_texte($req, array(), true); |
|
| 772 | - $res = "<div id='T" . md5($req) . "'>\n<pre>\n" . $req . "</pre>\n</div>\n"; |
|
| 773 | - // formatage et affichage des resultats bruts de la requete |
|
| 774 | - $ress_req = spip_query($req); |
|
| 775 | - $brut_sql = ''; |
|
| 776 | - $num = 1; |
|
| 777 | - // eviter l'affichage de milliers de lignes |
|
| 778 | - // personnalisation possible dans mes_options |
|
| 779 | - $max_aff = defined('_MAX_DEBUG_AFF') ? _MAX_DEBUG_AFF : 50; |
|
| 780 | - while ($retours_sql = sql_fetch($ress_req)) { |
|
| 781 | - if ($num <= $max_aff) { |
|
| 782 | - $brut_sql .= '<h3>' . ($num == 1 ? $num . ' sur ' . sql_count($ress_req) : $num) . '</h3>'; |
|
| 783 | - $brut_sql .= '<p>'; |
|
| 784 | - foreach ($retours_sql as $key => $val) { |
|
| 785 | - $brut_sql .= '<strong>' . $key . '</strong> => ' . spip_htmlspecialchars(couper($val, 150)) . "<br />\n"; |
|
| 786 | - } |
|
| 787 | - $brut_sql .= '</p>'; |
|
| 788 | - } |
|
| 789 | - $num++; |
|
| 790 | - } |
|
| 791 | - $res2 = interdire_scripts($brut_sql); |
|
| 792 | - foreach ($quoi as $view) { |
|
| 793 | - // ne pas afficher les $contexte_inclus |
|
| 794 | - $view = preg_replace(',<\?php.+\?[>],Uims', '', $view); |
|
| 795 | - if ($view) { |
|
| 796 | - $res2 .= "\n<br /><fieldset>" . interdire_scripts($view) . '</fieldset>'; |
|
| 797 | - } |
|
| 798 | - } |
|
| 799 | - } elseif ($affiche == 'code') { |
|
| 800 | - $legend = $nom; |
|
| 801 | - $res = ancre_texte('<' . "?php\n" . $quoi . "\n?" . '>'); |
|
| 802 | - } elseif ($affiche == 'boucle') { |
|
| 803 | - $legend = _T('zbug_boucle') . ' ' . $nom; |
|
| 804 | - // Le compilateur prefixe le nom des boucles par l'extension du fichier source. |
|
| 805 | - $gram = preg_match('/^([^_]+)_/', $objet, $r) ? $r[1] : ''; |
|
| 806 | - $res = ancre_texte(public_decompiler($quoi, $gram, 0, 'boucle')); |
|
| 807 | - } elseif ($affiche == 'squelette') { |
|
| 808 | - $legend = $GLOBALS['debug_objets']['sourcefile'][$objet]; |
|
| 809 | - $res = ancre_texte($GLOBALS['debug_objets']['squelette'][$objet]); |
|
| 810 | - } |
|
| 811 | - |
|
| 812 | - return [$legend, $res, $res2]; |
|
| 754 | + $quoi = $GLOBALS['debug_objets'][$affiche][$objet]; |
|
| 755 | + if (!empty($GLOBALS['debug_objets']['boucle'][$objet]->id_boucle)) { |
|
| 756 | + $nom = $GLOBALS['debug_objets']['boucle'][$objet]->id_boucle; |
|
| 757 | + } else { |
|
| 758 | + $nom = $GLOBALS['debug_objets']['sourcefile'][$objet]; |
|
| 759 | + } |
|
| 760 | + $res2 = ''; |
|
| 761 | + |
|
| 762 | + if ($affiche == 'resultat') { |
|
| 763 | + $legend = $nom; |
|
| 764 | + $req = $GLOBALS['debug_objets']['requete'][$objet]; |
|
| 765 | + if (function_exists('_mysql_traite_query')) { |
|
| 766 | + $c = strtolower(_request('connect') ?? ''); |
|
| 767 | + $c = $GLOBALS['connexions'][$c ?: 0]['prefixe']; |
|
| 768 | + $req = _mysql_traite_query($req, '', $c); |
|
| 769 | + } |
|
| 770 | + // permettre le copier/coller facile |
|
| 771 | + // $res = ancre_texte($req, array(), true); |
|
| 772 | + $res = "<div id='T" . md5($req) . "'>\n<pre>\n" . $req . "</pre>\n</div>\n"; |
|
| 773 | + // formatage et affichage des resultats bruts de la requete |
|
| 774 | + $ress_req = spip_query($req); |
|
| 775 | + $brut_sql = ''; |
|
| 776 | + $num = 1; |
|
| 777 | + // eviter l'affichage de milliers de lignes |
|
| 778 | + // personnalisation possible dans mes_options |
|
| 779 | + $max_aff = defined('_MAX_DEBUG_AFF') ? _MAX_DEBUG_AFF : 50; |
|
| 780 | + while ($retours_sql = sql_fetch($ress_req)) { |
|
| 781 | + if ($num <= $max_aff) { |
|
| 782 | + $brut_sql .= '<h3>' . ($num == 1 ? $num . ' sur ' . sql_count($ress_req) : $num) . '</h3>'; |
|
| 783 | + $brut_sql .= '<p>'; |
|
| 784 | + foreach ($retours_sql as $key => $val) { |
|
| 785 | + $brut_sql .= '<strong>' . $key . '</strong> => ' . spip_htmlspecialchars(couper($val, 150)) . "<br />\n"; |
|
| 786 | + } |
|
| 787 | + $brut_sql .= '</p>'; |
|
| 788 | + } |
|
| 789 | + $num++; |
|
| 790 | + } |
|
| 791 | + $res2 = interdire_scripts($brut_sql); |
|
| 792 | + foreach ($quoi as $view) { |
|
| 793 | + // ne pas afficher les $contexte_inclus |
|
| 794 | + $view = preg_replace(',<\?php.+\?[>],Uims', '', $view); |
|
| 795 | + if ($view) { |
|
| 796 | + $res2 .= "\n<br /><fieldset>" . interdire_scripts($view) . '</fieldset>'; |
|
| 797 | + } |
|
| 798 | + } |
|
| 799 | + } elseif ($affiche == 'code') { |
|
| 800 | + $legend = $nom; |
|
| 801 | + $res = ancre_texte('<' . "?php\n" . $quoi . "\n?" . '>'); |
|
| 802 | + } elseif ($affiche == 'boucle') { |
|
| 803 | + $legend = _T('zbug_boucle') . ' ' . $nom; |
|
| 804 | + // Le compilateur prefixe le nom des boucles par l'extension du fichier source. |
|
| 805 | + $gram = preg_match('/^([^_]+)_/', $objet, $r) ? $r[1] : ''; |
|
| 806 | + $res = ancre_texte(public_decompiler($quoi, $gram, 0, 'boucle')); |
|
| 807 | + } elseif ($affiche == 'squelette') { |
|
| 808 | + $legend = $GLOBALS['debug_objets']['sourcefile'][$objet]; |
|
| 809 | + $res = ancre_texte($GLOBALS['debug_objets']['squelette'][$objet]); |
|
| 810 | + } |
|
| 811 | + |
|
| 812 | + return [$legend, $res, $res2]; |
|
| 813 | 813 | } |
| 814 | 814 | |
| 815 | 815 | function debusquer_entete($titre, $corps) { |
| 816 | 816 | |
| 817 | - include_spip('balise/formulaire_admin'); |
|
| 818 | - include_spip('public/assembler'); // pour inclure_balise_dynamique |
|
| 819 | - include_spip('inc/texte'); // pour corriger_typo |
|
| 820 | - |
|
| 821 | - return _DOCTYPE_ECRIRE . |
|
| 822 | - html_lang_attributes() . |
|
| 823 | - "<head>\n<title>" . |
|
| 824 | - ('SPIP ' . $GLOBALS['spip_version_affichee'] . ' ' . |
|
| 825 | - _T('admin_debug') . ' ' . $titre . ' (' . |
|
| 826 | - supprimer_tags(corriger_typo($GLOBALS['meta']['nom_site']))) . |
|
| 827 | - ")</title>\n" . |
|
| 828 | - "<meta http-equiv='Content-Type' content='text/html" . |
|
| 829 | - (($c = $GLOBALS['meta']['charset']) ? "; charset=$c" : '') . |
|
| 830 | - "' />\n" . |
|
| 831 | - http_script('', 'jquery.js') |
|
| 832 | - . "<link rel='stylesheet' href='" . url_absolue(find_in_path('spip_admin.css')) |
|
| 833 | - . "' type='text/css' />" . |
|
| 834 | - "</head>\n" . |
|
| 835 | - "<body style='margin:0 10px;'>\n" . |
|
| 836 | - "<div id='spip-debug-header'>" . |
|
| 837 | - $corps . |
|
| 838 | - inclure_balise_dynamique(balise_FORMULAIRE_ADMIN_dyn('spip-admin-float', $GLOBALS['debug_objets']), false) . |
|
| 839 | - '</div></body></html>'; |
|
| 817 | + include_spip('balise/formulaire_admin'); |
|
| 818 | + include_spip('public/assembler'); // pour inclure_balise_dynamique |
|
| 819 | + include_spip('inc/texte'); // pour corriger_typo |
|
| 820 | + |
|
| 821 | + return _DOCTYPE_ECRIRE . |
|
| 822 | + html_lang_attributes() . |
|
| 823 | + "<head>\n<title>" . |
|
| 824 | + ('SPIP ' . $GLOBALS['spip_version_affichee'] . ' ' . |
|
| 825 | + _T('admin_debug') . ' ' . $titre . ' (' . |
|
| 826 | + supprimer_tags(corriger_typo($GLOBALS['meta']['nom_site']))) . |
|
| 827 | + ")</title>\n" . |
|
| 828 | + "<meta http-equiv='Content-Type' content='text/html" . |
|
| 829 | + (($c = $GLOBALS['meta']['charset']) ? "; charset=$c" : '') . |
|
| 830 | + "' />\n" . |
|
| 831 | + http_script('', 'jquery.js') |
|
| 832 | + . "<link rel='stylesheet' href='" . url_absolue(find_in_path('spip_admin.css')) |
|
| 833 | + . "' type='text/css' />" . |
|
| 834 | + "</head>\n" . |
|
| 835 | + "<body style='margin:0 10px;'>\n" . |
|
| 836 | + "<div id='spip-debug-header'>" . |
|
| 837 | + $corps . |
|
| 838 | + inclure_balise_dynamique(balise_FORMULAIRE_ADMIN_dyn('spip-admin-float', $GLOBALS['debug_objets']), false) . |
|
| 839 | + '</div></body></html>'; |
|
| 840 | 840 | } |
@@ -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 | /** |
@@ -43,12 +43,12 @@ discard block |
||
| 43 | 43 | **/ |
| 44 | 44 | function critere_racine_dist($idb, &$boucles, $crit) { |
| 45 | 45 | |
| 46 | - $not = $crit->not; |
|
| 47 | - $boucle = &$boucles[$idb]; |
|
| 48 | - $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent'; |
|
| 46 | + $not = $crit->not; |
|
| 47 | + $boucle = &$boucles[$idb]; |
|
| 48 | + $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent'; |
|
| 49 | 49 | |
| 50 | - $c = ["'='", "'$boucle->id_table." . "$id_parent'", 0]; |
|
| 51 | - $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c); |
|
| 50 | + $c = ["'='", "'$boucle->id_table." . "$id_parent'", 0]; |
|
| 51 | + $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c); |
|
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | |
@@ -65,15 +65,15 @@ discard block |
||
| 65 | 65 | * @return void |
| 66 | 66 | **/ |
| 67 | 67 | function critere_exclus_dist($idb, &$boucles, $crit) { |
| 68 | - $not = $crit->not; |
|
| 69 | - $boucle = &$boucles[$idb]; |
|
| 70 | - $id = $boucle->primary; |
|
| 71 | - |
|
| 72 | - if ($not or !$id) { |
|
| 73 | - return (['zbug_critere_inconnu', ['critere' => $not . $crit->op]]); |
|
| 74 | - } |
|
| 75 | - $arg = kwote(calculer_argument_precedent($idb, $id, $boucles)); |
|
| 76 | - $boucle->where[] = ["'!='", "'$boucle->id_table." . "$id'", $arg]; |
|
| 68 | + $not = $crit->not; |
|
| 69 | + $boucle = &$boucles[$idb]; |
|
| 70 | + $id = $boucle->primary; |
|
| 71 | + |
|
| 72 | + if ($not or !$id) { |
|
| 73 | + return (['zbug_critere_inconnu', ['critere' => $not . $crit->op]]); |
|
| 74 | + } |
|
| 75 | + $arg = kwote(calculer_argument_precedent($idb, $id, $boucles)); |
|
| 76 | + $boucle->where[] = ["'!='", "'$boucle->id_table." . "$id'", $arg]; |
|
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | |
@@ -93,73 +93,73 @@ discard block |
||
| 93 | 93 | * @return void |
| 94 | 94 | **/ |
| 95 | 95 | function critere_doublons_dist($idb, &$boucles, $crit) { |
| 96 | - $boucle = &$boucles[$idb]; |
|
| 97 | - $primary = $boucle->primary; |
|
| 98 | - |
|
| 99 | - // la table nécessite une clé primaire, non composée |
|
| 100 | - if (!$primary or strpos($primary, ',')) { |
|
| 101 | - return (['zbug_doublon_sur_table_sans_cle_primaire']); |
|
| 102 | - } |
|
| 103 | - |
|
| 104 | - $not = ($crit->not ? '' : 'NOT'); |
|
| 105 | - |
|
| 106 | - // le doublon s'applique sur un type de boucle (article) |
|
| 107 | - $nom = "'" . $boucle->type_requete . "'"; |
|
| 108 | - |
|
| 109 | - // compléter le nom avec un nom précisé {doublons nom} |
|
| 110 | - // on obtient $nom = "'article' . 'nom'" |
|
| 111 | - if (isset($crit->param[0])) { |
|
| 112 | - $nom .= '.' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 113 | - } |
|
| 114 | - |
|
| 115 | - // code qui déclarera l'index du stockage de nos doublons (pour éviter une notice PHP) |
|
| 116 | - $init_comment = "\n\n\t// Initialise le(s) critère(s) doublons\n"; |
|
| 117 | - $init_code = "\tif (!isset(\$doublons[\$d = $nom])) { \$doublons[\$d] = ''; }\n"; |
|
| 118 | - |
|
| 119 | - // on crée un sql_in avec la clé primaire de la table |
|
| 120 | - // et la collection des doublons déjà emmagasinés dans le tableau |
|
| 121 | - // $doublons et son index, ici $nom |
|
| 122 | - |
|
| 123 | - // debut du code "sql_in('articles.id_article', " |
|
| 124 | - $debut_in = "sql_in('" . $boucle->id_table . '.' . $primary . "', "; |
|
| 125 | - // lecture des données du doublon "$doublons[$doublon_index[] = " |
|
| 126 | - // Attention : boucle->doublons désigne une variable qu'on affecte |
|
| 127 | - $debut_doub = '$doublons[' . (!$not ? '' : ($boucle->doublons . '[]= ')); |
|
| 128 | - |
|
| 129 | - // le debut complet du code des doublons |
|
| 130 | - $debut_doub = $debut_in . $debut_doub; |
|
| 131 | - |
|
| 132 | - // nom du doublon "('article' . 'nom')]" |
|
| 133 | - $fin_doub = "($nom)]"; |
|
| 134 | - |
|
| 135 | - // si on trouve un autre critère doublon, |
|
| 136 | - // on fusionne pour avoir un seul IN, et on s'en va ! |
|
| 137 | - foreach ($boucle->where as $k => $w) { |
|
| 138 | - if (strpos($w[0], $debut_doub) === 0) { |
|
| 139 | - // fusionner le sql_in (du where) |
|
| 140 | - $boucle->where[$k][0] = $debut_doub . $fin_doub . ' . ' . substr($w[0], strlen($debut_in)); |
|
| 141 | - // fusionner l'initialisation (du hash) pour faire plus joli |
|
| 142 | - $x = strpos($boucle->hash, $init_comment); |
|
| 143 | - $len = strlen($init_comment); |
|
| 144 | - $boucle->hash = |
|
| 145 | - substr($boucle->hash, 0, $x + $len) . $init_code . substr($boucle->hash, $x + $len); |
|
| 146 | - |
|
| 147 | - return; |
|
| 148 | - } |
|
| 149 | - } |
|
| 150 | - |
|
| 151 | - // mettre l'ensemble dans un tableau pour que ce ne soit pas vu comme une constante |
|
| 152 | - $boucle->where[] = [$debut_doub . $fin_doub . ", '" . $not . "')"]; |
|
| 153 | - |
|
| 154 | - // déclarer le doublon s'il n'existe pas encore |
|
| 155 | - $boucle->hash .= $init_comment . $init_code; |
|
| 156 | - |
|
| 157 | - |
|
| 158 | - # la ligne suivante avait l'intention d'eviter une collecte deja faite |
|
| 159 | - # mais elle fait planter une boucle a 2 critere doublons: |
|
| 160 | - # {!doublons A}{doublons B} |
|
| 161 | - # (de http://article.gmane.org/gmane.comp.web.spip.devel/31034) |
|
| 162 | - # if ($crit->not) $boucle->doublons = ""; |
|
| 96 | + $boucle = &$boucles[$idb]; |
|
| 97 | + $primary = $boucle->primary; |
|
| 98 | + |
|
| 99 | + // la table nécessite une clé primaire, non composée |
|
| 100 | + if (!$primary or strpos($primary, ',')) { |
|
| 101 | + return (['zbug_doublon_sur_table_sans_cle_primaire']); |
|
| 102 | + } |
|
| 103 | + |
|
| 104 | + $not = ($crit->not ? '' : 'NOT'); |
|
| 105 | + |
|
| 106 | + // le doublon s'applique sur un type de boucle (article) |
|
| 107 | + $nom = "'" . $boucle->type_requete . "'"; |
|
| 108 | + |
|
| 109 | + // compléter le nom avec un nom précisé {doublons nom} |
|
| 110 | + // on obtient $nom = "'article' . 'nom'" |
|
| 111 | + if (isset($crit->param[0])) { |
|
| 112 | + $nom .= '.' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 113 | + } |
|
| 114 | + |
|
| 115 | + // code qui déclarera l'index du stockage de nos doublons (pour éviter une notice PHP) |
|
| 116 | + $init_comment = "\n\n\t// Initialise le(s) critère(s) doublons\n"; |
|
| 117 | + $init_code = "\tif (!isset(\$doublons[\$d = $nom])) { \$doublons[\$d] = ''; }\n"; |
|
| 118 | + |
|
| 119 | + // on crée un sql_in avec la clé primaire de la table |
|
| 120 | + // et la collection des doublons déjà emmagasinés dans le tableau |
|
| 121 | + // $doublons et son index, ici $nom |
|
| 122 | + |
|
| 123 | + // debut du code "sql_in('articles.id_article', " |
|
| 124 | + $debut_in = "sql_in('" . $boucle->id_table . '.' . $primary . "', "; |
|
| 125 | + // lecture des données du doublon "$doublons[$doublon_index[] = " |
|
| 126 | + // Attention : boucle->doublons désigne une variable qu'on affecte |
|
| 127 | + $debut_doub = '$doublons[' . (!$not ? '' : ($boucle->doublons . '[]= ')); |
|
| 128 | + |
|
| 129 | + // le debut complet du code des doublons |
|
| 130 | + $debut_doub = $debut_in . $debut_doub; |
|
| 131 | + |
|
| 132 | + // nom du doublon "('article' . 'nom')]" |
|
| 133 | + $fin_doub = "($nom)]"; |
|
| 134 | + |
|
| 135 | + // si on trouve un autre critère doublon, |
|
| 136 | + // on fusionne pour avoir un seul IN, et on s'en va ! |
|
| 137 | + foreach ($boucle->where as $k => $w) { |
|
| 138 | + if (strpos($w[0], $debut_doub) === 0) { |
|
| 139 | + // fusionner le sql_in (du where) |
|
| 140 | + $boucle->where[$k][0] = $debut_doub . $fin_doub . ' . ' . substr($w[0], strlen($debut_in)); |
|
| 141 | + // fusionner l'initialisation (du hash) pour faire plus joli |
|
| 142 | + $x = strpos($boucle->hash, $init_comment); |
|
| 143 | + $len = strlen($init_comment); |
|
| 144 | + $boucle->hash = |
|
| 145 | + substr($boucle->hash, 0, $x + $len) . $init_code . substr($boucle->hash, $x + $len); |
|
| 146 | + |
|
| 147 | + return; |
|
| 148 | + } |
|
| 149 | + } |
|
| 150 | + |
|
| 151 | + // mettre l'ensemble dans un tableau pour que ce ne soit pas vu comme une constante |
|
| 152 | + $boucle->where[] = [$debut_doub . $fin_doub . ", '" . $not . "')"]; |
|
| 153 | + |
|
| 154 | + // déclarer le doublon s'il n'existe pas encore |
|
| 155 | + $boucle->hash .= $init_comment . $init_code; |
|
| 156 | + |
|
| 157 | + |
|
| 158 | + # la ligne suivante avait l'intention d'eviter une collecte deja faite |
|
| 159 | + # mais elle fait planter une boucle a 2 critere doublons: |
|
| 160 | + # {!doublons A}{doublons B} |
|
| 161 | + # (de http://article.gmane.org/gmane.comp.web.spip.devel/31034) |
|
| 162 | + # if ($crit->not) $boucle->doublons = ""; |
|
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | |
@@ -180,14 +180,14 @@ discard block |
||
| 180 | 180 | * @return void |
| 181 | 181 | **/ |
| 182 | 182 | function critere_lang_select_dist($idb, &$boucles, $crit) { |
| 183 | - if (!isset($crit->param[1][0]) or !($param = $crit->param[1][0]->texte)) { |
|
| 184 | - $param = 'oui'; |
|
| 185 | - } |
|
| 186 | - if ($crit->not) { |
|
| 187 | - $param = ($param == 'oui') ? 'non' : 'oui'; |
|
| 188 | - } |
|
| 189 | - $boucle = &$boucles[$idb]; |
|
| 190 | - $boucle->lang_select = $param; |
|
| 183 | + if (!isset($crit->param[1][0]) or !($param = $crit->param[1][0]->texte)) { |
|
| 184 | + $param = 'oui'; |
|
| 185 | + } |
|
| 186 | + if ($crit->not) { |
|
| 187 | + $param = ($param == 'oui') ? 'non' : 'oui'; |
|
| 188 | + } |
|
| 189 | + $boucle = &$boucles[$idb]; |
|
| 190 | + $boucle->lang_select = $param; |
|
| 191 | 191 | } |
| 192 | 192 | |
| 193 | 193 | |
@@ -209,15 +209,15 @@ discard block |
||
| 209 | 209 | * @return void |
| 210 | 210 | **/ |
| 211 | 211 | function critere_debut_dist($idb, &$boucles, $crit) { |
| 212 | - [$un, $deux] = $crit->param; |
|
| 213 | - $un = $un[0]->texte; |
|
| 214 | - $deux = $deux[0]->texte; |
|
| 215 | - if ($deux) { |
|
| 216 | - $boucles[$idb]->limit = |
|
| 217 | - 'intval($Pile[0]["debut' . $un . '"]) . ",' . $deux . '"'; |
|
| 218 | - } else { |
|
| 219 | - calculer_critere_DEFAUT_dist($idb, $boucles, $crit); |
|
| 220 | - } |
|
| 212 | + [$un, $deux] = $crit->param; |
|
| 213 | + $un = $un[0]->texte; |
|
| 214 | + $deux = $deux[0]->texte; |
|
| 215 | + if ($deux) { |
|
| 216 | + $boucles[$idb]->limit = |
|
| 217 | + 'intval($Pile[0]["debut' . $un . '"]) . ",' . $deux . '"'; |
|
| 218 | + } else { |
|
| 219 | + calculer_critere_DEFAUT_dist($idb, $boucles, $crit); |
|
| 220 | + } |
|
| 221 | 221 | } |
| 222 | 222 | |
| 223 | 223 | |
@@ -251,58 +251,58 @@ discard block |
||
| 251 | 251 | **/ |
| 252 | 252 | function critere_pagination_dist($idb, &$boucles, $crit) { |
| 253 | 253 | |
| 254 | - $boucle = &$boucles[$idb]; |
|
| 255 | - // definition de la taille de la page |
|
| 256 | - $pas = !isset($crit->param[0][0]) ? "''" |
|
| 257 | - : calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent); |
|
| 258 | - |
|
| 259 | - if (!preg_match(_CODE_QUOTE, $pas, $r)) { |
|
| 260 | - $pas = "((\$a = intval($pas)) ? \$a : 10)"; |
|
| 261 | - } else { |
|
| 262 | - $r = intval($r[2]); |
|
| 263 | - $pas = strval($r ?: 10); |
|
| 264 | - } |
|
| 265 | - |
|
| 266 | - // Calcul du nommage de la pagination si il existe. |
|
| 267 | - // La nouvelle syntaxe {pagination 20, nom} est prise en compte et privilégiée mais on reste |
|
| 268 | - // compatible avec l'ancienne car certains cas fonctionnent correctement |
|
| 269 | - $type = "'$idb'"; |
|
| 270 | - // Calcul d'un nommage spécifique de la pagination si précisé. |
|
| 271 | - // Syntaxe {pagination 20, nom} |
|
| 272 | - if (isset($crit->param[0][1])) { |
|
| 273 | - $type = calculer_liste([$crit->param[0][1]], $idb, $boucles, $boucle->id_parent); |
|
| 274 | - } // Ancienne syntaxe {pagination 20 nom} pour compatibilité |
|
| 275 | - elseif (isset($crit->param[1][0])) { |
|
| 276 | - $type = calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent); |
|
| 277 | - } |
|
| 278 | - |
|
| 279 | - $debut = ($type[0] !== "'") ? "'debut'.$type" : ("'debut" . substr($type, 1)); |
|
| 280 | - $boucle->modificateur['debut_nom'] = $type; |
|
| 281 | - $partie = |
|
| 282 | - // tester si le numero de page demande est de la forme '@yyy' |
|
| 283 | - 'isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : _request(' . $debut . ");\n" |
|
| 284 | - . "\tif (\$debut_boucle && \$debut_boucle[0] === '@') {\n" |
|
| 285 | - . "\t\t" . '$debut_boucle = $Pile[0][' . $debut . '] = quete_debut_pagination(\'' . $boucle->primary . '\',$Pile[0][\'@' . $boucle->primary . '\'] = substr($debut_boucle,1),' . $pas . ',$iter);' . "\n" |
|
| 286 | - . "\t\t" . '$iter->seek(0);' . "\n" |
|
| 287 | - . "\t}\n" |
|
| 288 | - . "\t" . '$debut_boucle = intval($debut_boucle)'; |
|
| 289 | - |
|
| 290 | - $boucle->hash .= ' |
|
| 254 | + $boucle = &$boucles[$idb]; |
|
| 255 | + // definition de la taille de la page |
|
| 256 | + $pas = !isset($crit->param[0][0]) ? "''" |
|
| 257 | + : calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent); |
|
| 258 | + |
|
| 259 | + if (!preg_match(_CODE_QUOTE, $pas, $r)) { |
|
| 260 | + $pas = "((\$a = intval($pas)) ? \$a : 10)"; |
|
| 261 | + } else { |
|
| 262 | + $r = intval($r[2]); |
|
| 263 | + $pas = strval($r ?: 10); |
|
| 264 | + } |
|
| 265 | + |
|
| 266 | + // Calcul du nommage de la pagination si il existe. |
|
| 267 | + // La nouvelle syntaxe {pagination 20, nom} est prise en compte et privilégiée mais on reste |
|
| 268 | + // compatible avec l'ancienne car certains cas fonctionnent correctement |
|
| 269 | + $type = "'$idb'"; |
|
| 270 | + // Calcul d'un nommage spécifique de la pagination si précisé. |
|
| 271 | + // Syntaxe {pagination 20, nom} |
|
| 272 | + if (isset($crit->param[0][1])) { |
|
| 273 | + $type = calculer_liste([$crit->param[0][1]], $idb, $boucles, $boucle->id_parent); |
|
| 274 | + } // Ancienne syntaxe {pagination 20 nom} pour compatibilité |
|
| 275 | + elseif (isset($crit->param[1][0])) { |
|
| 276 | + $type = calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent); |
|
| 277 | + } |
|
| 278 | + |
|
| 279 | + $debut = ($type[0] !== "'") ? "'debut'.$type" : ("'debut" . substr($type, 1)); |
|
| 280 | + $boucle->modificateur['debut_nom'] = $type; |
|
| 281 | + $partie = |
|
| 282 | + // tester si le numero de page demande est de la forme '@yyy' |
|
| 283 | + 'isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : _request(' . $debut . ");\n" |
|
| 284 | + . "\tif (\$debut_boucle && \$debut_boucle[0] === '@') {\n" |
|
| 285 | + . "\t\t" . '$debut_boucle = $Pile[0][' . $debut . '] = quete_debut_pagination(\'' . $boucle->primary . '\',$Pile[0][\'@' . $boucle->primary . '\'] = substr($debut_boucle,1),' . $pas . ',$iter);' . "\n" |
|
| 286 | + . "\t\t" . '$iter->seek(0);' . "\n" |
|
| 287 | + . "\t}\n" |
|
| 288 | + . "\t" . '$debut_boucle = intval($debut_boucle)'; |
|
| 289 | + |
|
| 290 | + $boucle->hash .= ' |
|
| 291 | 291 | $command[\'pagination\'] = array((isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : null), ' . $pas . ');'; |
| 292 | 292 | |
| 293 | - $boucle->total_parties = $pas; |
|
| 294 | - calculer_parties($boucles, $idb, $partie, 'p+'); |
|
| 295 | - // ajouter la cle primaire dans le select pour pouvoir gerer la pagination referencee par @id |
|
| 296 | - // sauf si pas de primaire, ou si primaire composee |
|
| 297 | - // dans ce cas, on ne sait pas gerer une pagination indirecte |
|
| 298 | - $t = $boucle->id_table . '.' . $boucle->primary; |
|
| 299 | - if ( |
|
| 300 | - $boucle->primary |
|
| 301 | - and !preg_match('/[,\s]/', $boucle->primary) |
|
| 302 | - and !in_array($t, $boucle->select) |
|
| 303 | - ) { |
|
| 304 | - $boucle->select[] = $t; |
|
| 305 | - } |
|
| 293 | + $boucle->total_parties = $pas; |
|
| 294 | + calculer_parties($boucles, $idb, $partie, 'p+'); |
|
| 295 | + // ajouter la cle primaire dans le select pour pouvoir gerer la pagination referencee par @id |
|
| 296 | + // sauf si pas de primaire, ou si primaire composee |
|
| 297 | + // dans ce cas, on ne sait pas gerer une pagination indirecte |
|
| 298 | + $t = $boucle->id_table . '.' . $boucle->primary; |
|
| 299 | + if ( |
|
| 300 | + $boucle->primary |
|
| 301 | + and !preg_match('/[,\s]/', $boucle->primary) |
|
| 302 | + and !in_array($t, $boucle->select) |
|
| 303 | + ) { |
|
| 304 | + $boucle->select[] = $t; |
|
| 305 | + } |
|
| 306 | 306 | } |
| 307 | 307 | |
| 308 | 308 | |
@@ -324,24 +324,24 @@ discard block |
||
| 324 | 324 | **/ |
| 325 | 325 | function critere_recherche_dist($idb, &$boucles, $crit) { |
| 326 | 326 | |
| 327 | - $boucle = &$boucles[$idb]; |
|
| 327 | + $boucle = &$boucles[$idb]; |
|
| 328 | 328 | |
| 329 | - if (!$boucle->primary or strpos($boucle->primary, ',')) { |
|
| 330 | - erreur_squelette(_T('zbug_critere_sur_table_sans_cle_primaire', ['critere' => 'recherche']), $boucle); |
|
| 329 | + if (!$boucle->primary or strpos($boucle->primary, ',')) { |
|
| 330 | + erreur_squelette(_T('zbug_critere_sur_table_sans_cle_primaire', ['critere' => 'recherche']), $boucle); |
|
| 331 | 331 | |
| 332 | - return; |
|
| 333 | - } |
|
| 332 | + return; |
|
| 333 | + } |
|
| 334 | 334 | |
| 335 | - if (isset($crit->param[0])) { |
|
| 336 | - $quoi = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 337 | - } else { |
|
| 338 | - $quoi = '(isset($Pile[0]["recherche"])?$Pile[0]["recherche"]:(isset($GLOBALS["recherche"])?$GLOBALS["recherche"]:""))'; |
|
| 339 | - } |
|
| 335 | + if (isset($crit->param[0])) { |
|
| 336 | + $quoi = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 337 | + } else { |
|
| 338 | + $quoi = '(isset($Pile[0]["recherche"])?$Pile[0]["recherche"]:(isset($GLOBALS["recherche"])?$GLOBALS["recherche"]:""))'; |
|
| 339 | + } |
|
| 340 | 340 | |
| 341 | - $_modificateur = var_export($boucle->modificateur, true); |
|
| 342 | - $boucle->hash .= ' |
|
| 341 | + $_modificateur = var_export($boucle->modificateur, true); |
|
| 342 | + $boucle->hash .= ' |
|
| 343 | 343 | // RECHERCHE' |
| 344 | - . ($crit->cond ? ' |
|
| 344 | + . ($crit->cond ? ' |
|
| 345 | 345 | if (!strlen(' . $quoi . ')){ |
| 346 | 346 | list($rech_select, $rech_where) = array("0 as points",""); |
| 347 | 347 | } else' : '') . ' |
@@ -352,21 +352,21 @@ discard block |
||
| 352 | 352 | '; |
| 353 | 353 | |
| 354 | 354 | |
| 355 | - $t = $boucle->id_table . '.' . $boucle->primary; |
|
| 356 | - if (!in_array($t, $boucles[$idb]->select)) { |
|
| 357 | - $boucle->select[] = $t; |
|
| 358 | - } # pour postgres, neuneu ici |
|
| 359 | - // jointure uniquement sur le serveur principal |
|
| 360 | - // (on ne peut joindre une table d'un serveur distant avec la table des resultats du serveur principal) |
|
| 361 | - if (!$boucle->sql_serveur) { |
|
| 362 | - $boucle->join['resultats'] = ["'" . $boucle->id_table . "'", "'id'", "'" . $boucle->primary . "'"]; |
|
| 363 | - $boucle->from['resultats'] = 'spip_resultats'; |
|
| 364 | - } |
|
| 365 | - $boucle->select[] = '$rech_select'; |
|
| 366 | - //$boucle->where[]= "\$rech_where?'resultats.id=".$boucle->id_table.".".$boucle->primary."':''"; |
|
| 367 | - |
|
| 368 | - // et la recherche trouve |
|
| 369 | - $boucle->where[] = '$rech_where?$rech_where:\'\''; |
|
| 355 | + $t = $boucle->id_table . '.' . $boucle->primary; |
|
| 356 | + if (!in_array($t, $boucles[$idb]->select)) { |
|
| 357 | + $boucle->select[] = $t; |
|
| 358 | + } # pour postgres, neuneu ici |
|
| 359 | + // jointure uniquement sur le serveur principal |
|
| 360 | + // (on ne peut joindre une table d'un serveur distant avec la table des resultats du serveur principal) |
|
| 361 | + if (!$boucle->sql_serveur) { |
|
| 362 | + $boucle->join['resultats'] = ["'" . $boucle->id_table . "'", "'id'", "'" . $boucle->primary . "'"]; |
|
| 363 | + $boucle->from['resultats'] = 'spip_resultats'; |
|
| 364 | + } |
|
| 365 | + $boucle->select[] = '$rech_select'; |
|
| 366 | + //$boucle->where[]= "\$rech_where?'resultats.id=".$boucle->id_table.".".$boucle->primary."':''"; |
|
| 367 | + |
|
| 368 | + // et la recherche trouve |
|
| 369 | + $boucle->where[] = '$rech_where?$rech_where:\'\''; |
|
| 370 | 370 | } |
| 371 | 371 | |
| 372 | 372 | /** |
@@ -383,25 +383,25 @@ discard block |
||
| 383 | 383 | * @return void |
| 384 | 384 | **/ |
| 385 | 385 | function critere_traduction_dist($idb, &$boucles, $crit) { |
| 386 | - $boucle = &$boucles[$idb]; |
|
| 387 | - $prim = $boucle->primary; |
|
| 388 | - $table = $boucle->id_table; |
|
| 389 | - $arg = kwote(calculer_argument_precedent($idb, 'id_trad', $boucles)); |
|
| 390 | - $dprim = kwote(calculer_argument_precedent($idb, $prim, $boucles)); |
|
| 391 | - $boucle->where[] = |
|
| 392 | - [ |
|
| 393 | - "'OR'", |
|
| 394 | - [ |
|
| 395 | - "'AND'", |
|
| 396 | - ["'='", "'$table.id_trad'", 0], |
|
| 397 | - ["'='", "'$table.$prim'", $dprim] |
|
| 398 | - ], |
|
| 399 | - [ |
|
| 400 | - "'AND'", |
|
| 401 | - ["'>'", "'$table.id_trad'", 0], |
|
| 402 | - ["'='", "'$table.id_trad'", $arg] |
|
| 403 | - ] |
|
| 404 | - ]; |
|
| 386 | + $boucle = &$boucles[$idb]; |
|
| 387 | + $prim = $boucle->primary; |
|
| 388 | + $table = $boucle->id_table; |
|
| 389 | + $arg = kwote(calculer_argument_precedent($idb, 'id_trad', $boucles)); |
|
| 390 | + $dprim = kwote(calculer_argument_precedent($idb, $prim, $boucles)); |
|
| 391 | + $boucle->where[] = |
|
| 392 | + [ |
|
| 393 | + "'OR'", |
|
| 394 | + [ |
|
| 395 | + "'AND'", |
|
| 396 | + ["'='", "'$table.id_trad'", 0], |
|
| 397 | + ["'='", "'$table.$prim'", $dprim] |
|
| 398 | + ], |
|
| 399 | + [ |
|
| 400 | + "'AND'", |
|
| 401 | + ["'>'", "'$table.id_trad'", 0], |
|
| 402 | + ["'='", "'$table.id_trad'", $arg] |
|
| 403 | + ] |
|
| 404 | + ]; |
|
| 405 | 405 | } |
| 406 | 406 | |
| 407 | 407 | |
@@ -419,17 +419,17 @@ discard block |
||
| 419 | 419 | * @return void |
| 420 | 420 | **/ |
| 421 | 421 | function critere_origine_traduction_dist($idb, &$boucles, $crit) { |
| 422 | - $boucle = &$boucles[$idb]; |
|
| 423 | - $prim = $boucle->primary; |
|
| 424 | - $table = $boucle->id_table; |
|
| 425 | - |
|
| 426 | - $c = |
|
| 427 | - [ |
|
| 428 | - "'OR'", |
|
| 429 | - ["'='", "'$table." . "id_trad'", "'$table.$prim'"], |
|
| 430 | - ["'='", "'$table.id_trad'", "'0'"] |
|
| 431 | - ]; |
|
| 432 | - $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c); |
|
| 422 | + $boucle = &$boucles[$idb]; |
|
| 423 | + $prim = $boucle->primary; |
|
| 424 | + $table = $boucle->id_table; |
|
| 425 | + |
|
| 426 | + $c = |
|
| 427 | + [ |
|
| 428 | + "'OR'", |
|
| 429 | + ["'='", "'$table." . "id_trad'", "'$table.$prim'"], |
|
| 430 | + ["'='", "'$table.id_trad'", "'0'"] |
|
| 431 | + ]; |
|
| 432 | + $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c); |
|
| 433 | 433 | } |
| 434 | 434 | |
| 435 | 435 | |
@@ -446,17 +446,17 @@ discard block |
||
| 446 | 446 | **/ |
| 447 | 447 | function critere_meme_parent_dist($idb, &$boucles, $crit) { |
| 448 | 448 | |
| 449 | - $boucle = &$boucles[$idb]; |
|
| 450 | - $arg = kwote(calculer_argument_precedent($idb, 'id_parent', $boucles)); |
|
| 451 | - $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent'; |
|
| 452 | - $mparent = $boucle->id_table . '.' . $id_parent; |
|
| 453 | - |
|
| 454 | - if ($boucle->type_requete == 'rubriques' or isset($GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'])) { |
|
| 455 | - $boucle->where[] = ["'='", "'$mparent'", $arg]; |
|
| 456 | - } // le cas FORUMS est gere dans le plugin forum, dans la fonction critere_FORUMS_meme_parent_dist() |
|
| 457 | - else { |
|
| 458 | - return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $boucle->type_requete]]); |
|
| 459 | - } |
|
| 449 | + $boucle = &$boucles[$idb]; |
|
| 450 | + $arg = kwote(calculer_argument_precedent($idb, 'id_parent', $boucles)); |
|
| 451 | + $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent'; |
|
| 452 | + $mparent = $boucle->id_table . '.' . $id_parent; |
|
| 453 | + |
|
| 454 | + if ($boucle->type_requete == 'rubriques' or isset($GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'])) { |
|
| 455 | + $boucle->where[] = ["'='", "'$mparent'", $arg]; |
|
| 456 | + } // le cas FORUMS est gere dans le plugin forum, dans la fonction critere_FORUMS_meme_parent_dist() |
|
| 457 | + else { |
|
| 458 | + return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $boucle->type_requete]]); |
|
| 459 | + } |
|
| 460 | 460 | } |
| 461 | 461 | |
| 462 | 462 | |
@@ -487,37 +487,37 @@ discard block |
||
| 487 | 487 | **/ |
| 488 | 488 | function critere_branche_dist($idb, &$boucles, $crit) { |
| 489 | 489 | |
| 490 | - $not = $crit->not; |
|
| 491 | - $boucle = &$boucles[$idb]; |
|
| 492 | - // prendre en priorite un identifiant en parametre {branche XX} |
|
| 493 | - if (isset($crit->param[0])) { |
|
| 494 | - $arg = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 495 | - // sinon on le prend chez une boucle parente |
|
| 496 | - } else { |
|
| 497 | - $arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles), $boucle->sql_serveur, 'int NOT NULL'); |
|
| 498 | - } |
|
| 499 | - |
|
| 500 | - //Trouver une jointure |
|
| 501 | - $champ = 'id_rubrique'; |
|
| 502 | - $desc = $boucle->show; |
|
| 503 | - //Seulement si necessaire |
|
| 504 | - if (!array_key_exists($champ, $desc['field'])) { |
|
| 505 | - $cle = trouver_jointure_champ($champ, $boucle); |
|
| 506 | - $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 507 | - $desc = $trouver_table($boucle->from[$cle]); |
|
| 508 | - if (count(trouver_champs_decomposes($champ, $desc)) > 1) { |
|
| 509 | - $decompose = decompose_champ_id_objet($champ); |
|
| 510 | - $champ = array_shift($decompose); |
|
| 511 | - $boucle->where[] = ["'='", _q($cle . '.' . reset($decompose)), '"' . sql_quote(end($decompose)) . '"']; |
|
| 512 | - } |
|
| 513 | - } else { |
|
| 514 | - $cle = $boucle->id_table; |
|
| 515 | - } |
|
| 516 | - |
|
| 517 | - $c = "sql_in('$cle" . ".$champ', calcul_branche_in($arg)" |
|
| 518 | - . ($not ? ", 'NOT'" : '') . ')'; |
|
| 519 | - $boucle->where[] = !$crit->cond ? $c : |
|
| 520 | - ("($arg ? $c : " . ($not ? "'0=1'" : "'1=1'") . ')'); |
|
| 490 | + $not = $crit->not; |
|
| 491 | + $boucle = &$boucles[$idb]; |
|
| 492 | + // prendre en priorite un identifiant en parametre {branche XX} |
|
| 493 | + if (isset($crit->param[0])) { |
|
| 494 | + $arg = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 495 | + // sinon on le prend chez une boucle parente |
|
| 496 | + } else { |
|
| 497 | + $arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles), $boucle->sql_serveur, 'int NOT NULL'); |
|
| 498 | + } |
|
| 499 | + |
|
| 500 | + //Trouver une jointure |
|
| 501 | + $champ = 'id_rubrique'; |
|
| 502 | + $desc = $boucle->show; |
|
| 503 | + //Seulement si necessaire |
|
| 504 | + if (!array_key_exists($champ, $desc['field'])) { |
|
| 505 | + $cle = trouver_jointure_champ($champ, $boucle); |
|
| 506 | + $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 507 | + $desc = $trouver_table($boucle->from[$cle]); |
|
| 508 | + if (count(trouver_champs_decomposes($champ, $desc)) > 1) { |
|
| 509 | + $decompose = decompose_champ_id_objet($champ); |
|
| 510 | + $champ = array_shift($decompose); |
|
| 511 | + $boucle->where[] = ["'='", _q($cle . '.' . reset($decompose)), '"' . sql_quote(end($decompose)) . '"']; |
|
| 512 | + } |
|
| 513 | + } else { |
|
| 514 | + $cle = $boucle->id_table; |
|
| 515 | + } |
|
| 516 | + |
|
| 517 | + $c = "sql_in('$cle" . ".$champ', calcul_branche_in($arg)" |
|
| 518 | + . ($not ? ", 'NOT'" : '') . ')'; |
|
| 519 | + $boucle->where[] = !$crit->cond ? $c : |
|
| 520 | + ("($arg ? $c : " . ($not ? "'0=1'" : "'1=1'") . ')'); |
|
| 521 | 521 | } |
| 522 | 522 | |
| 523 | 523 | /** |
@@ -533,15 +533,15 @@ discard block |
||
| 533 | 533 | **/ |
| 534 | 534 | function critere_logo_dist($idb, &$boucles, $crit) { |
| 535 | 535 | |
| 536 | - $boucle = &$boucles[$idb]; |
|
| 537 | - $not = ($crit->not ? 'NOT' : ''); |
|
| 538 | - $serveur = $boucle->sql_serveur; |
|
| 536 | + $boucle = &$boucles[$idb]; |
|
| 537 | + $not = ($crit->not ? 'NOT' : ''); |
|
| 538 | + $serveur = $boucle->sql_serveur; |
|
| 539 | 539 | |
| 540 | - $c = "sql_in('" . |
|
| 541 | - $boucle->id_table . '.' . $boucle->primary |
|
| 542 | - . "', lister_objets_avec_logos('" . $boucle->primary . "'), '$not', '$serveur')"; |
|
| 540 | + $c = "sql_in('" . |
|
| 541 | + $boucle->id_table . '.' . $boucle->primary |
|
| 542 | + . "', lister_objets_avec_logos('" . $boucle->primary . "'), '$not', '$serveur')"; |
|
| 543 | 543 | |
| 544 | - $boucle->where[] = $c; |
|
| 544 | + $boucle->where[] = $c; |
|
| 545 | 545 | } |
| 546 | 546 | |
| 547 | 547 | |
@@ -563,31 +563,31 @@ discard block |
||
| 563 | 563 | * @return void |
| 564 | 564 | **/ |
| 565 | 565 | function critere_fusion_dist($idb, &$boucles, $crit) { |
| 566 | - if ($t = isset($crit->param[0])) { |
|
| 567 | - $t = $crit->param[0]; |
|
| 568 | - if ($t[0]->type == 'texte') { |
|
| 569 | - $t = $t[0]->texte; |
|
| 570 | - if (preg_match('/^(.*)\.(.*)$/', $t, $r)) { |
|
| 571 | - $t = table_objet_sql($r[1]); |
|
| 572 | - $t = array_search($t, $boucles[$idb]->from); |
|
| 573 | - if ($t) { |
|
| 574 | - $t .= '.' . $r[2]; |
|
| 575 | - } |
|
| 576 | - } |
|
| 577 | - } else { |
|
| 578 | - $t = '".' |
|
| 579 | - . calculer_critere_arg_dynamique($idb, $boucles, $t) |
|
| 580 | - . '."'; |
|
| 581 | - } |
|
| 582 | - } |
|
| 583 | - if ($t) { |
|
| 584 | - $boucles[$idb]->group[] = $t; |
|
| 585 | - if (!in_array($t, $boucles[$idb]->select)) { |
|
| 586 | - $boucles[$idb]->select[] = $t; |
|
| 587 | - } |
|
| 588 | - } else { |
|
| 589 | - return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']]); |
|
| 590 | - } |
|
| 566 | + if ($t = isset($crit->param[0])) { |
|
| 567 | + $t = $crit->param[0]; |
|
| 568 | + if ($t[0]->type == 'texte') { |
|
| 569 | + $t = $t[0]->texte; |
|
| 570 | + if (preg_match('/^(.*)\.(.*)$/', $t, $r)) { |
|
| 571 | + $t = table_objet_sql($r[1]); |
|
| 572 | + $t = array_search($t, $boucles[$idb]->from); |
|
| 573 | + if ($t) { |
|
| 574 | + $t .= '.' . $r[2]; |
|
| 575 | + } |
|
| 576 | + } |
|
| 577 | + } else { |
|
| 578 | + $t = '".' |
|
| 579 | + . calculer_critere_arg_dynamique($idb, $boucles, $t) |
|
| 580 | + . '."'; |
|
| 581 | + } |
|
| 582 | + } |
|
| 583 | + if ($t) { |
|
| 584 | + $boucles[$idb]->group[] = $t; |
|
| 585 | + if (!in_array($t, $boucles[$idb]->select)) { |
|
| 586 | + $boucles[$idb]->select[] = $t; |
|
| 587 | + } |
|
| 588 | + } else { |
|
| 589 | + return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']]); |
|
| 590 | + } |
|
| 591 | 591 | } |
| 592 | 592 | |
| 593 | 593 | /** |
@@ -607,7 +607,7 @@ discard block |
||
| 607 | 607 | * @return void |
| 608 | 608 | **/ |
| 609 | 609 | function critere_fusion_supprimer_dist($idb, &$boucles, $crit) { |
| 610 | - $boucles[$idb]->group = []; |
|
| 610 | + $boucles[$idb]->group = []; |
|
| 611 | 611 | } |
| 612 | 612 | |
| 613 | 613 | /** |
@@ -644,44 +644,44 @@ discard block |
||
| 644 | 644 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 645 | 645 | */ |
| 646 | 646 | function critere_collecte_dist($idb, &$boucles, $crit) { |
| 647 | - if (isset($crit->param[0])) { |
|
| 648 | - $_coll = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 649 | - $boucle = $boucles[$idb]; |
|
| 650 | - $boucle->modificateur['collate'] = "($_coll ?' COLLATE '.$_coll:'')"; |
|
| 651 | - $n = is_countable($boucle->order) ? count($boucle->order) : 0; |
|
| 652 | - if ($n && (strpos($boucle->order[$n - 1], 'COLLATE') === false)) { |
|
| 653 | - // l'instruction COLLATE doit être placée avant ASC ou DESC |
|
| 654 | - // notamment lors de l'utilisation `{!par xxx}{collate yyy}` |
|
| 655 | - if ( |
|
| 656 | - (false !== $i = strpos($boucle->order[$n - 1], 'ASC')) |
|
| 657 | - or (false !== $i = strpos($boucle->order[$n - 1], 'DESC')) |
|
| 658 | - ) { |
|
| 659 | - $boucle->order[$n - 1] = substr_replace($boucle->order[$n - 1], "' . " . $boucle->modificateur['collate'] . " . ' ", $i, 0); |
|
| 660 | - } else { |
|
| 661 | - $boucle->order[$n - 1] .= ' . ' . $boucle->modificateur['collate']; |
|
| 662 | - } |
|
| 663 | - } |
|
| 664 | - } else { |
|
| 665 | - return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . (is_countable($boucles[$idb]->order) ? count($boucles[$idb]->order) : 0)]]); |
|
| 666 | - } |
|
| 647 | + if (isset($crit->param[0])) { |
|
| 648 | + $_coll = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 649 | + $boucle = $boucles[$idb]; |
|
| 650 | + $boucle->modificateur['collate'] = "($_coll ?' COLLATE '.$_coll:'')"; |
|
| 651 | + $n = is_countable($boucle->order) ? count($boucle->order) : 0; |
|
| 652 | + if ($n && (strpos($boucle->order[$n - 1], 'COLLATE') === false)) { |
|
| 653 | + // l'instruction COLLATE doit être placée avant ASC ou DESC |
|
| 654 | + // notamment lors de l'utilisation `{!par xxx}{collate yyy}` |
|
| 655 | + if ( |
|
| 656 | + (false !== $i = strpos($boucle->order[$n - 1], 'ASC')) |
|
| 657 | + or (false !== $i = strpos($boucle->order[$n - 1], 'DESC')) |
|
| 658 | + ) { |
|
| 659 | + $boucle->order[$n - 1] = substr_replace($boucle->order[$n - 1], "' . " . $boucle->modificateur['collate'] . " . ' ", $i, 0); |
|
| 660 | + } else { |
|
| 661 | + $boucle->order[$n - 1] .= ' . ' . $boucle->modificateur['collate']; |
|
| 662 | + } |
|
| 663 | + } |
|
| 664 | + } else { |
|
| 665 | + return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . (is_countable($boucles[$idb]->order) ? count($boucles[$idb]->order) : 0)]]); |
|
| 666 | + } |
|
| 667 | 667 | } |
| 668 | 668 | |
| 669 | 669 | function calculer_critere_arg_dynamique($idb, &$boucles, $crit, $suffix = '') { |
| 670 | - $boucle = $boucles[$idb]; |
|
| 671 | - $alt = "('" . $boucle->id_table . '.\' . $x' . $suffix . ')'; |
|
| 672 | - $var = '$champs_' . $idb; |
|
| 673 | - $desc = (strpos($boucle->in, (string) "static $var =") !== false); |
|
| 674 | - if (!$desc) { |
|
| 675 | - $desc = $boucle->show['field']; |
|
| 676 | - $desc = implode(',', array_map('_q', array_keys($desc))); |
|
| 677 | - $boucles[$idb]->in .= "\n\tstatic $var = array(" . $desc . ');'; |
|
| 678 | - } |
|
| 679 | - if ($desc) { |
|
| 680 | - $alt = "(in_array(\$x, $var) ? $alt :(\$x$suffix))"; |
|
| 681 | - } |
|
| 682 | - $arg = calculer_liste($crit, $idb, $boucles, $boucle->id_parent); |
|
| 683 | - |
|
| 684 | - return "((\$x = preg_replace(\"/\\W/\",'', $arg)) ? $alt : '')"; |
|
| 670 | + $boucle = $boucles[$idb]; |
|
| 671 | + $alt = "('" . $boucle->id_table . '.\' . $x' . $suffix . ')'; |
|
| 672 | + $var = '$champs_' . $idb; |
|
| 673 | + $desc = (strpos($boucle->in, (string) "static $var =") !== false); |
|
| 674 | + if (!$desc) { |
|
| 675 | + $desc = $boucle->show['field']; |
|
| 676 | + $desc = implode(',', array_map('_q', array_keys($desc))); |
|
| 677 | + $boucles[$idb]->in .= "\n\tstatic $var = array(" . $desc . ');'; |
|
| 678 | + } |
|
| 679 | + if ($desc) { |
|
| 680 | + $alt = "(in_array(\$x, $var) ? $alt :(\$x$suffix))"; |
|
| 681 | + } |
|
| 682 | + $arg = calculer_liste($crit, $idb, $boucles, $boucle->id_parent); |
|
| 683 | + |
|
| 684 | + return "((\$x = preg_replace(\"/\\W/\",'', $arg)) ? $alt : '')"; |
|
| 685 | 685 | } |
| 686 | 686 | |
| 687 | 687 | /** |
@@ -720,7 +720,7 @@ discard block |
||
| 720 | 720 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 721 | 721 | */ |
| 722 | 722 | function critere_par_dist($idb, &$boucles, $crit) { |
| 723 | - return critere_parinverse($idb, $boucles, $crit); |
|
| 723 | + return critere_parinverse($idb, $boucles, $crit); |
|
| 724 | 724 | } |
| 725 | 725 | |
| 726 | 726 | /** |
@@ -742,93 +742,93 @@ discard block |
||
| 742 | 742 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 743 | 743 | */ |
| 744 | 744 | function critere_parinverse($idb, &$boucles, $crit) { |
| 745 | - $boucle = &$boucles[$idb]; |
|
| 746 | - |
|
| 747 | - $sens = $collecte = ''; |
|
| 748 | - if ($crit->not) { |
|
| 749 | - $sens = " . ' DESC'"; |
|
| 750 | - } |
|
| 751 | - if (isset($boucle->modificateur['collate'])) { |
|
| 752 | - $collecte = ' . ' . $boucle->modificateur['collate']; |
|
| 753 | - } |
|
| 754 | - |
|
| 755 | - // Pour chaque paramètre du critère |
|
| 756 | - foreach ($crit->param as $tri) { |
|
| 757 | - $order = $fct = ''; |
|
| 758 | - // tris specifiés dynamiquement {par #ENV{tri}} |
|
| 759 | - if ($tri[0]->type != 'texte') { |
|
| 760 | - // calculer le order dynamique qui verifie les champs |
|
| 761 | - $order = calculer_critere_arg_dynamique($idb, $boucles, $tri, $sens); |
|
| 762 | - // ajouter 'hasard' comme possibilité de tri dynamique |
|
| 763 | - calculer_critere_par_hasard($idb, $boucles, $crit); |
|
| 764 | - } |
|
| 765 | - // tris textuels {par titre} |
|
| 766 | - else { |
|
| 767 | - $par = array_shift($tri); |
|
| 768 | - $par = $par->texte; |
|
| 769 | - |
|
| 770 | - // tris de la forme {par expression champ} tel que {par num titre} ou {par multi titre} |
|
| 771 | - if (preg_match(',^(\w+)[\s]+(.*)$,', $par, $m)) { |
|
| 772 | - $expression = trim($m[1]); |
|
| 773 | - $champ = trim($m[2]); |
|
| 774 | - if (function_exists($f = 'calculer_critere_par_expression_' . $expression)) { |
|
| 775 | - $order = $f($idb, $boucles, $crit, $tri, $champ); |
|
| 776 | - } else { |
|
| 777 | - return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]]; |
|
| 778 | - } |
|
| 779 | - |
|
| 780 | - // tris de la forme {par champ} ou {par FONCTION(champ)} |
|
| 781 | - } elseif (preg_match(',^' . CHAMP_SQL_PLUS_FONC . '$,is', $par, $match)) { |
|
| 782 | - // {par FONCTION(champ)} |
|
| 783 | - if (count($match) > 2) { |
|
| 784 | - $par = substr($match[2], 1, -1); |
|
| 785 | - $fct = $match[1]; |
|
| 786 | - } |
|
| 787 | - // quelques cas spécifiques {par hasard}, {par date} |
|
| 788 | - if ($par == 'hasard') { |
|
| 789 | - $order = calculer_critere_par_hasard($idb, $boucles, $crit); |
|
| 790 | - } elseif ($par == 'date' and !empty($boucle->show['date'])) { |
|
| 791 | - $order = "'" . $boucle->id_table . '.' . $boucle->show['date'] . "'"; |
|
| 792 | - } else { |
|
| 793 | - // cas général {par champ}, {par table.champ}, ... |
|
| 794 | - $order = calculer_critere_par_champ($idb, $boucles, $crit, $par); |
|
| 795 | - } |
|
| 796 | - } |
|
| 797 | - |
|
| 798 | - // on ne sait pas traiter… |
|
| 799 | - else { |
|
| 800 | - return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]]; |
|
| 801 | - } |
|
| 802 | - |
|
| 803 | - // En cas d'erreur de squelette retournée par une fonction |
|
| 804 | - if (is_array($order)) { |
|
| 805 | - return $order; |
|
| 806 | - } |
|
| 807 | - } |
|
| 808 | - |
|
| 809 | - if (preg_match('/^\'([^"]*)\'$/', $order, $m)) { |
|
| 810 | - $t = $m[1]; |
|
| 811 | - if (strpos($t, '.') and !in_array($t, $boucle->select)) { |
|
| 812 | - $boucle->select[] = $t; |
|
| 813 | - } |
|
| 814 | - } else { |
|
| 815 | - $sens = ''; |
|
| 816 | - } |
|
| 817 | - |
|
| 818 | - if ($fct) { |
|
| 819 | - if (preg_match("/^\s*'(.*)'\s*$/", $order, $r)) { |
|
| 820 | - $order = "'$fct(" . $r[1] . ")'"; |
|
| 821 | - } else { |
|
| 822 | - $order = "'$fct(' . $order . ')'"; |
|
| 823 | - } |
|
| 824 | - } |
|
| 825 | - $t = $order . $collecte . $sens; |
|
| 826 | - if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) { |
|
| 827 | - $t = $r[1] . $r[2]; |
|
| 828 | - } |
|
| 829 | - |
|
| 830 | - $boucle->order[] = $t; |
|
| 831 | - } |
|
| 745 | + $boucle = &$boucles[$idb]; |
|
| 746 | + |
|
| 747 | + $sens = $collecte = ''; |
|
| 748 | + if ($crit->not) { |
|
| 749 | + $sens = " . ' DESC'"; |
|
| 750 | + } |
|
| 751 | + if (isset($boucle->modificateur['collate'])) { |
|
| 752 | + $collecte = ' . ' . $boucle->modificateur['collate']; |
|
| 753 | + } |
|
| 754 | + |
|
| 755 | + // Pour chaque paramètre du critère |
|
| 756 | + foreach ($crit->param as $tri) { |
|
| 757 | + $order = $fct = ''; |
|
| 758 | + // tris specifiés dynamiquement {par #ENV{tri}} |
|
| 759 | + if ($tri[0]->type != 'texte') { |
|
| 760 | + // calculer le order dynamique qui verifie les champs |
|
| 761 | + $order = calculer_critere_arg_dynamique($idb, $boucles, $tri, $sens); |
|
| 762 | + // ajouter 'hasard' comme possibilité de tri dynamique |
|
| 763 | + calculer_critere_par_hasard($idb, $boucles, $crit); |
|
| 764 | + } |
|
| 765 | + // tris textuels {par titre} |
|
| 766 | + else { |
|
| 767 | + $par = array_shift($tri); |
|
| 768 | + $par = $par->texte; |
|
| 769 | + |
|
| 770 | + // tris de la forme {par expression champ} tel que {par num titre} ou {par multi titre} |
|
| 771 | + if (preg_match(',^(\w+)[\s]+(.*)$,', $par, $m)) { |
|
| 772 | + $expression = trim($m[1]); |
|
| 773 | + $champ = trim($m[2]); |
|
| 774 | + if (function_exists($f = 'calculer_critere_par_expression_' . $expression)) { |
|
| 775 | + $order = $f($idb, $boucles, $crit, $tri, $champ); |
|
| 776 | + } else { |
|
| 777 | + return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]]; |
|
| 778 | + } |
|
| 779 | + |
|
| 780 | + // tris de la forme {par champ} ou {par FONCTION(champ)} |
|
| 781 | + } elseif (preg_match(',^' . CHAMP_SQL_PLUS_FONC . '$,is', $par, $match)) { |
|
| 782 | + // {par FONCTION(champ)} |
|
| 783 | + if (count($match) > 2) { |
|
| 784 | + $par = substr($match[2], 1, -1); |
|
| 785 | + $fct = $match[1]; |
|
| 786 | + } |
|
| 787 | + // quelques cas spécifiques {par hasard}, {par date} |
|
| 788 | + if ($par == 'hasard') { |
|
| 789 | + $order = calculer_critere_par_hasard($idb, $boucles, $crit); |
|
| 790 | + } elseif ($par == 'date' and !empty($boucle->show['date'])) { |
|
| 791 | + $order = "'" . $boucle->id_table . '.' . $boucle->show['date'] . "'"; |
|
| 792 | + } else { |
|
| 793 | + // cas général {par champ}, {par table.champ}, ... |
|
| 794 | + $order = calculer_critere_par_champ($idb, $boucles, $crit, $par); |
|
| 795 | + } |
|
| 796 | + } |
|
| 797 | + |
|
| 798 | + // on ne sait pas traiter… |
|
| 799 | + else { |
|
| 800 | + return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]]; |
|
| 801 | + } |
|
| 802 | + |
|
| 803 | + // En cas d'erreur de squelette retournée par une fonction |
|
| 804 | + if (is_array($order)) { |
|
| 805 | + return $order; |
|
| 806 | + } |
|
| 807 | + } |
|
| 808 | + |
|
| 809 | + if (preg_match('/^\'([^"]*)\'$/', $order, $m)) { |
|
| 810 | + $t = $m[1]; |
|
| 811 | + if (strpos($t, '.') and !in_array($t, $boucle->select)) { |
|
| 812 | + $boucle->select[] = $t; |
|
| 813 | + } |
|
| 814 | + } else { |
|
| 815 | + $sens = ''; |
|
| 816 | + } |
|
| 817 | + |
|
| 818 | + if ($fct) { |
|
| 819 | + if (preg_match("/^\s*'(.*)'\s*$/", $order, $r)) { |
|
| 820 | + $order = "'$fct(" . $r[1] . ")'"; |
|
| 821 | + } else { |
|
| 822 | + $order = "'$fct(' . $order . ')'"; |
|
| 823 | + } |
|
| 824 | + } |
|
| 825 | + $t = $order . $collecte . $sens; |
|
| 826 | + if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) { |
|
| 827 | + $t = $r[1] . $r[2]; |
|
| 828 | + } |
|
| 829 | + |
|
| 830 | + $boucle->order[] = $t; |
|
| 831 | + } |
|
| 832 | 832 | } |
| 833 | 833 | |
| 834 | 834 | /** |
@@ -842,13 +842,13 @@ discard block |
||
| 842 | 842 | * @return string Clause pour le Order by |
| 843 | 843 | */ |
| 844 | 844 | function calculer_critere_par_hasard($idb, &$boucles, $crit) { |
| 845 | - $boucle = &$boucles[$idb]; |
|
| 846 | - // Si ce n'est fait, ajouter un champ 'hasard' dans le select |
|
| 847 | - $parha = 'rand() AS hasard'; |
|
| 848 | - if (!in_array($parha, $boucle->select)) { |
|
| 849 | - $boucle->select[] = $parha; |
|
| 850 | - } |
|
| 851 | - return "'hasard'"; |
|
| 845 | + $boucle = &$boucles[$idb]; |
|
| 846 | + // Si ce n'est fait, ajouter un champ 'hasard' dans le select |
|
| 847 | + $parha = 'rand() AS hasard'; |
|
| 848 | + if (!in_array($parha, $boucle->select)) { |
|
| 849 | + $boucle->select[] = $parha; |
|
| 850 | + } |
|
| 851 | + return "'hasard'"; |
|
| 852 | 852 | } |
| 853 | 853 | |
| 854 | 854 | /** |
@@ -872,24 +872,24 @@ discard block |
||
| 872 | 872 | * @return string Clause pour le Order by |
| 873 | 873 | */ |
| 874 | 874 | function calculer_critere_par_expression_num($idb, &$boucles, $crit, $tri, $champ) { |
| 875 | - $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true); |
|
| 876 | - if (is_array($_champ)) { |
|
| 877 | - return ['zbug_critere_inconnu', ['critere' => $crit->op . " num $champ"]]; |
|
| 878 | - } |
|
| 879 | - $boucle = &$boucles[$idb]; |
|
| 880 | - $texte = '0+' . $_champ; |
|
| 881 | - $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent); |
|
| 882 | - if ($suite !== "''") { |
|
| 883 | - $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "'; |
|
| 884 | - } |
|
| 885 | - $asnum = 'num' . ($boucle->order ? count($boucle->order) : ''); |
|
| 886 | - $boucle->select[] = $texte . " AS $asnum"; |
|
| 887 | - |
|
| 888 | - $orderassinum = calculer_critere_par_expression_sinum($idb, $boucles, $crit, $tri, $champ); |
|
| 889 | - $orderassinum = trim($orderassinum, "'"); |
|
| 890 | - |
|
| 891 | - $order = "'$orderassinum, $asnum'"; |
|
| 892 | - return $order; |
|
| 875 | + $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true); |
|
| 876 | + if (is_array($_champ)) { |
|
| 877 | + return ['zbug_critere_inconnu', ['critere' => $crit->op . " num $champ"]]; |
|
| 878 | + } |
|
| 879 | + $boucle = &$boucles[$idb]; |
|
| 880 | + $texte = '0+' . $_champ; |
|
| 881 | + $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent); |
|
| 882 | + if ($suite !== "''") { |
|
| 883 | + $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "'; |
|
| 884 | + } |
|
| 885 | + $asnum = 'num' . ($boucle->order ? count($boucle->order) : ''); |
|
| 886 | + $boucle->select[] = $texte . " AS $asnum"; |
|
| 887 | + |
|
| 888 | + $orderassinum = calculer_critere_par_expression_sinum($idb, $boucles, $crit, $tri, $champ); |
|
| 889 | + $orderassinum = trim($orderassinum, "'"); |
|
| 890 | + |
|
| 891 | + $order = "'$orderassinum, $asnum'"; |
|
| 892 | + return $order; |
|
| 893 | 893 | } |
| 894 | 894 | |
| 895 | 895 | /** |
@@ -910,35 +910,35 @@ discard block |
||
| 910 | 910 | * @return string Clause pour le Order by |
| 911 | 911 | */ |
| 912 | 912 | function calculer_critere_par_expression_sinum($idb, &$boucles, $crit, $tri, $champ) { |
| 913 | - $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true); |
|
| 914 | - if (is_array($_champ)) { |
|
| 915 | - return ['zbug_critere_inconnu', ['critere' => $crit->op . " sinum $champ"]]; |
|
| 916 | - } |
|
| 917 | - $boucle = &$boucles[$idb]; |
|
| 918 | - $texte = '0+' . $_champ; |
|
| 919 | - $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent); |
|
| 920 | - if ($suite !== "''") { |
|
| 921 | - $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "'; |
|
| 922 | - } |
|
| 923 | - |
|
| 924 | - $as = false; |
|
| 925 | - $select = "CASE ( $texte ) WHEN 0 THEN 1 ELSE 0 END AS "; |
|
| 926 | - foreach ($boucle->select as $s) { |
|
| 927 | - if (strpos($s, $select) === 0) { |
|
| 928 | - $as = trim(substr($s, strlen($select))); |
|
| 929 | - if (!preg_match(',\W,', $as)) { |
|
| 930 | - break; |
|
| 931 | - } |
|
| 932 | - $as = false; |
|
| 933 | - } |
|
| 934 | - } |
|
| 935 | - |
|
| 936 | - if (!$as) { |
|
| 937 | - $as = 'sinum' . ($boucle->order ? count($boucle->order) : ''); |
|
| 938 | - $boucle->select[] = $select . $as; |
|
| 939 | - } |
|
| 940 | - $order = "'$as'"; |
|
| 941 | - return $order; |
|
| 913 | + $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true); |
|
| 914 | + if (is_array($_champ)) { |
|
| 915 | + return ['zbug_critere_inconnu', ['critere' => $crit->op . " sinum $champ"]]; |
|
| 916 | + } |
|
| 917 | + $boucle = &$boucles[$idb]; |
|
| 918 | + $texte = '0+' . $_champ; |
|
| 919 | + $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent); |
|
| 920 | + if ($suite !== "''") { |
|
| 921 | + $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "'; |
|
| 922 | + } |
|
| 923 | + |
|
| 924 | + $as = false; |
|
| 925 | + $select = "CASE ( $texte ) WHEN 0 THEN 1 ELSE 0 END AS "; |
|
| 926 | + foreach ($boucle->select as $s) { |
|
| 927 | + if (strpos($s, $select) === 0) { |
|
| 928 | + $as = trim(substr($s, strlen($select))); |
|
| 929 | + if (!preg_match(',\W,', $as)) { |
|
| 930 | + break; |
|
| 931 | + } |
|
| 932 | + $as = false; |
|
| 933 | + } |
|
| 934 | + } |
|
| 935 | + |
|
| 936 | + if (!$as) { |
|
| 937 | + $as = 'sinum' . ($boucle->order ? count($boucle->order) : ''); |
|
| 938 | + $boucle->select[] = $select . $as; |
|
| 939 | + } |
|
| 940 | + $order = "'$as'"; |
|
| 941 | + return $order; |
|
| 942 | 942 | } |
| 943 | 943 | |
| 944 | 944 | |
@@ -958,14 +958,14 @@ discard block |
||
| 958 | 958 | * @return string Clause pour le Order by |
| 959 | 959 | */ |
| 960 | 960 | function calculer_critere_par_expression_multi($idb, &$boucles, $crit, $tri, $champ) { |
| 961 | - $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true); |
|
| 962 | - if (is_array($_champ)) { |
|
| 963 | - return ['zbug_critere_inconnu', ['critere' => $crit->op . " multi $champ"]]; |
|
| 964 | - } |
|
| 965 | - $boucle = &$boucles[$idb]; |
|
| 966 | - $boucle->select[] = "\".sql_multi('" . $_champ . "', \$GLOBALS['spip_lang']).\""; |
|
| 967 | - $order = "'multi'"; |
|
| 968 | - return $order; |
|
| 961 | + $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true); |
|
| 962 | + if (is_array($_champ)) { |
|
| 963 | + return ['zbug_critere_inconnu', ['critere' => $crit->op . " multi $champ"]]; |
|
| 964 | + } |
|
| 965 | + $boucle = &$boucles[$idb]; |
|
| 966 | + $boucle->select[] = "\".sql_multi('" . $_champ . "', \$GLOBALS['spip_lang']).\""; |
|
| 967 | + $order = "'multi'"; |
|
| 968 | + return $order; |
|
| 969 | 969 | } |
| 970 | 970 | |
| 971 | 971 | /** |
@@ -984,56 +984,56 @@ discard block |
||
| 984 | 984 | * @return array|string |
| 985 | 985 | */ |
| 986 | 986 | function calculer_critere_par_champ($idb, &$boucles, $crit, $par, $raw = false) { |
| 987 | - $boucle = &$boucles[$idb]; |
|
| 988 | - $desc = $boucle->show; |
|
| 989 | - |
|
| 990 | - // le champ existe dans la table, pas de souci (le plus commun) |
|
| 991 | - if (isset($desc['field'][$par])) { |
|
| 992 | - $par = $boucle->id_table . '.' . $par; |
|
| 993 | - } |
|
| 994 | - // le champ est peut être une jointure |
|
| 995 | - else { |
|
| 996 | - $table = $table_alias = false; // toutes les tables de jointure possibles |
|
| 997 | - $champ = $par; |
|
| 998 | - |
|
| 999 | - // le champ demandé est une exception de jointure {par titre_mot} |
|
| 1000 | - if (isset($GLOBALS['exceptions_des_jointures'][$par])) { |
|
| 1001 | - [$table, $champ] = $GLOBALS['exceptions_des_jointures'][$par]; |
|
| 1002 | - } // la table de jointure est explicitement indiquée {par truc.muche} |
|
| 1003 | - elseif (preg_match('/^([^,]*)\.(.*)$/', $par, $r)) { |
|
| 1004 | - [, $table, $champ] = $r; |
|
| 1005 | - $table_alias = $table; // c'est peut-être un alias de table {par L1.titre} |
|
| 1006 | - $table = table_objet_sql($table); |
|
| 1007 | - } |
|
| 1008 | - |
|
| 1009 | - // Si on connait la table d'arrivée, on la demande donc explicitement |
|
| 1010 | - // Sinon on cherche le champ dans les tables possibles de jointures |
|
| 1011 | - // Si la table est déjà dans le from, on la réutilise. |
|
| 1012 | - if ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $table)) { |
|
| 1013 | - $par = $infos['alias'] . '.' . $champ; |
|
| 1014 | - } elseif ( |
|
| 1015 | - $boucle->jointures_explicites |
|
| 1016 | - and $alias = trouver_jointure_champ($champ, $boucle, explode(' ', $boucle->jointures_explicites), false, $table) |
|
| 1017 | - ) { |
|
| 1018 | - $par = $alias . '.' . $champ; |
|
| 1019 | - } elseif ($alias = trouver_jointure_champ($champ, $boucle, $boucle->jointures, false, $table)) { |
|
| 1020 | - $par = $alias . '.' . $champ; |
|
| 1021 | - // en spécifiant directement l'alias {par L2.titre} (situation hasardeuse tout de même) |
|
| 1022 | - } elseif ( |
|
| 1023 | - $table_alias |
|
| 1024 | - and isset($boucle->from[$table_alias]) |
|
| 1025 | - and $infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $boucle->from[$table_alias]) |
|
| 1026 | - ) { |
|
| 1027 | - $par = $infos['alias'] . '.' . $champ; |
|
| 1028 | - } elseif ($table) { |
|
| 1029 | - // On avait table + champ, mais on ne les a pas trouvés |
|
| 1030 | - return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]]; |
|
| 1031 | - } else { |
|
| 1032 | - // Sinon tant pis, ca doit etre un champ synthetise (cf points) |
|
| 1033 | - } |
|
| 1034 | - } |
|
| 1035 | - |
|
| 1036 | - return $raw ? $par : "'$par'"; |
|
| 987 | + $boucle = &$boucles[$idb]; |
|
| 988 | + $desc = $boucle->show; |
|
| 989 | + |
|
| 990 | + // le champ existe dans la table, pas de souci (le plus commun) |
|
| 991 | + if (isset($desc['field'][$par])) { |
|
| 992 | + $par = $boucle->id_table . '.' . $par; |
|
| 993 | + } |
|
| 994 | + // le champ est peut être une jointure |
|
| 995 | + else { |
|
| 996 | + $table = $table_alias = false; // toutes les tables de jointure possibles |
|
| 997 | + $champ = $par; |
|
| 998 | + |
|
| 999 | + // le champ demandé est une exception de jointure {par titre_mot} |
|
| 1000 | + if (isset($GLOBALS['exceptions_des_jointures'][$par])) { |
|
| 1001 | + [$table, $champ] = $GLOBALS['exceptions_des_jointures'][$par]; |
|
| 1002 | + } // la table de jointure est explicitement indiquée {par truc.muche} |
|
| 1003 | + elseif (preg_match('/^([^,]*)\.(.*)$/', $par, $r)) { |
|
| 1004 | + [, $table, $champ] = $r; |
|
| 1005 | + $table_alias = $table; // c'est peut-être un alias de table {par L1.titre} |
|
| 1006 | + $table = table_objet_sql($table); |
|
| 1007 | + } |
|
| 1008 | + |
|
| 1009 | + // Si on connait la table d'arrivée, on la demande donc explicitement |
|
| 1010 | + // Sinon on cherche le champ dans les tables possibles de jointures |
|
| 1011 | + // Si la table est déjà dans le from, on la réutilise. |
|
| 1012 | + if ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $table)) { |
|
| 1013 | + $par = $infos['alias'] . '.' . $champ; |
|
| 1014 | + } elseif ( |
|
| 1015 | + $boucle->jointures_explicites |
|
| 1016 | + and $alias = trouver_jointure_champ($champ, $boucle, explode(' ', $boucle->jointures_explicites), false, $table) |
|
| 1017 | + ) { |
|
| 1018 | + $par = $alias . '.' . $champ; |
|
| 1019 | + } elseif ($alias = trouver_jointure_champ($champ, $boucle, $boucle->jointures, false, $table)) { |
|
| 1020 | + $par = $alias . '.' . $champ; |
|
| 1021 | + // en spécifiant directement l'alias {par L2.titre} (situation hasardeuse tout de même) |
|
| 1022 | + } elseif ( |
|
| 1023 | + $table_alias |
|
| 1024 | + and isset($boucle->from[$table_alias]) |
|
| 1025 | + and $infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $boucle->from[$table_alias]) |
|
| 1026 | + ) { |
|
| 1027 | + $par = $infos['alias'] . '.' . $champ; |
|
| 1028 | + } elseif ($table) { |
|
| 1029 | + // On avait table + champ, mais on ne les a pas trouvés |
|
| 1030 | + return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]]; |
|
| 1031 | + } else { |
|
| 1032 | + // Sinon tant pis, ca doit etre un champ synthetise (cf points) |
|
| 1033 | + } |
|
| 1034 | + } |
|
| 1035 | + |
|
| 1036 | + return $raw ? $par : "'$par'"; |
|
| 1037 | 1037 | } |
| 1038 | 1038 | |
| 1039 | 1039 | /** |
@@ -1047,11 +1047,11 @@ discard block |
||
| 1047 | 1047 | * @return string Champ pour le compilateur si trouvé, tel que "'alias.champ'", sinon vide. |
| 1048 | 1048 | */ |
| 1049 | 1049 | function critere_par_joint($table, $champ, &$boucle) { |
| 1050 | - $t = array_search($table, $boucle->from); |
|
| 1051 | - if (!$t) { |
|
| 1052 | - $t = trouver_jointure_champ($champ, $boucle); |
|
| 1053 | - } |
|
| 1054 | - return !$t ? '' : ("'" . $t . '.' . $champ . "'"); |
|
| 1050 | + $t = array_search($table, $boucle->from); |
|
| 1051 | + if (!$t) { |
|
| 1052 | + $t = trouver_jointure_champ($champ, $boucle); |
|
| 1053 | + } |
|
| 1054 | + return !$t ? '' : ("'" . $t . '.' . $champ . "'"); |
|
| 1055 | 1055 | } |
| 1056 | 1056 | |
| 1057 | 1057 | /** |
@@ -1076,33 +1076,33 @@ discard block |
||
| 1076 | 1076 | */ |
| 1077 | 1077 | function critere_inverse_dist($idb, &$boucles, $crit) { |
| 1078 | 1078 | |
| 1079 | - $boucle = &$boucles[$idb]; |
|
| 1080 | - // Classement par ordre inverse |
|
| 1081 | - if ($crit->not) { |
|
| 1082 | - critere_parinverse($idb, $boucles, $crit); |
|
| 1083 | - } else { |
|
| 1084 | - $order = "' DESC'"; |
|
| 1085 | - // Classement par ordre inverse fonction eventuelle de #ENV{...} |
|
| 1086 | - if (isset($crit->param[0])) { |
|
| 1087 | - $critere = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 1088 | - $order = "(($critere)?' DESC':'')"; |
|
| 1089 | - } |
|
| 1090 | - |
|
| 1091 | - $n = is_countable($boucle->order) ? count($boucle->order) : 0; |
|
| 1092 | - if (!$n) { |
|
| 1093 | - if (isset($boucle->default_order[0])) { |
|
| 1094 | - $boucle->default_order[0] .= ' . " DESC"'; |
|
| 1095 | - } else { |
|
| 1096 | - $boucle->default_order[] = ' DESC'; |
|
| 1097 | - } |
|
| 1098 | - } else { |
|
| 1099 | - $t = $boucle->order[$n - 1] . " . $order"; |
|
| 1100 | - if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) { |
|
| 1101 | - $t = $r[1] . $r[2]; |
|
| 1102 | - } |
|
| 1103 | - $boucle->order[$n - 1] = $t; |
|
| 1104 | - } |
|
| 1105 | - } |
|
| 1079 | + $boucle = &$boucles[$idb]; |
|
| 1080 | + // Classement par ordre inverse |
|
| 1081 | + if ($crit->not) { |
|
| 1082 | + critere_parinverse($idb, $boucles, $crit); |
|
| 1083 | + } else { |
|
| 1084 | + $order = "' DESC'"; |
|
| 1085 | + // Classement par ordre inverse fonction eventuelle de #ENV{...} |
|
| 1086 | + if (isset($crit->param[0])) { |
|
| 1087 | + $critere = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 1088 | + $order = "(($critere)?' DESC':'')"; |
|
| 1089 | + } |
|
| 1090 | + |
|
| 1091 | + $n = is_countable($boucle->order) ? count($boucle->order) : 0; |
|
| 1092 | + if (!$n) { |
|
| 1093 | + if (isset($boucle->default_order[0])) { |
|
| 1094 | + $boucle->default_order[0] .= ' . " DESC"'; |
|
| 1095 | + } else { |
|
| 1096 | + $boucle->default_order[] = ' DESC'; |
|
| 1097 | + } |
|
| 1098 | + } else { |
|
| 1099 | + $t = $boucle->order[$n - 1] . " . $order"; |
|
| 1100 | + if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) { |
|
| 1101 | + $t = $r[1] . $r[2]; |
|
| 1102 | + } |
|
| 1103 | + $boucle->order[$n - 1] = $t; |
|
| 1104 | + } |
|
| 1105 | + } |
|
| 1106 | 1106 | } |
| 1107 | 1107 | |
| 1108 | 1108 | /** |
@@ -1113,137 +1113,137 @@ discard block |
||
| 1113 | 1113 | * @return array|string |
| 1114 | 1114 | */ |
| 1115 | 1115 | function critere_par_ordre_liste_dist($idb, &$boucles, $crit) { |
| 1116 | - $boucle = &$boucles[$idb]; |
|
| 1116 | + $boucle = &$boucles[$idb]; |
|
| 1117 | 1117 | |
| 1118 | - $sens = $collecte = ''; |
|
| 1119 | - if ($crit->not) { |
|
| 1120 | - $sens = " . ' DESC'"; |
|
| 1121 | - } |
|
| 1118 | + $sens = $collecte = ''; |
|
| 1119 | + if ($crit->not) { |
|
| 1120 | + $sens = " . ' DESC'"; |
|
| 1121 | + } |
|
| 1122 | 1122 | |
| 1123 | - $crit2 = clone $crit; |
|
| 1124 | - $crit2->not = false; |
|
| 1125 | - $crit2->param = [reset($crit->param)]; |
|
| 1126 | - $res = critere_parinverse($idb, $boucles, $crit2); |
|
| 1123 | + $crit2 = clone $crit; |
|
| 1124 | + $crit2->not = false; |
|
| 1125 | + $crit2->param = [reset($crit->param)]; |
|
| 1126 | + $res = critere_parinverse($idb, $boucles, $crit2); |
|
| 1127 | 1127 | |
| 1128 | - // erreur ? |
|
| 1129 | - if (is_array($res)) { |
|
| 1130 | - return $res; |
|
| 1131 | - } |
|
| 1128 | + // erreur ? |
|
| 1129 | + if (is_array($res)) { |
|
| 1130 | + return $res; |
|
| 1131 | + } |
|
| 1132 | 1132 | |
| 1133 | - $_order = array_pop($boucle->order); |
|
| 1133 | + $_order = array_pop($boucle->order); |
|
| 1134 | 1134 | |
| 1135 | - $_liste = calculer_liste($crit->param[1], [], $boucles, $boucles[$idb]->id_parent); |
|
| 1136 | - $boucle->order[] = "'FIELD(' . $_order . ',' . ((\$zl=formate_liste_critere_par_ordre_liste($_liste,'" . $boucle->sql_serveur . "')) ? \$zl : '0').')'$sens"; |
|
| 1135 | + $_liste = calculer_liste($crit->param[1], [], $boucles, $boucles[$idb]->id_parent); |
|
| 1136 | + $boucle->order[] = "'FIELD(' . $_order . ',' . ((\$zl=formate_liste_critere_par_ordre_liste($_liste,'" . $boucle->sql_serveur . "')) ? \$zl : '0').')'$sens"; |
|
| 1137 | 1137 | } |
| 1138 | 1138 | |
| 1139 | 1139 | |
| 1140 | 1140 | function critere_agenda_dist($idb, &$boucles, $crit) { |
| 1141 | - $params = $crit->param; |
|
| 1142 | - |
|
| 1143 | - if ((is_countable($params) ? count($params) : 0) < 1) { |
|
| 1144 | - return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']]; |
|
| 1145 | - } |
|
| 1146 | - |
|
| 1147 | - $boucle = &$boucles[$idb]; |
|
| 1148 | - $parent = $boucle->id_parent; |
|
| 1149 | - $fields = $boucle->show['field']; |
|
| 1150 | - |
|
| 1151 | - $date = array_shift($params); |
|
| 1152 | - $type = array_shift($params); |
|
| 1153 | - |
|
| 1154 | - // la valeur $type doit etre connue a la compilation |
|
| 1155 | - // donc etre forcement reduite a un litteral unique dans le source |
|
| 1156 | - $type = is_object($type[0]) ? $type[0]->texte : null; |
|
| 1157 | - |
|
| 1158 | - // La valeur date doit designer un champ de la table SQL. |
|
| 1159 | - // Si c'est un litteral unique dans le source, verifier a la compil, |
|
| 1160 | - // sinon synthetiser le test de verif pour execution ulterieure |
|
| 1161 | - // On prendra arbitrairement le premier champ si test negatif. |
|
| 1162 | - if (((is_countable($date) ? count($date) : 0) == 1) and ($date[0]->type == 'texte')) { |
|
| 1163 | - $date = $date[0]->texte; |
|
| 1164 | - if (!isset($fields[$date])) { |
|
| 1165 | - return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $date]]; |
|
| 1166 | - } |
|
| 1167 | - } else { |
|
| 1168 | - $a = calculer_liste($date, $idb, $boucles, $parent); |
|
| 1169 | - $noms = array_keys($fields); |
|
| 1170 | - $defaut = $noms[0]; |
|
| 1171 | - $noms = join(' ', $noms); |
|
| 1172 | - # bien laisser 2 espaces avant $nom pour que strpos<>0 |
|
| 1173 | - $cond = "(\$a=strval($a))AND\nstrpos(\" $noms \",\" \$a \")"; |
|
| 1174 | - $date = "'.(($cond)\n?\$a:\"$defaut\").'"; |
|
| 1175 | - } |
|
| 1176 | - $annee = $params ? array_shift($params) : ''; |
|
| 1177 | - $annee = "\n" . 'sprintf("%04d", ($x = ' . |
|
| 1178 | - calculer_liste($annee, $idb, $boucles, $parent) . |
|
| 1179 | - ') ? $x : date("Y"))'; |
|
| 1180 | - |
|
| 1181 | - $mois = $params ? array_shift($params) : ''; |
|
| 1182 | - $mois = "\n" . 'sprintf("%02d", ($x = ' . |
|
| 1183 | - calculer_liste($mois, $idb, $boucles, $parent) . |
|
| 1184 | - ') ? $x : date("m"))'; |
|
| 1185 | - |
|
| 1186 | - $jour = $params ? array_shift($params) : ''; |
|
| 1187 | - $jour = "\n" . 'sprintf("%02d", ($x = ' . |
|
| 1188 | - calculer_liste($jour, $idb, $boucles, $parent) . |
|
| 1189 | - ') ? $x : date("d"))'; |
|
| 1190 | - |
|
| 1191 | - $annee2 = $params ? array_shift($params) : ''; |
|
| 1192 | - $annee2 = "\n" . 'sprintf("%04d", ($x = ' . |
|
| 1193 | - calculer_liste($annee2, $idb, $boucles, $parent) . |
|
| 1194 | - ') ? $x : date("Y"))'; |
|
| 1195 | - |
|
| 1196 | - $mois2 = $params ? array_shift($params) : ''; |
|
| 1197 | - $mois2 = "\n" . 'sprintf("%02d", ($x = ' . |
|
| 1198 | - calculer_liste($mois2, $idb, $boucles, $parent) . |
|
| 1199 | - ') ? $x : date("m"))'; |
|
| 1200 | - |
|
| 1201 | - $jour2 = $params ? array_shift($params) : ''; |
|
| 1202 | - $jour2 = "\n" . 'sprintf("%02d", ($x = ' . |
|
| 1203 | - calculer_liste($jour2, $idb, $boucles, $parent) . |
|
| 1204 | - ') ? $x : date("d"))'; |
|
| 1205 | - |
|
| 1206 | - $date = $boucle->id_table . ".$date"; |
|
| 1207 | - |
|
| 1208 | - $quote_end = ",'" . $boucle->sql_serveur . "','text'"; |
|
| 1209 | - if ($type == 'jour') { |
|
| 1210 | - $boucle->where[] = [ |
|
| 1211 | - "'='", |
|
| 1212 | - "'DATE_FORMAT($date, \'%Y%m%d\')'", |
|
| 1213 | - ("sql_quote($annee . $mois . $jour$quote_end)") |
|
| 1214 | - ]; |
|
| 1215 | - } elseif ($type == 'mois') { |
|
| 1216 | - $boucle->where[] = [ |
|
| 1217 | - "'='", |
|
| 1218 | - "'DATE_FORMAT($date, \'%Y%m\')'", |
|
| 1219 | - ("sql_quote($annee . $mois$quote_end)") |
|
| 1220 | - ]; |
|
| 1221 | - } elseif ($type == 'semaine') { |
|
| 1222 | - $boucle->where[] = [ |
|
| 1223 | - "'AND'", |
|
| 1224 | - [ |
|
| 1225 | - "'>='", |
|
| 1226 | - "'DATE_FORMAT($date, \'%Y%m%d\')'", |
|
| 1227 | - ("date_debut_semaine($annee, $mois, $jour)") |
|
| 1228 | - ], |
|
| 1229 | - [ |
|
| 1230 | - "'<='", |
|
| 1231 | - "'DATE_FORMAT($date, \'%Y%m%d\')'", |
|
| 1232 | - ("date_fin_semaine($annee, $mois, $jour)") |
|
| 1233 | - ] |
|
| 1234 | - ]; |
|
| 1235 | - } elseif ((is_countable($crit->param) ? count($crit->param) : 0) > 2) { |
|
| 1236 | - $boucle->where[] = [ |
|
| 1237 | - "'AND'", |
|
| 1238 | - [ |
|
| 1239 | - "'>='", |
|
| 1240 | - "'DATE_FORMAT($date, \'%Y%m%d\')'", |
|
| 1241 | - ("sql_quote($annee . $mois . $jour$quote_end)") |
|
| 1242 | - ], |
|
| 1243 | - ["'<='", "'DATE_FORMAT($date, \'%Y%m%d\')'", ("sql_quote($annee2 . $mois2 . $jour2$quote_end)")] |
|
| 1244 | - ]; |
|
| 1245 | - } |
|
| 1246 | - // sinon on prend tout |
|
| 1141 | + $params = $crit->param; |
|
| 1142 | + |
|
| 1143 | + if ((is_countable($params) ? count($params) : 0) < 1) { |
|
| 1144 | + return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']]; |
|
| 1145 | + } |
|
| 1146 | + |
|
| 1147 | + $boucle = &$boucles[$idb]; |
|
| 1148 | + $parent = $boucle->id_parent; |
|
| 1149 | + $fields = $boucle->show['field']; |
|
| 1150 | + |
|
| 1151 | + $date = array_shift($params); |
|
| 1152 | + $type = array_shift($params); |
|
| 1153 | + |
|
| 1154 | + // la valeur $type doit etre connue a la compilation |
|
| 1155 | + // donc etre forcement reduite a un litteral unique dans le source |
|
| 1156 | + $type = is_object($type[0]) ? $type[0]->texte : null; |
|
| 1157 | + |
|
| 1158 | + // La valeur date doit designer un champ de la table SQL. |
|
| 1159 | + // Si c'est un litteral unique dans le source, verifier a la compil, |
|
| 1160 | + // sinon synthetiser le test de verif pour execution ulterieure |
|
| 1161 | + // On prendra arbitrairement le premier champ si test negatif. |
|
| 1162 | + if (((is_countable($date) ? count($date) : 0) == 1) and ($date[0]->type == 'texte')) { |
|
| 1163 | + $date = $date[0]->texte; |
|
| 1164 | + if (!isset($fields[$date])) { |
|
| 1165 | + return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $date]]; |
|
| 1166 | + } |
|
| 1167 | + } else { |
|
| 1168 | + $a = calculer_liste($date, $idb, $boucles, $parent); |
|
| 1169 | + $noms = array_keys($fields); |
|
| 1170 | + $defaut = $noms[0]; |
|
| 1171 | + $noms = join(' ', $noms); |
|
| 1172 | + # bien laisser 2 espaces avant $nom pour que strpos<>0 |
|
| 1173 | + $cond = "(\$a=strval($a))AND\nstrpos(\" $noms \",\" \$a \")"; |
|
| 1174 | + $date = "'.(($cond)\n?\$a:\"$defaut\").'"; |
|
| 1175 | + } |
|
| 1176 | + $annee = $params ? array_shift($params) : ''; |
|
| 1177 | + $annee = "\n" . 'sprintf("%04d", ($x = ' . |
|
| 1178 | + calculer_liste($annee, $idb, $boucles, $parent) . |
|
| 1179 | + ') ? $x : date("Y"))'; |
|
| 1180 | + |
|
| 1181 | + $mois = $params ? array_shift($params) : ''; |
|
| 1182 | + $mois = "\n" . 'sprintf("%02d", ($x = ' . |
|
| 1183 | + calculer_liste($mois, $idb, $boucles, $parent) . |
|
| 1184 | + ') ? $x : date("m"))'; |
|
| 1185 | + |
|
| 1186 | + $jour = $params ? array_shift($params) : ''; |
|
| 1187 | + $jour = "\n" . 'sprintf("%02d", ($x = ' . |
|
| 1188 | + calculer_liste($jour, $idb, $boucles, $parent) . |
|
| 1189 | + ') ? $x : date("d"))'; |
|
| 1190 | + |
|
| 1191 | + $annee2 = $params ? array_shift($params) : ''; |
|
| 1192 | + $annee2 = "\n" . 'sprintf("%04d", ($x = ' . |
|
| 1193 | + calculer_liste($annee2, $idb, $boucles, $parent) . |
|
| 1194 | + ') ? $x : date("Y"))'; |
|
| 1195 | + |
|
| 1196 | + $mois2 = $params ? array_shift($params) : ''; |
|
| 1197 | + $mois2 = "\n" . 'sprintf("%02d", ($x = ' . |
|
| 1198 | + calculer_liste($mois2, $idb, $boucles, $parent) . |
|
| 1199 | + ') ? $x : date("m"))'; |
|
| 1200 | + |
|
| 1201 | + $jour2 = $params ? array_shift($params) : ''; |
|
| 1202 | + $jour2 = "\n" . 'sprintf("%02d", ($x = ' . |
|
| 1203 | + calculer_liste($jour2, $idb, $boucles, $parent) . |
|
| 1204 | + ') ? $x : date("d"))'; |
|
| 1205 | + |
|
| 1206 | + $date = $boucle->id_table . ".$date"; |
|
| 1207 | + |
|
| 1208 | + $quote_end = ",'" . $boucle->sql_serveur . "','text'"; |
|
| 1209 | + if ($type == 'jour') { |
|
| 1210 | + $boucle->where[] = [ |
|
| 1211 | + "'='", |
|
| 1212 | + "'DATE_FORMAT($date, \'%Y%m%d\')'", |
|
| 1213 | + ("sql_quote($annee . $mois . $jour$quote_end)") |
|
| 1214 | + ]; |
|
| 1215 | + } elseif ($type == 'mois') { |
|
| 1216 | + $boucle->where[] = [ |
|
| 1217 | + "'='", |
|
| 1218 | + "'DATE_FORMAT($date, \'%Y%m\')'", |
|
| 1219 | + ("sql_quote($annee . $mois$quote_end)") |
|
| 1220 | + ]; |
|
| 1221 | + } elseif ($type == 'semaine') { |
|
| 1222 | + $boucle->where[] = [ |
|
| 1223 | + "'AND'", |
|
| 1224 | + [ |
|
| 1225 | + "'>='", |
|
| 1226 | + "'DATE_FORMAT($date, \'%Y%m%d\')'", |
|
| 1227 | + ("date_debut_semaine($annee, $mois, $jour)") |
|
| 1228 | + ], |
|
| 1229 | + [ |
|
| 1230 | + "'<='", |
|
| 1231 | + "'DATE_FORMAT($date, \'%Y%m%d\')'", |
|
| 1232 | + ("date_fin_semaine($annee, $mois, $jour)") |
|
| 1233 | + ] |
|
| 1234 | + ]; |
|
| 1235 | + } elseif ((is_countable($crit->param) ? count($crit->param) : 0) > 2) { |
|
| 1236 | + $boucle->where[] = [ |
|
| 1237 | + "'AND'", |
|
| 1238 | + [ |
|
| 1239 | + "'>='", |
|
| 1240 | + "'DATE_FORMAT($date, \'%Y%m%d\')'", |
|
| 1241 | + ("sql_quote($annee . $mois . $jour$quote_end)") |
|
| 1242 | + ], |
|
| 1243 | + ["'<='", "'DATE_FORMAT($date, \'%Y%m%d\')'", ("sql_quote($annee2 . $mois2 . $jour2$quote_end)")] |
|
| 1244 | + ]; |
|
| 1245 | + } |
|
| 1246 | + // sinon on prend tout |
|
| 1247 | 1247 | } |
| 1248 | 1248 | |
| 1249 | 1249 | |
@@ -1268,33 +1268,33 @@ discard block |
||
| 1268 | 1268 | * @return void |
| 1269 | 1269 | **/ |
| 1270 | 1270 | function calculer_critere_parties($idb, &$boucles, $crit) { |
| 1271 | - $boucle = &$boucles[$idb]; |
|
| 1272 | - $a1 = $crit->param[0]; |
|
| 1273 | - $a2 = $crit->param[1]; |
|
| 1274 | - $op = $crit->op; |
|
| 1275 | - |
|
| 1276 | - [$a11, $a12] = calculer_critere_parties_aux($idb, $boucles, $a1); |
|
| 1277 | - [$a21, $a22] = calculer_critere_parties_aux($idb, $boucles, $a2); |
|
| 1278 | - |
|
| 1279 | - if (($op == ',') && (is_numeric($a11) && (is_numeric($a21)))) { |
|
| 1280 | - $boucle->limit = $a11 . ',' . $a21; |
|
| 1281 | - } else { |
|
| 1282 | - // 3 dans {1/3}, {2,3} ou {1,n-3} |
|
| 1283 | - $boucle->total_parties = ($a21 != 'n') ? $a21 : $a22; |
|
| 1284 | - // 2 dans {2/3}, {2,5}, {n-2,1} |
|
| 1285 | - $partie = ($a11 != 'n') ? $a11 : $a12; |
|
| 1286 | - $mode = (($op == '/') ? '/' : |
|
| 1287 | - (($a11 == 'n') ? '-' : '+') . (($a21 == 'n') ? '-' : '+')); |
|
| 1288 | - // cas simple {0,#ENV{truc}} compilons le en LIMIT : |
|
| 1289 | - if ($a11 !== 'n' and $a21 !== 'n' and $mode == '++' and $op == ',') { |
|
| 1290 | - $boucle->limit = |
|
| 1291 | - (is_numeric($a11) ? "'$a11'" : $a11) |
|
| 1292 | - . ".','." |
|
| 1293 | - . (is_numeric($a21) ? "'$a21'" : $a21); |
|
| 1294 | - } else { |
|
| 1295 | - calculer_parties($boucles, $idb, $partie, $mode); |
|
| 1296 | - } |
|
| 1297 | - } |
|
| 1271 | + $boucle = &$boucles[$idb]; |
|
| 1272 | + $a1 = $crit->param[0]; |
|
| 1273 | + $a2 = $crit->param[1]; |
|
| 1274 | + $op = $crit->op; |
|
| 1275 | + |
|
| 1276 | + [$a11, $a12] = calculer_critere_parties_aux($idb, $boucles, $a1); |
|
| 1277 | + [$a21, $a22] = calculer_critere_parties_aux($idb, $boucles, $a2); |
|
| 1278 | + |
|
| 1279 | + if (($op == ',') && (is_numeric($a11) && (is_numeric($a21)))) { |
|
| 1280 | + $boucle->limit = $a11 . ',' . $a21; |
|
| 1281 | + } else { |
|
| 1282 | + // 3 dans {1/3}, {2,3} ou {1,n-3} |
|
| 1283 | + $boucle->total_parties = ($a21 != 'n') ? $a21 : $a22; |
|
| 1284 | + // 2 dans {2/3}, {2,5}, {n-2,1} |
|
| 1285 | + $partie = ($a11 != 'n') ? $a11 : $a12; |
|
| 1286 | + $mode = (($op == '/') ? '/' : |
|
| 1287 | + (($a11 == 'n') ? '-' : '+') . (($a21 == 'n') ? '-' : '+')); |
|
| 1288 | + // cas simple {0,#ENV{truc}} compilons le en LIMIT : |
|
| 1289 | + if ($a11 !== 'n' and $a21 !== 'n' and $mode == '++' and $op == ',') { |
|
| 1290 | + $boucle->limit = |
|
| 1291 | + (is_numeric($a11) ? "'$a11'" : $a11) |
|
| 1292 | + . ".','." |
|
| 1293 | + . (is_numeric($a21) ? "'$a21'" : $a21); |
|
| 1294 | + } else { |
|
| 1295 | + calculer_parties($boucles, $idb, $partie, $mode); |
|
| 1296 | + } |
|
| 1297 | + } |
|
| 1298 | 1298 | } |
| 1299 | 1299 | |
| 1300 | 1300 | /** |
@@ -1322,63 +1322,63 @@ discard block |
||
| 1322 | 1322 | * @return void |
| 1323 | 1323 | **/ |
| 1324 | 1324 | function calculer_parties(&$boucles, $id_boucle, $debut, $mode) { |
| 1325 | - $total_parties = $boucles[$id_boucle]->total_parties; |
|
| 1326 | - |
|
| 1327 | - preg_match(',([+-/p])([+-/])?,', $mode, $regs); |
|
| 1328 | - [, $op1, $op2] = array_pad($regs, 3, null); |
|
| 1329 | - $nombre_boucle = "\$Numrows['$id_boucle']['total']"; |
|
| 1330 | - // {1/3} |
|
| 1331 | - if ($op1 == '/') { |
|
| 1332 | - $pmoins1 = is_numeric($debut) ? ($debut - 1) : "($debut-1)"; |
|
| 1333 | - $totpos = is_numeric($total_parties) ? ($total_parties) : |
|
| 1334 | - "($total_parties ? $total_parties : 1)"; |
|
| 1335 | - $fin = "ceil(($nombre_boucle * $debut )/$totpos) - 1"; |
|
| 1336 | - $debut = !$pmoins1 ? 0 : "ceil(($nombre_boucle * $pmoins1)/$totpos);"; |
|
| 1337 | - } else { |
|
| 1338 | - // cas {n-1,x} |
|
| 1339 | - if ($op1 == '-') { |
|
| 1340 | - $debut = "$nombre_boucle - $debut;"; |
|
| 1341 | - } |
|
| 1342 | - |
|
| 1343 | - // cas {x,n-1} |
|
| 1344 | - if ($op2 == '-') { |
|
| 1345 | - $fin = '$debut_boucle + ' . $nombre_boucle . ' - ' |
|
| 1346 | - . (is_numeric($total_parties) ? ($total_parties + 1) : |
|
| 1347 | - ($total_parties . ' - 1')); |
|
| 1348 | - } else { |
|
| 1349 | - // {x,1} ou {pagination} |
|
| 1350 | - $fin = '$debut_boucle' |
|
| 1351 | - . (is_numeric($total_parties) ? |
|
| 1352 | - (($total_parties == 1) ? '' : (' + ' . ($total_parties - 1))) : |
|
| 1353 | - ('+' . $total_parties . ' - 1')); |
|
| 1354 | - } |
|
| 1355 | - |
|
| 1356 | - // {pagination}, gerer le debut_xx=-1 pour tout voir |
|
| 1357 | - if ($op1 == 'p') { |
|
| 1358 | - $debut .= ";\n \$debut_boucle = ((\$tout=(\$debut_boucle == -1))?0:(\$debut_boucle))"; |
|
| 1359 | - $debut .= ";\n \$debut_boucle = max(0,min(\$debut_boucle,floor(($nombre_boucle-1)/($total_parties))*($total_parties)))"; |
|
| 1360 | - $fin = "(\$tout ? $nombre_boucle : $fin)"; |
|
| 1361 | - } |
|
| 1362 | - } |
|
| 1363 | - |
|
| 1364 | - // Notes : |
|
| 1365 | - // $debut_boucle et $fin_boucle sont les indices SQL du premier |
|
| 1366 | - // et du dernier demandes dans la boucle : 0 pour le premier, |
|
| 1367 | - // n-1 pour le dernier ; donc total_boucle = 1 + debut - fin |
|
| 1368 | - // Utiliser min pour rabattre $fin_boucle sur total_boucle. |
|
| 1369 | - |
|
| 1370 | - $boucles[$id_boucle]->mode_partie = "\n\t" |
|
| 1371 | - . '$debut_boucle = ' . $debut . ";\n " |
|
| 1372 | - . "\$debut_boucle = intval(\$debut_boucle);\n " |
|
| 1373 | - . '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n " |
|
| 1374 | - . '$Numrows[\'' . $id_boucle . "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n " |
|
| 1375 | - . '$Numrows[\'' . $id_boucle . '\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);' |
|
| 1376 | - . "\n\tif (\$debut_boucle>0" |
|
| 1377 | - . " AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total']" |
|
| 1378 | - . " AND \$iter->seek(\$debut_boucle,'continue'))" |
|
| 1379 | - . "\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t"; |
|
| 1380 | - |
|
| 1381 | - $boucles[$id_boucle]->partie = " |
|
| 1325 | + $total_parties = $boucles[$id_boucle]->total_parties; |
|
| 1326 | + |
|
| 1327 | + preg_match(',([+-/p])([+-/])?,', $mode, $regs); |
|
| 1328 | + [, $op1, $op2] = array_pad($regs, 3, null); |
|
| 1329 | + $nombre_boucle = "\$Numrows['$id_boucle']['total']"; |
|
| 1330 | + // {1/3} |
|
| 1331 | + if ($op1 == '/') { |
|
| 1332 | + $pmoins1 = is_numeric($debut) ? ($debut - 1) : "($debut-1)"; |
|
| 1333 | + $totpos = is_numeric($total_parties) ? ($total_parties) : |
|
| 1334 | + "($total_parties ? $total_parties : 1)"; |
|
| 1335 | + $fin = "ceil(($nombre_boucle * $debut )/$totpos) - 1"; |
|
| 1336 | + $debut = !$pmoins1 ? 0 : "ceil(($nombre_boucle * $pmoins1)/$totpos);"; |
|
| 1337 | + } else { |
|
| 1338 | + // cas {n-1,x} |
|
| 1339 | + if ($op1 == '-') { |
|
| 1340 | + $debut = "$nombre_boucle - $debut;"; |
|
| 1341 | + } |
|
| 1342 | + |
|
| 1343 | + // cas {x,n-1} |
|
| 1344 | + if ($op2 == '-') { |
|
| 1345 | + $fin = '$debut_boucle + ' . $nombre_boucle . ' - ' |
|
| 1346 | + . (is_numeric($total_parties) ? ($total_parties + 1) : |
|
| 1347 | + ($total_parties . ' - 1')); |
|
| 1348 | + } else { |
|
| 1349 | + // {x,1} ou {pagination} |
|
| 1350 | + $fin = '$debut_boucle' |
|
| 1351 | + . (is_numeric($total_parties) ? |
|
| 1352 | + (($total_parties == 1) ? '' : (' + ' . ($total_parties - 1))) : |
|
| 1353 | + ('+' . $total_parties . ' - 1')); |
|
| 1354 | + } |
|
| 1355 | + |
|
| 1356 | + // {pagination}, gerer le debut_xx=-1 pour tout voir |
|
| 1357 | + if ($op1 == 'p') { |
|
| 1358 | + $debut .= ";\n \$debut_boucle = ((\$tout=(\$debut_boucle == -1))?0:(\$debut_boucle))"; |
|
| 1359 | + $debut .= ";\n \$debut_boucle = max(0,min(\$debut_boucle,floor(($nombre_boucle-1)/($total_parties))*($total_parties)))"; |
|
| 1360 | + $fin = "(\$tout ? $nombre_boucle : $fin)"; |
|
| 1361 | + } |
|
| 1362 | + } |
|
| 1363 | + |
|
| 1364 | + // Notes : |
|
| 1365 | + // $debut_boucle et $fin_boucle sont les indices SQL du premier |
|
| 1366 | + // et du dernier demandes dans la boucle : 0 pour le premier, |
|
| 1367 | + // n-1 pour le dernier ; donc total_boucle = 1 + debut - fin |
|
| 1368 | + // Utiliser min pour rabattre $fin_boucle sur total_boucle. |
|
| 1369 | + |
|
| 1370 | + $boucles[$id_boucle]->mode_partie = "\n\t" |
|
| 1371 | + . '$debut_boucle = ' . $debut . ";\n " |
|
| 1372 | + . "\$debut_boucle = intval(\$debut_boucle);\n " |
|
| 1373 | + . '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n " |
|
| 1374 | + . '$Numrows[\'' . $id_boucle . "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n " |
|
| 1375 | + . '$Numrows[\'' . $id_boucle . '\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);' |
|
| 1376 | + . "\n\tif (\$debut_boucle>0" |
|
| 1377 | + . " AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total']" |
|
| 1378 | + . " AND \$iter->seek(\$debut_boucle,'continue'))" |
|
| 1379 | + . "\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t"; |
|
| 1380 | + |
|
| 1381 | + $boucles[$id_boucle]->partie = " |
|
| 1382 | 1382 | if (\$Numrows['$id_boucle']['compteur_boucle'] <= \$debut_boucle) continue; |
| 1383 | 1383 | if (\$Numrows['$id_boucle']['compteur_boucle']-1 > \$fin_boucle) break;"; |
| 1384 | 1384 | } |
@@ -1395,26 +1395,26 @@ discard block |
||
| 1395 | 1395 | * @return array Valeur de l'élément (peut être une expression PHP), Nombre soustrait |
| 1396 | 1396 | **/ |
| 1397 | 1397 | function calculer_critere_parties_aux($idb, &$boucles, $param) { |
| 1398 | - if ($param[0]->type != 'texte') { |
|
| 1399 | - $a1 = calculer_liste([$param[0]], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 1400 | - if (isset($param[1]->texte)) { |
|
| 1401 | - preg_match(',^ *(-([0-9]+))? *$,', $param[1]->texte, $m); |
|
| 1402 | - |
|
| 1403 | - return ["intval($a1)", ((isset($m[2]) and $m[2]) ? $m[2] : 0)]; |
|
| 1404 | - } else { |
|
| 1405 | - return ["intval($a1)", 0]; |
|
| 1406 | - } |
|
| 1407 | - } else { |
|
| 1408 | - preg_match(',^ *(([0-9]+)|n) *(- *([0-9]+)? *)?$,', $param[0]->texte, $m); |
|
| 1409 | - $a1 = $m[1]; |
|
| 1410 | - if (empty($m[3])) { |
|
| 1411 | - return [$a1, 0]; |
|
| 1412 | - } elseif (!empty($m[4])) { |
|
| 1413 | - return [$a1, $m[4]]; |
|
| 1414 | - } else { |
|
| 1415 | - return [$a1, calculer_liste([$param[1]], $idb, $boucles, $boucles[$idb]->id_parent)]; |
|
| 1416 | - } |
|
| 1417 | - } |
|
| 1398 | + if ($param[0]->type != 'texte') { |
|
| 1399 | + $a1 = calculer_liste([$param[0]], $idb, $boucles, $boucles[$idb]->id_parent); |
|
| 1400 | + if (isset($param[1]->texte)) { |
|
| 1401 | + preg_match(',^ *(-([0-9]+))? *$,', $param[1]->texte, $m); |
|
| 1402 | + |
|
| 1403 | + return ["intval($a1)", ((isset($m[2]) and $m[2]) ? $m[2] : 0)]; |
|
| 1404 | + } else { |
|
| 1405 | + return ["intval($a1)", 0]; |
|
| 1406 | + } |
|
| 1407 | + } else { |
|
| 1408 | + preg_match(',^ *(([0-9]+)|n) *(- *([0-9]+)? *)?$,', $param[0]->texte, $m); |
|
| 1409 | + $a1 = $m[1]; |
|
| 1410 | + if (empty($m[3])) { |
|
| 1411 | + return [$a1, 0]; |
|
| 1412 | + } elseif (!empty($m[4])) { |
|
| 1413 | + return [$a1, $m[4]]; |
|
| 1414 | + } else { |
|
| 1415 | + return [$a1, calculer_liste([$param[1]], $idb, $boucles, $boucles[$idb]->id_parent)]; |
|
| 1416 | + } |
|
| 1417 | + } |
|
| 1418 | 1418 | } |
| 1419 | 1419 | |
| 1420 | 1420 | |
@@ -1441,47 +1441,47 @@ discard block |
||
| 1441 | 1441 | * array : Erreur sur un des critères |
| 1442 | 1442 | **/ |
| 1443 | 1443 | function calculer_criteres($idb, &$boucles) { |
| 1444 | - $msg = ''; |
|
| 1445 | - $boucle = $boucles[$idb]; |
|
| 1446 | - $table = strtoupper($boucle->type_requete); |
|
| 1447 | - $serveur = strtolower($boucle->sql_serveur); |
|
| 1448 | - |
|
| 1449 | - $defaut = charger_fonction('DEFAUT', 'calculer_critere'); |
|
| 1450 | - // s'il y avait une erreur de syntaxe, propager cette info |
|
| 1451 | - if (!is_array($boucle->criteres)) { |
|
| 1452 | - return []; |
|
| 1453 | - } |
|
| 1454 | - |
|
| 1455 | - foreach ($boucle->criteres as $crit) { |
|
| 1456 | - $critere = $crit->op; |
|
| 1457 | - // critere personnalise ? |
|
| 1458 | - if ( |
|
| 1459 | - (!$serveur or |
|
| 1460 | - ((!function_exists($f = 'critere_' . $serveur . '_' . $table . '_' . $critere)) |
|
| 1461 | - and (!function_exists($f = $f . '_dist')) |
|
| 1462 | - and (!function_exists($f = 'critere_' . $serveur . '_' . $critere)) |
|
| 1463 | - and (!function_exists($f = $f . '_dist')) |
|
| 1464 | - ) |
|
| 1465 | - ) |
|
| 1466 | - and (!function_exists($f = 'critere_' . $table . '_' . $critere)) |
|
| 1467 | - and (!function_exists($f = $f . '_dist')) |
|
| 1468 | - and (!function_exists($f = 'critere_' . $critere)) |
|
| 1469 | - and (!function_exists($f = $f . '_dist')) |
|
| 1470 | - ) { |
|
| 1471 | - // fonction critere standard |
|
| 1472 | - $f = $defaut; |
|
| 1473 | - } |
|
| 1474 | - // compile le critere |
|
| 1475 | - $res = $f($idb, $boucles, $crit); |
|
| 1476 | - |
|
| 1477 | - // Gestion centralisee des erreurs pour pouvoir propager |
|
| 1478 | - if (is_array($res)) { |
|
| 1479 | - $msg = $res; |
|
| 1480 | - erreur_squelette($msg, $boucle); |
|
| 1481 | - } |
|
| 1482 | - } |
|
| 1483 | - |
|
| 1484 | - return $msg; |
|
| 1444 | + $msg = ''; |
|
| 1445 | + $boucle = $boucles[$idb]; |
|
| 1446 | + $table = strtoupper($boucle->type_requete); |
|
| 1447 | + $serveur = strtolower($boucle->sql_serveur); |
|
| 1448 | + |
|
| 1449 | + $defaut = charger_fonction('DEFAUT', 'calculer_critere'); |
|
| 1450 | + // s'il y avait une erreur de syntaxe, propager cette info |
|
| 1451 | + if (!is_array($boucle->criteres)) { |
|
| 1452 | + return []; |
|
| 1453 | + } |
|
| 1454 | + |
|
| 1455 | + foreach ($boucle->criteres as $crit) { |
|
| 1456 | + $critere = $crit->op; |
|
| 1457 | + // critere personnalise ? |
|
| 1458 | + if ( |
|
| 1459 | + (!$serveur or |
|
| 1460 | + ((!function_exists($f = 'critere_' . $serveur . '_' . $table . '_' . $critere)) |
|
| 1461 | + and (!function_exists($f = $f . '_dist')) |
|
| 1462 | + and (!function_exists($f = 'critere_' . $serveur . '_' . $critere)) |
|
| 1463 | + and (!function_exists($f = $f . '_dist')) |
|
| 1464 | + ) |
|
| 1465 | + ) |
|
| 1466 | + and (!function_exists($f = 'critere_' . $table . '_' . $critere)) |
|
| 1467 | + and (!function_exists($f = $f . '_dist')) |
|
| 1468 | + and (!function_exists($f = 'critere_' . $critere)) |
|
| 1469 | + and (!function_exists($f = $f . '_dist')) |
|
| 1470 | + ) { |
|
| 1471 | + // fonction critere standard |
|
| 1472 | + $f = $defaut; |
|
| 1473 | + } |
|
| 1474 | + // compile le critere |
|
| 1475 | + $res = $f($idb, $boucles, $crit); |
|
| 1476 | + |
|
| 1477 | + // Gestion centralisee des erreurs pour pouvoir propager |
|
| 1478 | + if (is_array($res)) { |
|
| 1479 | + $msg = $res; |
|
| 1480 | + erreur_squelette($msg, $boucle); |
|
| 1481 | + } |
|
| 1482 | + } |
|
| 1483 | + |
|
| 1484 | + return $msg; |
|
| 1485 | 1485 | } |
| 1486 | 1486 | |
| 1487 | 1487 | /** |
@@ -1496,11 +1496,11 @@ discard block |
||
| 1496 | 1496 | * @return string Code compilé rééchappé |
| 1497 | 1497 | */ |
| 1498 | 1498 | function kwote($lisp, $serveur = '', $type = '') { |
| 1499 | - if (preg_match(_CODE_QUOTE, $lisp, $r)) { |
|
| 1500 | - return $r[1] . '"' . sql_quote(str_replace(["\\'", '\\\\'], ["'", '\\'], $r[2]), $serveur, $type) . '"'; |
|
| 1501 | - } else { |
|
| 1502 | - return "sql_quote($lisp, '$serveur', '" . str_replace("'", "\\'", $type) . "')"; |
|
| 1503 | - } |
|
| 1499 | + if (preg_match(_CODE_QUOTE, $lisp, $r)) { |
|
| 1500 | + return $r[1] . '"' . sql_quote(str_replace(["\\'", '\\\\'], ["'", '\\'], $r[2]), $serveur, $type) . '"'; |
|
| 1501 | + } else { |
|
| 1502 | + return "sql_quote($lisp, '$serveur', '" . str_replace("'", "\\'", $type) . "')"; |
|
| 1503 | + } |
|
| 1504 | 1504 | } |
| 1505 | 1505 | |
| 1506 | 1506 | |
@@ -1519,81 +1519,81 @@ discard block |
||
| 1519 | 1519 | * @return void |
| 1520 | 1520 | **/ |
| 1521 | 1521 | function critere_IN_dist($idb, &$boucles, $crit) { |
| 1522 | - $r = calculer_critere_infixe($idb, $boucles, $crit); |
|
| 1523 | - if (!$r) { |
|
| 1524 | - return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']]); |
|
| 1525 | - } |
|
| 1526 | - [$arg, $op, $val, $col, $where_complement] = $r; |
|
| 1527 | - |
|
| 1528 | - $in = critere_IN_cas($idb, $boucles, $crit->not ? 'NOT' : ($crit->exclus ? 'exclus' : ''), $arg, $op, $val, $col); |
|
| 1529 | - |
|
| 1530 | - // inserer la condition; exemple: {id_mot ?IN (66, 62, 64)} |
|
| 1531 | - $where = $in; |
|
| 1532 | - if ($crit->cond) { |
|
| 1533 | - $pred = calculer_argument_precedent($idb, $col, $boucles); |
|
| 1534 | - $where = ["'?'", $pred, $where, "''"]; |
|
| 1535 | - if ($where_complement) { // condition annexe du type "AND (objet='article')" |
|
| 1536 | - $where_complement = ["'?'", $pred, $where_complement, "''"]; |
|
| 1537 | - } |
|
| 1538 | - } |
|
| 1539 | - if ($crit->exclus) { |
|
| 1540 | - if (!preg_match(',^L[0-9]+[.],', $arg)) { |
|
| 1541 | - $where = ["'NOT'", $where]; |
|
| 1542 | - } else // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete |
|
| 1543 | - // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent |
|
| 1544 | - { |
|
| 1545 | - $where = [ |
|
| 1546 | - "'NOT'", |
|
| 1547 | - [ |
|
| 1548 | - "'IN'", |
|
| 1549 | - "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", |
|
| 1550 | - ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where] |
|
| 1551 | - ] |
|
| 1552 | - ]; |
|
| 1553 | - } |
|
| 1554 | - } |
|
| 1555 | - |
|
| 1556 | - $boucles[$idb]->where[] = $where; |
|
| 1557 | - if ($where_complement) { // condition annexe du type "AND (objet='article')" |
|
| 1558 | - $boucles[$idb]->where[] = $where_complement; |
|
| 1559 | - } |
|
| 1522 | + $r = calculer_critere_infixe($idb, $boucles, $crit); |
|
| 1523 | + if (!$r) { |
|
| 1524 | + return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']]); |
|
| 1525 | + } |
|
| 1526 | + [$arg, $op, $val, $col, $where_complement] = $r; |
|
| 1527 | + |
|
| 1528 | + $in = critere_IN_cas($idb, $boucles, $crit->not ? 'NOT' : ($crit->exclus ? 'exclus' : ''), $arg, $op, $val, $col); |
|
| 1529 | + |
|
| 1530 | + // inserer la condition; exemple: {id_mot ?IN (66, 62, 64)} |
|
| 1531 | + $where = $in; |
|
| 1532 | + if ($crit->cond) { |
|
| 1533 | + $pred = calculer_argument_precedent($idb, $col, $boucles); |
|
| 1534 | + $where = ["'?'", $pred, $where, "''"]; |
|
| 1535 | + if ($where_complement) { // condition annexe du type "AND (objet='article')" |
|
| 1536 | + $where_complement = ["'?'", $pred, $where_complement, "''"]; |
|
| 1537 | + } |
|
| 1538 | + } |
|
| 1539 | + if ($crit->exclus) { |
|
| 1540 | + if (!preg_match(',^L[0-9]+[.],', $arg)) { |
|
| 1541 | + $where = ["'NOT'", $where]; |
|
| 1542 | + } else // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete |
|
| 1543 | + // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent |
|
| 1544 | + { |
|
| 1545 | + $where = [ |
|
| 1546 | + "'NOT'", |
|
| 1547 | + [ |
|
| 1548 | + "'IN'", |
|
| 1549 | + "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", |
|
| 1550 | + ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where] |
|
| 1551 | + ] |
|
| 1552 | + ]; |
|
| 1553 | + } |
|
| 1554 | + } |
|
| 1555 | + |
|
| 1556 | + $boucles[$idb]->where[] = $where; |
|
| 1557 | + if ($where_complement) { // condition annexe du type "AND (objet='article')" |
|
| 1558 | + $boucles[$idb]->where[] = $where_complement; |
|
| 1559 | + } |
|
| 1560 | 1560 | } |
| 1561 | 1561 | |
| 1562 | 1562 | function critere_IN_cas($idb, &$boucles, $crit2, $arg, $op, $val, $col) { |
| 1563 | - static $num = []; |
|
| 1564 | - $descr = $boucles[$idb]->descr; |
|
| 1565 | - $cpt = &$num[$descr['nom']][$descr['gram']][$idb]; |
|
| 1566 | - |
|
| 1567 | - $var = '$in' . $cpt++; |
|
| 1568 | - $x = "\n\t$var = array();"; |
|
| 1569 | - foreach ($val as $k => $v) { |
|
| 1570 | - if (preg_match(",^(\n//.*\n)?'(.*)'$,", $v, $r)) { |
|
| 1571 | - // optimiser le traitement des constantes |
|
| 1572 | - if (is_numeric($r[2])) { |
|
| 1573 | - $x .= "\n\t$var" . "[]= $r[2];"; |
|
| 1574 | - } else { |
|
| 1575 | - $x .= "\n\t$var" . '[]= ' . sql_quote($r[2]) . ';'; |
|
| 1576 | - } |
|
| 1577 | - } else { |
|
| 1578 | - // Pour permettre de passer des tableaux de valeurs |
|
| 1579 | - // on repere l'utilisation brute de #ENV**{X}, |
|
| 1580 | - // c'est-a-dire sa traduction en ($PILE[0][X]). |
|
| 1581 | - // et on deballe mais en rajoutant l'anti XSS |
|
| 1582 | - $x .= "\n\tif (!(is_array(\$a = ($v))))\n\t\t$var" . "[]= \$a;\n\telse $var = array_merge($var, \$a);"; |
|
| 1583 | - } |
|
| 1584 | - } |
|
| 1585 | - |
|
| 1586 | - $boucles[$idb]->in .= $x; |
|
| 1587 | - |
|
| 1588 | - // inserer le tri par defaut selon les ordres du IN ... |
|
| 1589 | - // avec une ecriture de type FIELD qui degrade les performances (du meme ordre qu'un regexp) |
|
| 1590 | - // et que l'on limite donc strictement aux cas necessaires : |
|
| 1591 | - // si ce n'est pas un !IN, et si il n'y a pas d'autre order dans la boucle |
|
| 1592 | - if (!$crit2) { |
|
| 1593 | - $boucles[$idb]->default_order[] = "((!\$zqv=sql_quote($var) OR \$zqv===\"''\") ? 0 : ('FIELD($arg,' . \$zqv . ')'))"; |
|
| 1594 | - } |
|
| 1595 | - |
|
| 1596 | - return "sql_in('$arg', $var" . ($crit2 == 'NOT' ? ",'NOT'" : '') . ')'; |
|
| 1563 | + static $num = []; |
|
| 1564 | + $descr = $boucles[$idb]->descr; |
|
| 1565 | + $cpt = &$num[$descr['nom']][$descr['gram']][$idb]; |
|
| 1566 | + |
|
| 1567 | + $var = '$in' . $cpt++; |
|
| 1568 | + $x = "\n\t$var = array();"; |
|
| 1569 | + foreach ($val as $k => $v) { |
|
| 1570 | + if (preg_match(",^(\n//.*\n)?'(.*)'$,", $v, $r)) { |
|
| 1571 | + // optimiser le traitement des constantes |
|
| 1572 | + if (is_numeric($r[2])) { |
|
| 1573 | + $x .= "\n\t$var" . "[]= $r[2];"; |
|
| 1574 | + } else { |
|
| 1575 | + $x .= "\n\t$var" . '[]= ' . sql_quote($r[2]) . ';'; |
|
| 1576 | + } |
|
| 1577 | + } else { |
|
| 1578 | + // Pour permettre de passer des tableaux de valeurs |
|
| 1579 | + // on repere l'utilisation brute de #ENV**{X}, |
|
| 1580 | + // c'est-a-dire sa traduction en ($PILE[0][X]). |
|
| 1581 | + // et on deballe mais en rajoutant l'anti XSS |
|
| 1582 | + $x .= "\n\tif (!(is_array(\$a = ($v))))\n\t\t$var" . "[]= \$a;\n\telse $var = array_merge($var, \$a);"; |
|
| 1583 | + } |
|
| 1584 | + } |
|
| 1585 | + |
|
| 1586 | + $boucles[$idb]->in .= $x; |
|
| 1587 | + |
|
| 1588 | + // inserer le tri par defaut selon les ordres du IN ... |
|
| 1589 | + // avec une ecriture de type FIELD qui degrade les performances (du meme ordre qu'un regexp) |
|
| 1590 | + // et que l'on limite donc strictement aux cas necessaires : |
|
| 1591 | + // si ce n'est pas un !IN, et si il n'y a pas d'autre order dans la boucle |
|
| 1592 | + if (!$crit2) { |
|
| 1593 | + $boucles[$idb]->default_order[] = "((!\$zqv=sql_quote($var) OR \$zqv===\"''\") ? 0 : ('FIELD($arg,' . \$zqv . ')'))"; |
|
| 1594 | + } |
|
| 1595 | + |
|
| 1596 | + return "sql_in('$arg', $var" . ($crit2 == 'NOT' ? ",'NOT'" : '') . ')'; |
|
| 1597 | 1597 | } |
| 1598 | 1598 | |
| 1599 | 1599 | /** |
@@ -1609,22 +1609,22 @@ discard block |
||
| 1609 | 1609 | * @return void |
| 1610 | 1610 | */ |
| 1611 | 1611 | function critere_where_dist($idb, &$boucles, $crit) { |
| 1612 | - $boucle = &$boucles[$idb]; |
|
| 1613 | - if (isset($crit->param[0])) { |
|
| 1614 | - $_where = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent); |
|
| 1615 | - } else { |
|
| 1616 | - $_where = 'spip_sanitize_from_request(@$Pile[0]["where"],"where","vide")'; |
|
| 1617 | - } |
|
| 1618 | - |
|
| 1619 | - if ($crit->cond) { |
|
| 1620 | - $_where = "((\$zzw = $_where) ? \$zzw : '')"; |
|
| 1621 | - } |
|
| 1622 | - |
|
| 1623 | - if ($crit->not) { |
|
| 1624 | - $_where = "array('NOT',$_where)"; |
|
| 1625 | - } |
|
| 1626 | - |
|
| 1627 | - $boucle->where[] = $_where; |
|
| 1612 | + $boucle = &$boucles[$idb]; |
|
| 1613 | + if (isset($crit->param[0])) { |
|
| 1614 | + $_where = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent); |
|
| 1615 | + } else { |
|
| 1616 | + $_where = 'spip_sanitize_from_request(@$Pile[0]["where"],"where","vide")'; |
|
| 1617 | + } |
|
| 1618 | + |
|
| 1619 | + if ($crit->cond) { |
|
| 1620 | + $_where = "((\$zzw = $_where) ? \$zzw : '')"; |
|
| 1621 | + } |
|
| 1622 | + |
|
| 1623 | + if ($crit->not) { |
|
| 1624 | + $_where = "array('NOT',$_where)"; |
|
| 1625 | + } |
|
| 1626 | + |
|
| 1627 | + $boucle->where[] = $_where; |
|
| 1628 | 1628 | } |
| 1629 | 1629 | |
| 1630 | 1630 | /** |
@@ -1652,31 +1652,31 @@ discard block |
||
| 1652 | 1652 | * @return void |
| 1653 | 1653 | */ |
| 1654 | 1654 | function critere_id__dist($idb, &$boucles, $crit) { |
| 1655 | - /** @var Boucle $boucle */ |
|
| 1656 | - $boucle = $boucles[$idb]; |
|
| 1657 | - |
|
| 1658 | - $champs = lister_champs_id_conditionnel( |
|
| 1659 | - $boucle->show['table'], |
|
| 1660 | - $boucle->show, |
|
| 1661 | - $boucle->sql_serveur |
|
| 1662 | - ); |
|
| 1663 | - |
|
| 1664 | - // ne pas tenir compte des critères identiques déjà présents. |
|
| 1665 | - if (!empty($boucle->modificateur['criteres'])) { |
|
| 1666 | - $champs = array_diff($champs, array_keys($boucle->modificateur['criteres'])); |
|
| 1667 | - } |
|
| 1668 | - // nous aider en mode debug. |
|
| 1669 | - $boucle->debug[] = 'id_ : ' . implode(', ', $champs); |
|
| 1670 | - $boucle->modificateur['id_'] = $champs; |
|
| 1671 | - |
|
| 1672 | - // créer un critère {id_xxx?} de chaque champ retenu |
|
| 1673 | - foreach ($champs as $champ) { |
|
| 1674 | - $critere_id_table = new Critere(); |
|
| 1675 | - $critere_id_table->op = $champ; |
|
| 1676 | - $critere_id_table->cond = '?'; |
|
| 1677 | - $critere_id_table->ligne = $crit->ligne; |
|
| 1678 | - calculer_critere_DEFAUT_dist($idb, $boucles, $critere_id_table); |
|
| 1679 | - } |
|
| 1655 | + /** @var Boucle $boucle */ |
|
| 1656 | + $boucle = $boucles[$idb]; |
|
| 1657 | + |
|
| 1658 | + $champs = lister_champs_id_conditionnel( |
|
| 1659 | + $boucle->show['table'], |
|
| 1660 | + $boucle->show, |
|
| 1661 | + $boucle->sql_serveur |
|
| 1662 | + ); |
|
| 1663 | + |
|
| 1664 | + // ne pas tenir compte des critères identiques déjà présents. |
|
| 1665 | + if (!empty($boucle->modificateur['criteres'])) { |
|
| 1666 | + $champs = array_diff($champs, array_keys($boucle->modificateur['criteres'])); |
|
| 1667 | + } |
|
| 1668 | + // nous aider en mode debug. |
|
| 1669 | + $boucle->debug[] = 'id_ : ' . implode(', ', $champs); |
|
| 1670 | + $boucle->modificateur['id_'] = $champs; |
|
| 1671 | + |
|
| 1672 | + // créer un critère {id_xxx?} de chaque champ retenu |
|
| 1673 | + foreach ($champs as $champ) { |
|
| 1674 | + $critere_id_table = new Critere(); |
|
| 1675 | + $critere_id_table->op = $champ; |
|
| 1676 | + $critere_id_table->cond = '?'; |
|
| 1677 | + $critere_id_table->ligne = $crit->ligne; |
|
| 1678 | + calculer_critere_DEFAUT_dist($idb, $boucles, $critere_id_table); |
|
| 1679 | + } |
|
| 1680 | 1680 | } |
| 1681 | 1681 | |
| 1682 | 1682 | /** |
@@ -1696,75 +1696,75 @@ discard block |
||
| 1696 | 1696 | * @return array Liste de nom de champs (tel que id_article, id_mot, id_parent ...) |
| 1697 | 1697 | */ |
| 1698 | 1698 | function lister_champs_id_conditionnel($table, $desc = null, $serveur = '') { |
| 1699 | - // calculer la description de la table |
|
| 1700 | - if (!is_array($desc)) { |
|
| 1701 | - $desc = description_table($table, $serveur); |
|
| 1702 | - } |
|
| 1703 | - if (!$desc) { |
|
| 1704 | - return []; |
|
| 1705 | - } |
|
| 1706 | - |
|
| 1707 | - // Les champs id_xx de la table demandée |
|
| 1708 | - $champs = array_filter( |
|
| 1709 | - array_keys($desc['field']), |
|
| 1710 | - fn($champ) => strpos($champ, 'id_') === 0 or (in_array($champ, ['objet'])) |
|
| 1711 | - ); |
|
| 1712 | - |
|
| 1713 | - // Si le champ id_rubrique appartient à la liste et si id_secteur n'est pas inclus on le rajoute. |
|
| 1714 | - if ( |
|
| 1715 | - in_array('id_rubrique', $champs) |
|
| 1716 | - and !in_array('id_secteur', $champs) |
|
| 1717 | - ) { |
|
| 1718 | - $champs[] = 'id_secteur'; |
|
| 1719 | - } |
|
| 1720 | - |
|
| 1721 | - // On ne fera pas mieux pour les tables d’un autre serveur |
|
| 1722 | - if ($serveur) { |
|
| 1723 | - return $champs; |
|
| 1724 | - } |
|
| 1725 | - |
|
| 1726 | - $primary = false; |
|
| 1727 | - $associable = false; |
|
| 1728 | - include_spip('action/editer_liens'); |
|
| 1729 | - |
|
| 1730 | - if (isset($desc['type'])) { |
|
| 1731 | - $primary = id_table_objet($desc['type']); |
|
| 1732 | - $associable = objet_associable($desc['type']); |
|
| 1733 | - } |
|
| 1734 | - if (isset($desc['field']['id_objet']) and isset($desc['field']['objet'])) { |
|
| 1735 | - $associable = true; |
|
| 1736 | - } |
|
| 1737 | - |
|
| 1738 | - // liste de toutes les tables principales, sauf la notre |
|
| 1739 | - $tables = lister_tables_objets_sql(); |
|
| 1740 | - unset($tables[$table]); |
|
| 1741 | - |
|
| 1742 | - foreach ($tables as $_table => $_desc) { |
|
| 1743 | - if ( |
|
| 1744 | - $associable |
|
| 1745 | - or ($primary and in_array($primary, array_keys($_desc['field']))) |
|
| 1746 | - or objet_associable($_desc['type']) |
|
| 1747 | - ) { |
|
| 1748 | - $champs[] = id_table_objet($_table); |
|
| 1749 | - } |
|
| 1750 | - } |
|
| 1751 | - $champs = array_values(array_unique($champs)); |
|
| 1752 | - |
|
| 1753 | - // Exclusions de certains id |
|
| 1754 | - $exclusions = pipeline( |
|
| 1755 | - 'exclure_id_conditionnel', |
|
| 1756 | - [ |
|
| 1757 | - 'args' => [ |
|
| 1758 | - 'table' => $table, |
|
| 1759 | - 'id_table_objet' => $primary, |
|
| 1760 | - 'associable' => $associable, |
|
| 1761 | - ], |
|
| 1762 | - 'data' => [], |
|
| 1763 | - ] |
|
| 1764 | - ); |
|
| 1765 | - $champs = array_diff($champs, $exclusions); |
|
| 1766 | - |
|
| 1767 | - return $champs; |
|
| 1699 | + // calculer la description de la table |
|
| 1700 | + if (!is_array($desc)) { |
|
| 1701 | + $desc = description_table($table, $serveur); |
|
| 1702 | + } |
|
| 1703 | + if (!$desc) { |
|
| 1704 | + return []; |
|
| 1705 | + } |
|
| 1706 | + |
|
| 1707 | + // Les champs id_xx de la table demandée |
|
| 1708 | + $champs = array_filter( |
|
| 1709 | + array_keys($desc['field']), |
|
| 1710 | + fn($champ) => strpos($champ, 'id_') === 0 or (in_array($champ, ['objet'])) |
|
| 1711 | + ); |
|
| 1712 | + |
|
| 1713 | + // Si le champ id_rubrique appartient à la liste et si id_secteur n'est pas inclus on le rajoute. |
|
| 1714 | + if ( |
|
| 1715 | + in_array('id_rubrique', $champs) |
|
| 1716 | + and !in_array('id_secteur', $champs) |
|
| 1717 | + ) { |
|
| 1718 | + $champs[] = 'id_secteur'; |
|
| 1719 | + } |
|
| 1720 | + |
|
| 1721 | + // On ne fera pas mieux pour les tables d’un autre serveur |
|
| 1722 | + if ($serveur) { |
|
| 1723 | + return $champs; |
|
| 1724 | + } |
|
| 1725 | + |
|
| 1726 | + $primary = false; |
|
| 1727 | + $associable = false; |
|
| 1728 | + include_spip('action/editer_liens'); |
|
| 1729 | + |
|
| 1730 | + if (isset($desc['type'])) { |
|
| 1731 | + $primary = id_table_objet($desc['type']); |
|
| 1732 | + $associable = objet_associable($desc['type']); |
|
| 1733 | + } |
|
| 1734 | + if (isset($desc['field']['id_objet']) and isset($desc['field']['objet'])) { |
|
| 1735 | + $associable = true; |
|
| 1736 | + } |
|
| 1737 | + |
|
| 1738 | + // liste de toutes les tables principales, sauf la notre |
|
| 1739 | + $tables = lister_tables_objets_sql(); |
|
| 1740 | + unset($tables[$table]); |
|
| 1741 | + |
|
| 1742 | + foreach ($tables as $_table => $_desc) { |
|
| 1743 | + if ( |
|
| 1744 | + $associable |
|
| 1745 | + or ($primary and in_array($primary, array_keys($_desc['field']))) |
|
| 1746 | + or objet_associable($_desc['type']) |
|
| 1747 | + ) { |
|
| 1748 | + $champs[] = id_table_objet($_table); |
|
| 1749 | + } |
|
| 1750 | + } |
|
| 1751 | + $champs = array_values(array_unique($champs)); |
|
| 1752 | + |
|
| 1753 | + // Exclusions de certains id |
|
| 1754 | + $exclusions = pipeline( |
|
| 1755 | + 'exclure_id_conditionnel', |
|
| 1756 | + [ |
|
| 1757 | + 'args' => [ |
|
| 1758 | + 'table' => $table, |
|
| 1759 | + 'id_table_objet' => $primary, |
|
| 1760 | + 'associable' => $associable, |
|
| 1761 | + ], |
|
| 1762 | + 'data' => [], |
|
| 1763 | + ] |
|
| 1764 | + ); |
|
| 1765 | + $champs = array_diff($champs, $exclusions); |
|
| 1766 | + |
|
| 1767 | + return $champs; |
|
| 1768 | 1768 | } |
| 1769 | 1769 | |
| 1770 | 1770 | /** |
@@ -1819,27 +1819,27 @@ discard block |
||
| 1819 | 1819 | * @return void |
| 1820 | 1820 | */ |
| 1821 | 1821 | function critere_tri_dist($idb, &$boucles, $crit) { |
| 1822 | - $boucle = &$boucles[$idb]; |
|
| 1823 | - |
|
| 1824 | - // definition du champ par defaut |
|
| 1825 | - $_champ_defaut = !isset($crit->param[0][0]) ? "''" |
|
| 1826 | - : calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent); |
|
| 1827 | - $_sens_defaut = !isset($crit->param[1][0]) ? '1' |
|
| 1828 | - : calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent); |
|
| 1829 | - $_variable = !isset($crit->param[2][0]) ? "'$idb'" |
|
| 1830 | - : calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent); |
|
| 1831 | - |
|
| 1832 | - $_tri = "((\$t=(isset(\$Pile[0]['tri'.$_variable]))?\$Pile[0]['tri'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('tri'.$_variable))?session_get('tri'.$_variable):$_champ_defaut))?tri_protege_champ(\$t):'')"; |
|
| 1833 | - |
|
| 1834 | - $_sens_defaut = "(is_array(\$s=$_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)"; |
|
| 1835 | - $_sens = "((intval(\$t=(isset(\$Pile[0]['sens'.$_variable]))?\$Pile[0]['sens'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('sens'.$_variable))?session_get('sens'.$_variable):$_sens_defaut))==-1 OR \$t=='inverse')?-1:1)"; |
|
| 1836 | - |
|
| 1837 | - $boucle->modificateur['tri_champ'] = $_tri; |
|
| 1838 | - $boucle->modificateur['tri_sens'] = $_sens; |
|
| 1839 | - $boucle->modificateur['tri_nom'] = $_variable; |
|
| 1840 | - // faut il inserer un test sur l'existence de $tri parmi les champs de la table ? |
|
| 1841 | - // evite des erreurs sql, mais peut empecher des tri sur jointure ... |
|
| 1842 | - $boucle->hash .= " |
|
| 1822 | + $boucle = &$boucles[$idb]; |
|
| 1823 | + |
|
| 1824 | + // definition du champ par defaut |
|
| 1825 | + $_champ_defaut = !isset($crit->param[0][0]) ? "''" |
|
| 1826 | + : calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent); |
|
| 1827 | + $_sens_defaut = !isset($crit->param[1][0]) ? '1' |
|
| 1828 | + : calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent); |
|
| 1829 | + $_variable = !isset($crit->param[2][0]) ? "'$idb'" |
|
| 1830 | + : calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent); |
|
| 1831 | + |
|
| 1832 | + $_tri = "((\$t=(isset(\$Pile[0]['tri'.$_variable]))?\$Pile[0]['tri'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('tri'.$_variable))?session_get('tri'.$_variable):$_champ_defaut))?tri_protege_champ(\$t):'')"; |
|
| 1833 | + |
|
| 1834 | + $_sens_defaut = "(is_array(\$s=$_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)"; |
|
| 1835 | + $_sens = "((intval(\$t=(isset(\$Pile[0]['sens'.$_variable]))?\$Pile[0]['sens'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('sens'.$_variable))?session_get('sens'.$_variable):$_sens_defaut))==-1 OR \$t=='inverse')?-1:1)"; |
|
| 1836 | + |
|
| 1837 | + $boucle->modificateur['tri_champ'] = $_tri; |
|
| 1838 | + $boucle->modificateur['tri_sens'] = $_sens; |
|
| 1839 | + $boucle->modificateur['tri_nom'] = $_variable; |
|
| 1840 | + // faut il inserer un test sur l'existence de $tri parmi les champs de la table ? |
|
| 1841 | + // evite des erreurs sql, mais peut empecher des tri sur jointure ... |
|
| 1842 | + $boucle->hash .= " |
|
| 1843 | 1843 | \$senstri = ''; |
| 1844 | 1844 | \$tri = $_tri; |
| 1845 | 1845 | if (\$tri){ |
@@ -1847,8 +1847,8 @@ discard block |
||
| 1847 | 1847 | \$senstri = (\$senstri<0)?' DESC':''; |
| 1848 | 1848 | }; |
| 1849 | 1849 | "; |
| 1850 | - $boucle->select[] = '".tri_champ_select($tri)."'; |
|
| 1851 | - $boucle->order[] = "tri_champ_order(\$tri,\$command['from'],\$senstri)"; |
|
| 1850 | + $boucle->select[] = '".tri_champ_select($tri)."'; |
|
| 1851 | + $boucle->order[] = "tri_champ_order(\$tri,\$command['from'],\$senstri)"; |
|
| 1852 | 1852 | } |
| 1853 | 1853 | |
| 1854 | 1854 | # Criteres de comparaison |
@@ -1865,20 +1865,20 @@ discard block |
||
| 1865 | 1865 | * @return void |
| 1866 | 1866 | **/ |
| 1867 | 1867 | function calculer_critere_DEFAUT_dist($idb, &$boucles, $crit) { |
| 1868 | - // double cas particulier {0,1} et {1/2} repere a l'analyse lexicale |
|
| 1869 | - if (($crit->op == ',') or ($crit->op == '/')) { |
|
| 1870 | - return calculer_critere_parties($idb, $boucles, $crit); |
|
| 1871 | - } |
|
| 1872 | - |
|
| 1873 | - $r = calculer_critere_infixe($idb, $boucles, $crit); |
|
| 1874 | - if (!$r) { |
|
| 1875 | - # // on produit une erreur seulement si le critere n'a pas de '?' |
|
| 1876 | - # if (!$crit->cond) { |
|
| 1877 | - return (['zbug_critere_inconnu', ['critere' => $crit->op]]); |
|
| 1878 | - # } |
|
| 1879 | - } else { |
|
| 1880 | - calculer_critere_DEFAUT_args($idb, $boucles, $crit, $r); |
|
| 1881 | - } |
|
| 1868 | + // double cas particulier {0,1} et {1/2} repere a l'analyse lexicale |
|
| 1869 | + if (($crit->op == ',') or ($crit->op == '/')) { |
|
| 1870 | + return calculer_critere_parties($idb, $boucles, $crit); |
|
| 1871 | + } |
|
| 1872 | + |
|
| 1873 | + $r = calculer_critere_infixe($idb, $boucles, $crit); |
|
| 1874 | + if (!$r) { |
|
| 1875 | + # // on produit une erreur seulement si le critere n'a pas de '?' |
|
| 1876 | + # if (!$crit->cond) { |
|
| 1877 | + return (['zbug_critere_inconnu', ['critere' => $crit->op]]); |
|
| 1878 | + # } |
|
| 1879 | + } else { |
|
| 1880 | + calculer_critere_DEFAUT_args($idb, $boucles, $crit, $r); |
|
| 1881 | + } |
|
| 1882 | 1882 | } |
| 1883 | 1883 | |
| 1884 | 1884 | |
@@ -1898,62 +1898,62 @@ discard block |
||
| 1898 | 1898 | * @return void |
| 1899 | 1899 | **/ |
| 1900 | 1900 | function calculer_critere_DEFAUT_args($idb, &$boucles, $crit, $args) { |
| 1901 | - [$arg, $op, $val, $col, $where_complement] = $args; |
|
| 1902 | - |
|
| 1903 | - $where = ["'$op'", "'$arg'", $val[0]]; |
|
| 1904 | - |
|
| 1905 | - // inserer la negation (cf !...) |
|
| 1906 | - |
|
| 1907 | - if ($crit->not) { |
|
| 1908 | - $where = ["'NOT'", $where]; |
|
| 1909 | - } |
|
| 1910 | - if ($crit->exclus) { |
|
| 1911 | - if (!preg_match(',^L[0-9]+[.],', $arg)) { |
|
| 1912 | - $where = ["'NOT'", $where]; |
|
| 1913 | - } else { |
|
| 1914 | - // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete |
|
| 1915 | - // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent |
|
| 1916 | - $where = [ |
|
| 1917 | - "'NOT'", |
|
| 1918 | - [ |
|
| 1919 | - "'IN'", |
|
| 1920 | - "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", |
|
| 1921 | - ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where] |
|
| 1922 | - ] |
|
| 1923 | - ]; |
|
| 1924 | - } |
|
| 1925 | - } |
|
| 1926 | - |
|
| 1927 | - // inserer la condition (cf {lang?}) |
|
| 1928 | - // traiter a part la date, elle est mise d'office par SPIP, |
|
| 1929 | - if ($crit->cond) { |
|
| 1930 | - $pred = calculer_argument_precedent($idb, $col, $boucles); |
|
| 1931 | - if ($col === 'date' or $col === 'date_redac') { |
|
| 1932 | - if ($pred === "\$Pile[0]['" . $col . "']") { |
|
| 1933 | - $pred = "(\$Pile[0]['{$col}_default']?'':$pred)"; |
|
| 1934 | - } |
|
| 1935 | - } |
|
| 1936 | - |
|
| 1937 | - if ($op === '=' and !$crit->not) { |
|
| 1938 | - $where = [ |
|
| 1939 | - "'?'", |
|
| 1940 | - "(is_array($pred))", |
|
| 1941 | - critere_IN_cas($idb, $boucles, 'COND', $arg, $op, [$pred], $col), |
|
| 1942 | - $where |
|
| 1943 | - ]; |
|
| 1944 | - } |
|
| 1945 | - $where = ["'?'", "!is_whereable($pred)", "''", $where]; |
|
| 1946 | - if ($where_complement) { |
|
| 1947 | - // condition annexe du type "AND (objet='article')" |
|
| 1948 | - $where_complement = ["'?'", "!is_whereable($pred)", "''", $where_complement]; |
|
| 1949 | - } |
|
| 1950 | - } |
|
| 1951 | - |
|
| 1952 | - $boucles[$idb]->where[] = $where; |
|
| 1953 | - if ($where_complement) { |
|
| 1954 | - // condition annexe du type "AND (objet='article')" |
|
| 1955 | - $boucles[$idb]->where[] = $where_complement; |
|
| 1956 | - } |
|
| 1901 | + [$arg, $op, $val, $col, $where_complement] = $args; |
|
| 1902 | + |
|
| 1903 | + $where = ["'$op'", "'$arg'", $val[0]]; |
|
| 1904 | + |
|
| 1905 | + // inserer la negation (cf !...) |
|
| 1906 | + |
|
| 1907 | + if ($crit->not) { |
|
| 1908 | + $where = ["'NOT'", $where]; |
|
| 1909 | + } |
|
| 1910 | + if ($crit->exclus) { |
|
| 1911 | + if (!preg_match(',^L[0-9]+[.],', $arg)) { |
|
| 1912 | + $where = ["'NOT'", $where]; |
|
| 1913 | + } else { |
|
| 1914 | + // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete |
|
| 1915 | + // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent |
|
| 1916 | + $where = [ |
|
| 1917 | + "'NOT'", |
|
| 1918 | + [ |
|
| 1919 | + "'IN'", |
|
| 1920 | + "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", |
|
| 1921 | + ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where] |
|
| 1922 | + ] |
|
| 1923 | + ]; |
|
| 1924 | + } |
|
| 1925 | + } |
|
| 1926 | + |
|
| 1927 | + // inserer la condition (cf {lang?}) |
|
| 1928 | + // traiter a part la date, elle est mise d'office par SPIP, |
|
| 1929 | + if ($crit->cond) { |
|
| 1930 | + $pred = calculer_argument_precedent($idb, $col, $boucles); |
|
| 1931 | + if ($col === 'date' or $col === 'date_redac') { |
|
| 1932 | + if ($pred === "\$Pile[0]['" . $col . "']") { |
|
| 1933 | + $pred = "(\$Pile[0]['{$col}_default']?'':$pred)"; |
|
| 1934 | + } |
|
| 1935 | + } |
|
| 1936 | + |
|
| 1937 | + if ($op === '=' and !$crit->not) { |
|
| 1938 | + $where = [ |
|
| 1939 | + "'?'", |
|
| 1940 | + "(is_array($pred))", |
|
| 1941 | + critere_IN_cas($idb, $boucles, 'COND', $arg, $op, [$pred], $col), |
|
| 1942 | + $where |
|
| 1943 | + ]; |
|
| 1944 | + } |
|
| 1945 | + $where = ["'?'", "!is_whereable($pred)", "''", $where]; |
|
| 1946 | + if ($where_complement) { |
|
| 1947 | + // condition annexe du type "AND (objet='article')" |
|
| 1948 | + $where_complement = ["'?'", "!is_whereable($pred)", "''", $where_complement]; |
|
| 1949 | + } |
|
| 1950 | + } |
|
| 1951 | + |
|
| 1952 | + $boucles[$idb]->where[] = $where; |
|
| 1953 | + if ($where_complement) { |
|
| 1954 | + // condition annexe du type "AND (objet='article')" |
|
| 1955 | + $boucles[$idb]->where[] = $where_complement; |
|
| 1956 | + } |
|
| 1957 | 1957 | } |
| 1958 | 1958 | |
| 1959 | 1959 | |
@@ -1994,165 +1994,165 @@ discard block |
||
| 1994 | 1994 | **/ |
| 1995 | 1995 | function calculer_critere_infixe($idb, &$boucles, $crit) { |
| 1996 | 1996 | |
| 1997 | - $boucle = &$boucles[$idb]; |
|
| 1998 | - $type = $boucle->type_requete; |
|
| 1999 | - $table = $boucle->id_table ?? ''; |
|
| 2000 | - $desc = $boucle->show; |
|
| 2001 | - $col_vraie = null; |
|
| 2002 | - |
|
| 2003 | - [$fct, $col, $op, $val, $args_sql] = |
|
| 2004 | - calculer_critere_infixe_ops($idb, $boucles, $crit); |
|
| 2005 | - |
|
| 2006 | - $col_alias = $col; |
|
| 2007 | - $where_complement = false; |
|
| 2008 | - |
|
| 2009 | - // Cas particulier : id_enfant => utiliser la colonne id_objet |
|
| 2010 | - if ($col == 'id_enfant') { |
|
| 2011 | - $col = $boucle->primary; |
|
| 2012 | - } |
|
| 2013 | - |
|
| 2014 | - // Cas particulier : id_parent => verifier les exceptions de tables |
|
| 2015 | - if ( |
|
| 2016 | - (in_array($col, ['id_parent', 'id_secteur']) and isset($GLOBALS['exceptions_des_tables'][$table][$col])) |
|
| 2017 | - or (isset($GLOBALS['exceptions_des_tables'][$table][$col]) and is_string($GLOBALS['exceptions_des_tables'][$table][$col])) |
|
| 2018 | - ) { |
|
| 2019 | - $col = $GLOBALS['exceptions_des_tables'][$table][$col]; |
|
| 2020 | - } // et possibilite de gerer un critere secteur sur des tables de plugins (ie forums) |
|
| 2021 | - else { |
|
| 2022 | - if (($col == 'id_secteur') and ($critere_secteur = charger_fonction("critere_secteur_$type", 'public', true))) { |
|
| 2023 | - $table = $critere_secteur($idb, $boucles, $val, $crit); |
|
| 2024 | - } |
|
| 2025 | - |
|
| 2026 | - // cas id_article=xx qui se mappe en id_objet=xx AND objet=article |
|
| 2027 | - // sauf si exception declaree : sauter cette etape |
|
| 2028 | - else { |
|
| 2029 | - if ( |
|
| 2030 | - !isset($GLOBALS['exceptions_des_jointures'][table_objet_sql($table)][$col]) |
|
| 2031 | - and !isset($GLOBALS['exceptions_des_jointures'][$col]) |
|
| 2032 | - and count(trouver_champs_decomposes($col, $desc)) > 1 |
|
| 2033 | - ) { |
|
| 2034 | - $e = decompose_champ_id_objet($col); |
|
| 2035 | - $col = array_shift($e); |
|
| 2036 | - $where_complement = primary_doublee($e, $table); |
|
| 2037 | - } // Cas particulier : expressions de date |
|
| 2038 | - else { |
|
| 2039 | - if ($c = calculer_critere_infixe_date($idb, $boucles, $col)) { |
|
| 2040 | - [$col, $col_vraie] = $c; |
|
| 2041 | - $table = ''; |
|
| 2042 | - } // table explicitée {mots.titre} |
|
| 2043 | - else { |
|
| 2044 | - if (preg_match('/^(.*)\.(.*)$/', $col, $r)) { |
|
| 2045 | - [, $table, $col] = $r; |
|
| 2046 | - $col_alias = $col; |
|
| 2047 | - |
|
| 2048 | - $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 2049 | - if ( |
|
| 2050 | - $desc = $trouver_table($table, $boucle->sql_serveur) |
|
| 2051 | - and isset($desc['field'][$col]) |
|
| 2052 | - and $cle = array_search($desc['table'], $boucle->from) |
|
| 2053 | - ) { |
|
| 2054 | - $table = $cle; |
|
| 2055 | - } else { |
|
| 2056 | - $table = trouver_jointure_champ($col, $boucle, [$table], ($crit->cond or $op != '=')); |
|
| 2057 | - } |
|
| 2058 | - #$table = calculer_critere_externe_init($boucle, array($table), $col, $desc, ($crit->cond OR $op!='='), true); |
|
| 2059 | - if (!$table) { |
|
| 2060 | - return ''; |
|
| 2061 | - } |
|
| 2062 | - } |
|
| 2063 | - // si le champ n'est pas trouvé dans la table, |
|
| 2064 | - // on cherche si une jointure peut l'obtenir |
|
| 2065 | - elseif (@!array_key_exists($col, $desc['field'])) { |
|
| 2066 | - // Champ joker * des iterateurs DATA qui accepte tout |
|
| 2067 | - if (@array_key_exists('*', $desc['field'])) { |
|
| 2068 | - $desc['field'][$col_vraie ?: $col] = ''; // on veut pas de cast INT par defaut car le type peut etre n'importe quoi dans les boucles DATA |
|
| 2069 | - } |
|
| 2070 | - else { |
|
| 2071 | - $r = calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table); |
|
| 2072 | - if (!$r) { |
|
| 2073 | - return ''; |
|
| 2074 | - } |
|
| 2075 | - [$col, $col_alias, $table, $where_complement, $desc] = $r; |
|
| 2076 | - } |
|
| 2077 | - } |
|
| 2078 | - } |
|
| 2079 | - } |
|
| 2080 | - } |
|
| 2081 | - } |
|
| 2082 | - |
|
| 2083 | - $col_vraie = ($col_vraie ?: $col); |
|
| 2084 | - // Dans tous les cas, |
|
| 2085 | - // virer les guillemets eventuels autour d'un int (qui sont refuses par certains SQL) |
|
| 2086 | - // et passer dans sql_quote avec le type si connu |
|
| 2087 | - // et int sinon si la valeur est numerique |
|
| 2088 | - // sinon introduire le vrai type du champ si connu dans le sql_quote (ou int NOT NULL sinon) |
|
| 2089 | - // Ne pas utiliser intval, PHP tronquant les Bigint de SQL |
|
| 2090 | - if ($op == '=' or in_array($op, $GLOBALS['table_criteres_infixes'])) { |
|
| 2091 | - $type_cast_quote = ($desc['field'][$col_vraie] ?? 'int NOT NULL'); |
|
| 2092 | - // defaire le quote des int et les passer dans sql_quote avec le bon type de champ si on le connait, int sinon |
|
| 2093 | - // prendre en compte le debug ou la valeur arrive avec un commentaire PHP en debut |
|
| 2094 | - if (preg_match(",^\\A(\s*//.*?$\s*)?\"'(-?\d+)'\"\\z,ms", $val[0], $r)) { |
|
| 2095 | - $val[0] = $r[1] . '"' . sql_quote($r[2], $boucle->sql_serveur, $type_cast_quote) . '"'; |
|
| 2096 | - } |
|
| 2097 | - // sinon expliciter les |
|
| 2098 | - // sql_quote(truc) en sql_quote(truc,'',type) |
|
| 2099 | - // sql_quote(truc,serveur) en sql_quote(truc,serveur,type) |
|
| 2100 | - // sql_quote(truc,serveur,'') en sql_quote(truc,serveur,type) |
|
| 2101 | - // sans toucher aux |
|
| 2102 | - // sql_quote(truc,'','varchar(10) DEFAULT \'oui\' COLLATE NOCASE') |
|
| 2103 | - // sql_quote(truc,'','varchar') |
|
| 2104 | - elseif ( |
|
| 2105 | - preg_match('/\Asql_quote[(](.*?)(,[^)]*?)?(,[^)]*(?:\(\d+\)[^)]*)?)?[)]\s*\z/ms', $val[0], $r) |
|
| 2106 | - // si pas deja un type |
|
| 2107 | - and (!isset($r[3]) or !$r[3] or !trim($r[3], ", '")) |
|
| 2108 | - ) { |
|
| 2109 | - $r = $r[1] |
|
| 2110 | - . ((isset($r[2]) and $r[2]) ? $r[2] : ",''") |
|
| 2111 | - . ",'" . addslashes($type_cast_quote) . "'"; |
|
| 2112 | - $val[0] = "sql_quote($r)"; |
|
| 2113 | - } |
|
| 2114 | - elseif ( |
|
| 2115 | - strpos($val[0], '@@defaultcast@@') !== false |
|
| 2116 | - and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r) |
|
| 2117 | - ) { |
|
| 2118 | - $val[0] = substr($val[0], 0, -strlen($r[0])) . "'" . addslashes($type_cast_quote) . "')"; |
|
| 2119 | - } |
|
| 2120 | - } |
|
| 2121 | - |
|
| 2122 | - if ( |
|
| 2123 | - strpos($val[0], '@@defaultcast@@') !== false |
|
| 2124 | - and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r) |
|
| 2125 | - ) { |
|
| 2126 | - $val[0] = substr($val[0], 0, -strlen($r[0])) . "'char')"; |
|
| 2127 | - } |
|
| 2128 | - |
|
| 2129 | - // Indicateur pour permettre aux fonctionx boucle_X de modifier |
|
| 2130 | - // leurs requetes par defaut, notamment le champ statut |
|
| 2131 | - // Ne pas confondre champs de la table principale et des jointures |
|
| 2132 | - if ($table === $boucle->id_table) { |
|
| 2133 | - $boucles[$idb]->modificateur['criteres'][$col_vraie] = true; |
|
| 2134 | - if ($col_alias != $col_vraie) { |
|
| 2135 | - $boucles[$idb]->modificateur['criteres'][$col_alias] = true; |
|
| 2136 | - } |
|
| 2137 | - } |
|
| 2138 | - |
|
| 2139 | - // inserer le nom de la table SQL devant le nom du champ |
|
| 2140 | - if ($table) { |
|
| 2141 | - if ($col[0] == '`') { |
|
| 2142 | - $arg = "$table." . substr($col, 1, -1); |
|
| 2143 | - } else { |
|
| 2144 | - $arg = "$table.$col"; |
|
| 2145 | - } |
|
| 2146 | - } else { |
|
| 2147 | - $arg = $col; |
|
| 2148 | - } |
|
| 2149 | - |
|
| 2150 | - // inserer la fonction SQL |
|
| 2151 | - if ($fct) { |
|
| 2152 | - $arg = "$fct($arg$args_sql)"; |
|
| 2153 | - } |
|
| 2154 | - |
|
| 2155 | - return [$arg, $op, $val, $col_alias, $where_complement]; |
|
| 1997 | + $boucle = &$boucles[$idb]; |
|
| 1998 | + $type = $boucle->type_requete; |
|
| 1999 | + $table = $boucle->id_table ?? ''; |
|
| 2000 | + $desc = $boucle->show; |
|
| 2001 | + $col_vraie = null; |
|
| 2002 | + |
|
| 2003 | + [$fct, $col, $op, $val, $args_sql] = |
|
| 2004 | + calculer_critere_infixe_ops($idb, $boucles, $crit); |
|
| 2005 | + |
|
| 2006 | + $col_alias = $col; |
|
| 2007 | + $where_complement = false; |
|
| 2008 | + |
|
| 2009 | + // Cas particulier : id_enfant => utiliser la colonne id_objet |
|
| 2010 | + if ($col == 'id_enfant') { |
|
| 2011 | + $col = $boucle->primary; |
|
| 2012 | + } |
|
| 2013 | + |
|
| 2014 | + // Cas particulier : id_parent => verifier les exceptions de tables |
|
| 2015 | + if ( |
|
| 2016 | + (in_array($col, ['id_parent', 'id_secteur']) and isset($GLOBALS['exceptions_des_tables'][$table][$col])) |
|
| 2017 | + or (isset($GLOBALS['exceptions_des_tables'][$table][$col]) and is_string($GLOBALS['exceptions_des_tables'][$table][$col])) |
|
| 2018 | + ) { |
|
| 2019 | + $col = $GLOBALS['exceptions_des_tables'][$table][$col]; |
|
| 2020 | + } // et possibilite de gerer un critere secteur sur des tables de plugins (ie forums) |
|
| 2021 | + else { |
|
| 2022 | + if (($col == 'id_secteur') and ($critere_secteur = charger_fonction("critere_secteur_$type", 'public', true))) { |
|
| 2023 | + $table = $critere_secteur($idb, $boucles, $val, $crit); |
|
| 2024 | + } |
|
| 2025 | + |
|
| 2026 | + // cas id_article=xx qui se mappe en id_objet=xx AND objet=article |
|
| 2027 | + // sauf si exception declaree : sauter cette etape |
|
| 2028 | + else { |
|
| 2029 | + if ( |
|
| 2030 | + !isset($GLOBALS['exceptions_des_jointures'][table_objet_sql($table)][$col]) |
|
| 2031 | + and !isset($GLOBALS['exceptions_des_jointures'][$col]) |
|
| 2032 | + and count(trouver_champs_decomposes($col, $desc)) > 1 |
|
| 2033 | + ) { |
|
| 2034 | + $e = decompose_champ_id_objet($col); |
|
| 2035 | + $col = array_shift($e); |
|
| 2036 | + $where_complement = primary_doublee($e, $table); |
|
| 2037 | + } // Cas particulier : expressions de date |
|
| 2038 | + else { |
|
| 2039 | + if ($c = calculer_critere_infixe_date($idb, $boucles, $col)) { |
|
| 2040 | + [$col, $col_vraie] = $c; |
|
| 2041 | + $table = ''; |
|
| 2042 | + } // table explicitée {mots.titre} |
|
| 2043 | + else { |
|
| 2044 | + if (preg_match('/^(.*)\.(.*)$/', $col, $r)) { |
|
| 2045 | + [, $table, $col] = $r; |
|
| 2046 | + $col_alias = $col; |
|
| 2047 | + |
|
| 2048 | + $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 2049 | + if ( |
|
| 2050 | + $desc = $trouver_table($table, $boucle->sql_serveur) |
|
| 2051 | + and isset($desc['field'][$col]) |
|
| 2052 | + and $cle = array_search($desc['table'], $boucle->from) |
|
| 2053 | + ) { |
|
| 2054 | + $table = $cle; |
|
| 2055 | + } else { |
|
| 2056 | + $table = trouver_jointure_champ($col, $boucle, [$table], ($crit->cond or $op != '=')); |
|
| 2057 | + } |
|
| 2058 | + #$table = calculer_critere_externe_init($boucle, array($table), $col, $desc, ($crit->cond OR $op!='='), true); |
|
| 2059 | + if (!$table) { |
|
| 2060 | + return ''; |
|
| 2061 | + } |
|
| 2062 | + } |
|
| 2063 | + // si le champ n'est pas trouvé dans la table, |
|
| 2064 | + // on cherche si une jointure peut l'obtenir |
|
| 2065 | + elseif (@!array_key_exists($col, $desc['field'])) { |
|
| 2066 | + // Champ joker * des iterateurs DATA qui accepte tout |
|
| 2067 | + if (@array_key_exists('*', $desc['field'])) { |
|
| 2068 | + $desc['field'][$col_vraie ?: $col] = ''; // on veut pas de cast INT par defaut car le type peut etre n'importe quoi dans les boucles DATA |
|
| 2069 | + } |
|
| 2070 | + else { |
|
| 2071 | + $r = calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table); |
|
| 2072 | + if (!$r) { |
|
| 2073 | + return ''; |
|
| 2074 | + } |
|
| 2075 | + [$col, $col_alias, $table, $where_complement, $desc] = $r; |
|
| 2076 | + } |
|
| 2077 | + } |
|
| 2078 | + } |
|
| 2079 | + } |
|
| 2080 | + } |
|
| 2081 | + } |
|
| 2082 | + |
|
| 2083 | + $col_vraie = ($col_vraie ?: $col); |
|
| 2084 | + // Dans tous les cas, |
|
| 2085 | + // virer les guillemets eventuels autour d'un int (qui sont refuses par certains SQL) |
|
| 2086 | + // et passer dans sql_quote avec le type si connu |
|
| 2087 | + // et int sinon si la valeur est numerique |
|
| 2088 | + // sinon introduire le vrai type du champ si connu dans le sql_quote (ou int NOT NULL sinon) |
|
| 2089 | + // Ne pas utiliser intval, PHP tronquant les Bigint de SQL |
|
| 2090 | + if ($op == '=' or in_array($op, $GLOBALS['table_criteres_infixes'])) { |
|
| 2091 | + $type_cast_quote = ($desc['field'][$col_vraie] ?? 'int NOT NULL'); |
|
| 2092 | + // defaire le quote des int et les passer dans sql_quote avec le bon type de champ si on le connait, int sinon |
|
| 2093 | + // prendre en compte le debug ou la valeur arrive avec un commentaire PHP en debut |
|
| 2094 | + if (preg_match(",^\\A(\s*//.*?$\s*)?\"'(-?\d+)'\"\\z,ms", $val[0], $r)) { |
|
| 2095 | + $val[0] = $r[1] . '"' . sql_quote($r[2], $boucle->sql_serveur, $type_cast_quote) . '"'; |
|
| 2096 | + } |
|
| 2097 | + // sinon expliciter les |
|
| 2098 | + // sql_quote(truc) en sql_quote(truc,'',type) |
|
| 2099 | + // sql_quote(truc,serveur) en sql_quote(truc,serveur,type) |
|
| 2100 | + // sql_quote(truc,serveur,'') en sql_quote(truc,serveur,type) |
|
| 2101 | + // sans toucher aux |
|
| 2102 | + // sql_quote(truc,'','varchar(10) DEFAULT \'oui\' COLLATE NOCASE') |
|
| 2103 | + // sql_quote(truc,'','varchar') |
|
| 2104 | + elseif ( |
|
| 2105 | + preg_match('/\Asql_quote[(](.*?)(,[^)]*?)?(,[^)]*(?:\(\d+\)[^)]*)?)?[)]\s*\z/ms', $val[0], $r) |
|
| 2106 | + // si pas deja un type |
|
| 2107 | + and (!isset($r[3]) or !$r[3] or !trim($r[3], ", '")) |
|
| 2108 | + ) { |
|
| 2109 | + $r = $r[1] |
|
| 2110 | + . ((isset($r[2]) and $r[2]) ? $r[2] : ",''") |
|
| 2111 | + . ",'" . addslashes($type_cast_quote) . "'"; |
|
| 2112 | + $val[0] = "sql_quote($r)"; |
|
| 2113 | + } |
|
| 2114 | + elseif ( |
|
| 2115 | + strpos($val[0], '@@defaultcast@@') !== false |
|
| 2116 | + and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r) |
|
| 2117 | + ) { |
|
| 2118 | + $val[0] = substr($val[0], 0, -strlen($r[0])) . "'" . addslashes($type_cast_quote) . "')"; |
|
| 2119 | + } |
|
| 2120 | + } |
|
| 2121 | + |
|
| 2122 | + if ( |
|
| 2123 | + strpos($val[0], '@@defaultcast@@') !== false |
|
| 2124 | + and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r) |
|
| 2125 | + ) { |
|
| 2126 | + $val[0] = substr($val[0], 0, -strlen($r[0])) . "'char')"; |
|
| 2127 | + } |
|
| 2128 | + |
|
| 2129 | + // Indicateur pour permettre aux fonctionx boucle_X de modifier |
|
| 2130 | + // leurs requetes par defaut, notamment le champ statut |
|
| 2131 | + // Ne pas confondre champs de la table principale et des jointures |
|
| 2132 | + if ($table === $boucle->id_table) { |
|
| 2133 | + $boucles[$idb]->modificateur['criteres'][$col_vraie] = true; |
|
| 2134 | + if ($col_alias != $col_vraie) { |
|
| 2135 | + $boucles[$idb]->modificateur['criteres'][$col_alias] = true; |
|
| 2136 | + } |
|
| 2137 | + } |
|
| 2138 | + |
|
| 2139 | + // inserer le nom de la table SQL devant le nom du champ |
|
| 2140 | + if ($table) { |
|
| 2141 | + if ($col[0] == '`') { |
|
| 2142 | + $arg = "$table." . substr($col, 1, -1); |
|
| 2143 | + } else { |
|
| 2144 | + $arg = "$table.$col"; |
|
| 2145 | + } |
|
| 2146 | + } else { |
|
| 2147 | + $arg = $col; |
|
| 2148 | + } |
|
| 2149 | + |
|
| 2150 | + // inserer la fonction SQL |
|
| 2151 | + if ($fct) { |
|
| 2152 | + $arg = "$fct($arg$args_sql)"; |
|
| 2153 | + } |
|
| 2154 | + |
|
| 2155 | + return [$arg, $op, $val, $col_alias, $where_complement]; |
|
| 2156 | 2156 | } |
| 2157 | 2157 | |
| 2158 | 2158 | |
@@ -2181,77 +2181,77 @@ discard block |
||
| 2181 | 2181 | **/ |
| 2182 | 2182 | function calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table) { |
| 2183 | 2183 | |
| 2184 | - $where = ''; |
|
| 2185 | - |
|
| 2186 | - $calculer_critere_externe = 'calculer_critere_externe_init'; |
|
| 2187 | - // gestion par les plugins des jointures tordues |
|
| 2188 | - // pas automatiques mais necessaires |
|
| 2189 | - $table_sql = table_objet_sql($table); |
|
| 2190 | - if ( |
|
| 2191 | - isset($GLOBALS['exceptions_des_jointures'][$table_sql]) |
|
| 2192 | - and is_array($GLOBALS['exceptions_des_jointures'][$table_sql]) |
|
| 2193 | - and |
|
| 2194 | - ( |
|
| 2195 | - isset($GLOBALS['exceptions_des_jointures'][$table_sql][$col]) |
|
| 2196 | - or |
|
| 2197 | - isset($GLOBALS['exceptions_des_jointures'][$table_sql]['']) |
|
| 2198 | - ) |
|
| 2199 | - ) { |
|
| 2200 | - $t = $GLOBALS['exceptions_des_jointures'][$table_sql]; |
|
| 2201 | - $index = $t[$col] ?? $t[''] ?? []; |
|
| 2202 | - |
|
| 2203 | - if ((is_countable($index) ? count($index) : 0) == 3) { |
|
| 2204 | - [$t, $col, $calculer_critere_externe] = $index; |
|
| 2205 | - } elseif ((is_countable($index) ? count($index) : 0) == 2) { |
|
| 2206 | - [$t, $col] = $t[$col]; |
|
| 2207 | - } elseif ((is_countable($index) ? count($index) : 0) == 1) { |
|
| 2208 | - [$calculer_critere_externe] = $index; |
|
| 2209 | - $t = $table; |
|
| 2210 | - } else { |
|
| 2211 | - $t = ''; |
|
| 2212 | - } // jointure non declaree. La trouver. |
|
| 2213 | - } elseif (isset($GLOBALS['exceptions_des_jointures'][$col])) { |
|
| 2214 | - [$t, $col] = $GLOBALS['exceptions_des_jointures'][$col]; |
|
| 2215 | - } else { |
|
| 2216 | - $t = ''; |
|
| 2217 | - } // jointure non declaree. La trouver. |
|
| 2218 | - |
|
| 2219 | - // ici on construit le from pour fournir $col en piochant dans les jointures |
|
| 2220 | - |
|
| 2221 | - // si des jointures explicites sont fournies, on cherche d'abord dans celles ci |
|
| 2222 | - // permet de forcer une table de lien quand il y a ambiguite |
|
| 2223 | - // <BOUCLE_(DOCUMENTS documents_liens){id_mot}> |
|
| 2224 | - // alors que <BOUCLE_(DOCUMENTS){id_mot}> produit la meme chose que <BOUCLE_(DOCUMENTS mots_liens){id_mot}> |
|
| 2225 | - $table = ''; |
|
| 2226 | - if ($boucle->jointures_explicites) { |
|
| 2227 | - $jointures_explicites = explode(' ', $boucle->jointures_explicites); |
|
| 2228 | - $table = $calculer_critere_externe($boucle, $jointures_explicites, $col, $desc, ($crit->cond or $op != '='), $t); |
|
| 2229 | - } |
|
| 2230 | - |
|
| 2231 | - // et sinon on cherche parmi toutes les jointures declarees |
|
| 2232 | - if (!$table) { |
|
| 2233 | - $table = $calculer_critere_externe($boucle, $boucle->jointures, $col, $desc, ($crit->cond or $op != '='), $t); |
|
| 2234 | - } |
|
| 2235 | - |
|
| 2236 | - if (!$table) { |
|
| 2237 | - return ''; |
|
| 2238 | - } |
|
| 2239 | - |
|
| 2240 | - // il ne reste plus qu'a trouver le champ dans les from |
|
| 2241 | - [$nom, $desc, $cle] = trouver_champ_exterieur($col, $boucle->from, $boucle); |
|
| 2242 | - |
|
| 2243 | - if ((is_countable($cle) ? count($cle) : 0) > 1 or reset($cle) !== $col) { |
|
| 2244 | - $col_alias = $col; // id_article devient juste le nom d'origine |
|
| 2245 | - if ((is_countable($cle) ? count($cle) : 0) > 1 and reset($cle) == 'id_objet') { |
|
| 2246 | - $e = decompose_champ_id_objet($col); |
|
| 2247 | - $col = array_shift($e); |
|
| 2248 | - $where = primary_doublee($e, $table); |
|
| 2249 | - } else { |
|
| 2250 | - $col = reset($cle); |
|
| 2251 | - } |
|
| 2252 | - } |
|
| 2253 | - |
|
| 2254 | - return [$col, $col_alias, $table, $where, $desc]; |
|
| 2184 | + $where = ''; |
|
| 2185 | + |
|
| 2186 | + $calculer_critere_externe = 'calculer_critere_externe_init'; |
|
| 2187 | + // gestion par les plugins des jointures tordues |
|
| 2188 | + // pas automatiques mais necessaires |
|
| 2189 | + $table_sql = table_objet_sql($table); |
|
| 2190 | + if ( |
|
| 2191 | + isset($GLOBALS['exceptions_des_jointures'][$table_sql]) |
|
| 2192 | + and is_array($GLOBALS['exceptions_des_jointures'][$table_sql]) |
|
| 2193 | + and |
|
| 2194 | + ( |
|
| 2195 | + isset($GLOBALS['exceptions_des_jointures'][$table_sql][$col]) |
|
| 2196 | + or |
|
| 2197 | + isset($GLOBALS['exceptions_des_jointures'][$table_sql]['']) |
|
| 2198 | + ) |
|
| 2199 | + ) { |
|
| 2200 | + $t = $GLOBALS['exceptions_des_jointures'][$table_sql]; |
|
| 2201 | + $index = $t[$col] ?? $t[''] ?? []; |
|
| 2202 | + |
|
| 2203 | + if ((is_countable($index) ? count($index) : 0) == 3) { |
|
| 2204 | + [$t, $col, $calculer_critere_externe] = $index; |
|
| 2205 | + } elseif ((is_countable($index) ? count($index) : 0) == 2) { |
|
| 2206 | + [$t, $col] = $t[$col]; |
|
| 2207 | + } elseif ((is_countable($index) ? count($index) : 0) == 1) { |
|
| 2208 | + [$calculer_critere_externe] = $index; |
|
| 2209 | + $t = $table; |
|
| 2210 | + } else { |
|
| 2211 | + $t = ''; |
|
| 2212 | + } // jointure non declaree. La trouver. |
|
| 2213 | + } elseif (isset($GLOBALS['exceptions_des_jointures'][$col])) { |
|
| 2214 | + [$t, $col] = $GLOBALS['exceptions_des_jointures'][$col]; |
|
| 2215 | + } else { |
|
| 2216 | + $t = ''; |
|
| 2217 | + } // jointure non declaree. La trouver. |
|
| 2218 | + |
|
| 2219 | + // ici on construit le from pour fournir $col en piochant dans les jointures |
|
| 2220 | + |
|
| 2221 | + // si des jointures explicites sont fournies, on cherche d'abord dans celles ci |
|
| 2222 | + // permet de forcer une table de lien quand il y a ambiguite |
|
| 2223 | + // <BOUCLE_(DOCUMENTS documents_liens){id_mot}> |
|
| 2224 | + // alors que <BOUCLE_(DOCUMENTS){id_mot}> produit la meme chose que <BOUCLE_(DOCUMENTS mots_liens){id_mot}> |
|
| 2225 | + $table = ''; |
|
| 2226 | + if ($boucle->jointures_explicites) { |
|
| 2227 | + $jointures_explicites = explode(' ', $boucle->jointures_explicites); |
|
| 2228 | + $table = $calculer_critere_externe($boucle, $jointures_explicites, $col, $desc, ($crit->cond or $op != '='), $t); |
|
| 2229 | + } |
|
| 2230 | + |
|
| 2231 | + // et sinon on cherche parmi toutes les jointures declarees |
|
| 2232 | + if (!$table) { |
|
| 2233 | + $table = $calculer_critere_externe($boucle, $boucle->jointures, $col, $desc, ($crit->cond or $op != '='), $t); |
|
| 2234 | + } |
|
| 2235 | + |
|
| 2236 | + if (!$table) { |
|
| 2237 | + return ''; |
|
| 2238 | + } |
|
| 2239 | + |
|
| 2240 | + // il ne reste plus qu'a trouver le champ dans les from |
|
| 2241 | + [$nom, $desc, $cle] = trouver_champ_exterieur($col, $boucle->from, $boucle); |
|
| 2242 | + |
|
| 2243 | + if ((is_countable($cle) ? count($cle) : 0) > 1 or reset($cle) !== $col) { |
|
| 2244 | + $col_alias = $col; // id_article devient juste le nom d'origine |
|
| 2245 | + if ((is_countable($cle) ? count($cle) : 0) > 1 and reset($cle) == 'id_objet') { |
|
| 2246 | + $e = decompose_champ_id_objet($col); |
|
| 2247 | + $col = array_shift($e); |
|
| 2248 | + $where = primary_doublee($e, $table); |
|
| 2249 | + } else { |
|
| 2250 | + $col = reset($cle); |
|
| 2251 | + } |
|
| 2252 | + } |
|
| 2253 | + |
|
| 2254 | + return [$col, $col_alias, $table, $where, $desc]; |
|
| 2255 | 2255 | } |
| 2256 | 2256 | |
| 2257 | 2257 | |
@@ -2272,10 +2272,10 @@ discard block |
||
| 2272 | 2272 | * - valeur |
| 2273 | 2273 | **/ |
| 2274 | 2274 | function primary_doublee($decompose, $table) { |
| 2275 | - $e1 = reset($decompose); |
|
| 2276 | - $e2 = "sql_quote('" . end($decompose) . "')"; |
|
| 2275 | + $e1 = reset($decompose); |
|
| 2276 | + $e2 = "sql_quote('" . end($decompose) . "')"; |
|
| 2277 | 2277 | |
| 2278 | - return ["'='", "'$table." . $e1 . "'", $e2]; |
|
| 2278 | + return ["'='", "'$table." . $e1 . "'", $e2]; |
|
| 2279 | 2279 | } |
| 2280 | 2280 | |
| 2281 | 2281 | /** |
@@ -2306,57 +2306,57 @@ discard block |
||
| 2306 | 2306 | * Vide sinon. |
| 2307 | 2307 | */ |
| 2308 | 2308 | function calculer_critere_externe_init(&$boucle, $joints, $col, $desc, $cond, $checkarrivee = false) { |
| 2309 | - // si on demande un truc du genre spip_mots |
|
| 2310 | - // avec aussi spip_mots_liens dans les jointures dispo |
|
| 2311 | - // et qu'on est la |
|
| 2312 | - // il faut privilegier la jointure directe en 2 etapes spip_mots_liens, spip_mots |
|
| 2313 | - if ( |
|
| 2314 | - $checkarrivee |
|
| 2315 | - and is_string($checkarrivee) |
|
| 2316 | - and $a = table_objet($checkarrivee) |
|
| 2317 | - and in_array($a . '_liens', $joints) |
|
| 2318 | - ) { |
|
| 2319 | - if ($res = calculer_lien_externe_init($boucle, $joints, $col, $desc, $cond, $checkarrivee)) { |
|
| 2320 | - return $res; |
|
| 2321 | - } |
|
| 2322 | - } |
|
| 2323 | - foreach ($joints as $joint) { |
|
| 2324 | - if ($arrivee = trouver_champ_exterieur($col, [$joint], $boucle, $checkarrivee)) { |
|
| 2325 | - // alias de table dans le from |
|
| 2326 | - $t = array_search($arrivee[0], $boucle->from); |
|
| 2327 | - // recuperer la cle id_xx eventuellement decomposee en (id_objet,objet) |
|
| 2328 | - $cols = $arrivee[2]; |
|
| 2329 | - // mais on ignore la 3eme cle si presente qui correspond alors au point de depart |
|
| 2330 | - if ((is_countable($cols) ? count($cols) : 0) > 2) { |
|
| 2331 | - array_pop($cols); |
|
| 2332 | - } |
|
| 2333 | - if ($t) { |
|
| 2334 | - // la table est déjà dans le FROM, on vérifie si le champ est utilisé. |
|
| 2335 | - $joindre = false; |
|
| 2336 | - foreach ($cols as $col) { |
|
| 2337 | - $c = '/\b' . $t . ".$col" . '\b/'; |
|
| 2338 | - if (trouver_champ($c, $boucle->where)) { |
|
| 2339 | - $joindre = true; |
|
| 2340 | - } else { |
|
| 2341 | - // mais ca peut etre dans le FIELD pour le Having |
|
| 2342 | - $c = "/FIELD.$t" . ".$col,/"; |
|
| 2343 | - if (trouver_champ($c, $boucle->select)) { |
|
| 2344 | - $joindre = true; |
|
| 2345 | - } |
|
| 2346 | - } |
|
| 2347 | - } |
|
| 2348 | - if (!$joindre) { |
|
| 2349 | - return $t; |
|
| 2350 | - } |
|
| 2351 | - } |
|
| 2352 | - array_pop($arrivee); |
|
| 2353 | - if ($res = calculer_jointure($boucle, [$boucle->id_table, $desc], $arrivee, $cols, $cond, 1)) { |
|
| 2354 | - return $res; |
|
| 2355 | - } |
|
| 2356 | - } |
|
| 2357 | - } |
|
| 2358 | - |
|
| 2359 | - return ''; |
|
| 2309 | + // si on demande un truc du genre spip_mots |
|
| 2310 | + // avec aussi spip_mots_liens dans les jointures dispo |
|
| 2311 | + // et qu'on est la |
|
| 2312 | + // il faut privilegier la jointure directe en 2 etapes spip_mots_liens, spip_mots |
|
| 2313 | + if ( |
|
| 2314 | + $checkarrivee |
|
| 2315 | + and is_string($checkarrivee) |
|
| 2316 | + and $a = table_objet($checkarrivee) |
|
| 2317 | + and in_array($a . '_liens', $joints) |
|
| 2318 | + ) { |
|
| 2319 | + if ($res = calculer_lien_externe_init($boucle, $joints, $col, $desc, $cond, $checkarrivee)) { |
|
| 2320 | + return $res; |
|
| 2321 | + } |
|
| 2322 | + } |
|
| 2323 | + foreach ($joints as $joint) { |
|
| 2324 | + if ($arrivee = trouver_champ_exterieur($col, [$joint], $boucle, $checkarrivee)) { |
|
| 2325 | + // alias de table dans le from |
|
| 2326 | + $t = array_search($arrivee[0], $boucle->from); |
|
| 2327 | + // recuperer la cle id_xx eventuellement decomposee en (id_objet,objet) |
|
| 2328 | + $cols = $arrivee[2]; |
|
| 2329 | + // mais on ignore la 3eme cle si presente qui correspond alors au point de depart |
|
| 2330 | + if ((is_countable($cols) ? count($cols) : 0) > 2) { |
|
| 2331 | + array_pop($cols); |
|
| 2332 | + } |
|
| 2333 | + if ($t) { |
|
| 2334 | + // la table est déjà dans le FROM, on vérifie si le champ est utilisé. |
|
| 2335 | + $joindre = false; |
|
| 2336 | + foreach ($cols as $col) { |
|
| 2337 | + $c = '/\b' . $t . ".$col" . '\b/'; |
|
| 2338 | + if (trouver_champ($c, $boucle->where)) { |
|
| 2339 | + $joindre = true; |
|
| 2340 | + } else { |
|
| 2341 | + // mais ca peut etre dans le FIELD pour le Having |
|
| 2342 | + $c = "/FIELD.$t" . ".$col,/"; |
|
| 2343 | + if (trouver_champ($c, $boucle->select)) { |
|
| 2344 | + $joindre = true; |
|
| 2345 | + } |
|
| 2346 | + } |
|
| 2347 | + } |
|
| 2348 | + if (!$joindre) { |
|
| 2349 | + return $t; |
|
| 2350 | + } |
|
| 2351 | + } |
|
| 2352 | + array_pop($arrivee); |
|
| 2353 | + if ($res = calculer_jointure($boucle, [$boucle->id_table, $desc], $arrivee, $cols, $cond, 1)) { |
|
| 2354 | + return $res; |
|
| 2355 | + } |
|
| 2356 | + } |
|
| 2357 | + } |
|
| 2358 | + |
|
| 2359 | + return ''; |
|
| 2360 | 2360 | } |
| 2361 | 2361 | |
| 2362 | 2362 | /** |
@@ -2382,35 +2382,35 @@ discard block |
||
| 2382 | 2382 | * Alias de la table de jointure (Lx) |
| 2383 | 2383 | */ |
| 2384 | 2384 | function calculer_lien_externe_init(&$boucle, $joints, $col, $desc, $cond, $checkarrivee = false) { |
| 2385 | - $primary_arrivee = id_table_objet($checkarrivee); |
|
| 2386 | - |
|
| 2387 | - // [FIXME] $checkarrivee peut-il arriver avec false ???? |
|
| 2388 | - $intermediaire = trouver_champ_exterieur($primary_arrivee, $joints, $boucle, $checkarrivee . '_liens'); |
|
| 2389 | - $arrivee = trouver_champ_exterieur($col, $joints, $boucle, $checkarrivee); |
|
| 2390 | - |
|
| 2391 | - if (!$intermediaire or !$arrivee) { |
|
| 2392 | - return ''; |
|
| 2393 | - } |
|
| 2394 | - array_pop($intermediaire); // enlever la cle en 3eme argument |
|
| 2395 | - array_pop($arrivee); // enlever la cle en 3eme argument |
|
| 2396 | - |
|
| 2397 | - $res = fabrique_jointures( |
|
| 2398 | - $boucle, |
|
| 2399 | - [ |
|
| 2400 | - [ |
|
| 2401 | - $boucle->id_table, |
|
| 2402 | - $intermediaire, |
|
| 2403 | - [id_table_objet($desc['table_objet']), 'id_objet', 'objet', $desc['type']] |
|
| 2404 | - ], |
|
| 2405 | - [reset($intermediaire), $arrivee, $primary_arrivee] |
|
| 2406 | - ], |
|
| 2407 | - $cond, |
|
| 2408 | - $desc, |
|
| 2409 | - $boucle->id_table, |
|
| 2410 | - [$col] |
|
| 2411 | - ); |
|
| 2412 | - |
|
| 2413 | - return $res; |
|
| 2385 | + $primary_arrivee = id_table_objet($checkarrivee); |
|
| 2386 | + |
|
| 2387 | + // [FIXME] $checkarrivee peut-il arriver avec false ???? |
|
| 2388 | + $intermediaire = trouver_champ_exterieur($primary_arrivee, $joints, $boucle, $checkarrivee . '_liens'); |
|
| 2389 | + $arrivee = trouver_champ_exterieur($col, $joints, $boucle, $checkarrivee); |
|
| 2390 | + |
|
| 2391 | + if (!$intermediaire or !$arrivee) { |
|
| 2392 | + return ''; |
|
| 2393 | + } |
|
| 2394 | + array_pop($intermediaire); // enlever la cle en 3eme argument |
|
| 2395 | + array_pop($arrivee); // enlever la cle en 3eme argument |
|
| 2396 | + |
|
| 2397 | + $res = fabrique_jointures( |
|
| 2398 | + $boucle, |
|
| 2399 | + [ |
|
| 2400 | + [ |
|
| 2401 | + $boucle->id_table, |
|
| 2402 | + $intermediaire, |
|
| 2403 | + [id_table_objet($desc['table_objet']), 'id_objet', 'objet', $desc['type']] |
|
| 2404 | + ], |
|
| 2405 | + [reset($intermediaire), $arrivee, $primary_arrivee] |
|
| 2406 | + ], |
|
| 2407 | + $cond, |
|
| 2408 | + $desc, |
|
| 2409 | + $boucle->id_table, |
|
| 2410 | + [$col] |
|
| 2411 | + ); |
|
| 2412 | + |
|
| 2413 | + return $res; |
|
| 2414 | 2414 | } |
| 2415 | 2415 | |
| 2416 | 2416 | |
@@ -2427,17 +2427,17 @@ discard block |
||
| 2427 | 2427 | * false sinon. |
| 2428 | 2428 | **/ |
| 2429 | 2429 | function trouver_champ($champ, $where) { |
| 2430 | - if (!is_array($where)) { |
|
| 2431 | - return preg_match($champ, $where); |
|
| 2432 | - } else { |
|
| 2433 | - foreach ($where as $clause) { |
|
| 2434 | - if (trouver_champ($champ, $clause)) { |
|
| 2435 | - return true; |
|
| 2436 | - } |
|
| 2437 | - } |
|
| 2438 | - |
|
| 2439 | - return false; |
|
| 2440 | - } |
|
| 2430 | + if (!is_array($where)) { |
|
| 2431 | + return preg_match($champ, $where); |
|
| 2432 | + } else { |
|
| 2433 | + foreach ($where as $clause) { |
|
| 2434 | + if (trouver_champ($champ, $clause)) { |
|
| 2435 | + return true; |
|
| 2436 | + } |
|
| 2437 | + } |
|
| 2438 | + |
|
| 2439 | + return false; |
|
| 2440 | + } |
|
| 2441 | 2441 | } |
| 2442 | 2442 | |
| 2443 | 2443 | |
@@ -2463,129 +2463,129 @@ discard block |
||
| 2463 | 2463 | * - string $args_sql Suite des arguments du critère. ? |
| 2464 | 2464 | **/ |
| 2465 | 2465 | function calculer_critere_infixe_ops($idb, &$boucles, $crit) { |
| 2466 | - // cas d'une valeur comparee a elle-meme ou son referent |
|
| 2467 | - if (count($crit->param) == 0) { |
|
| 2468 | - $op = '='; |
|
| 2469 | - $col = $val = $crit->op; |
|
| 2470 | - if (preg_match('/^(.*)\.(.*)$/', $col, $r)) { |
|
| 2471 | - $val = $r[2]; |
|
| 2472 | - } |
|
| 2473 | - // Cas special {lang} : aller chercher $GLOBALS['spip_lang'] |
|
| 2474 | - if ($val == 'lang') { |
|
| 2475 | - $val = [kwote('$GLOBALS[\'spip_lang\']')]; |
|
| 2476 | - } else { |
|
| 2477 | - $defaut = null; |
|
| 2478 | - if ($val == 'id_parent') { |
|
| 2479 | - // Si id_parent, comparer l'id_parent avec l'id_objet |
|
| 2480 | - // de la boucle superieure.... faudrait verifier qu'il existe |
|
| 2481 | - // pour eviter l'erreur SQL |
|
| 2482 | - $val = $boucles[$idb]->primary; |
|
| 2483 | - // mais si pas de boucle superieure, prendre id_parent dans l'env |
|
| 2484 | - $defaut = "(\$Pile[0]['id_parent'] ?? null)"; |
|
| 2485 | - } elseif ($val == 'id_enfant') { |
|
| 2486 | - // Si id_enfant, comparer l'id_objet avec l'id_parent |
|
| 2487 | - // de la boucle superieure |
|
| 2488 | - $val = 'id_parent'; |
|
| 2489 | - } elseif ($crit->cond and ($col == 'date' or $col == 'date_redac')) { |
|
| 2490 | - // un critere conditionnel sur date est traite a part |
|
| 2491 | - // car la date est mise d'office par SPIP, |
|
| 2492 | - $defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])"; |
|
| 2493 | - } |
|
| 2494 | - |
|
| 2495 | - $val = calculer_argument_precedent($idb, $val, $boucles, $defaut); |
|
| 2496 | - $val = [kwote($val)]; |
|
| 2497 | - } |
|
| 2498 | - } else { |
|
| 2499 | - // comparaison explicite |
|
| 2500 | - // le phraseur impose que le premier param soit du texte |
|
| 2501 | - $params = $crit->param; |
|
| 2502 | - $op = $crit->op; |
|
| 2503 | - if ($op == '==') { |
|
| 2504 | - $op = 'REGEXP'; |
|
| 2505 | - } |
|
| 2506 | - $col = array_shift($params); |
|
| 2507 | - $col = $col[0]->texte; |
|
| 2508 | - |
|
| 2509 | - $val = []; |
|
| 2510 | - $parent = $boucles[$idb]->id_parent; |
|
| 2511 | - |
|
| 2512 | - // Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur, |
|
| 2513 | - // celui ne sachant pas ce qu'est un critere infixe |
|
| 2514 | - // et a fortiori son 2e operande qu'entoure " ou ' |
|
| 2515 | - if ( |
|
| 2516 | - count($params) == 1 |
|
| 2517 | - and (is_countable($params[0]) ? count($params[0]) : 0) == 3 |
|
| 2518 | - and $params[0][0]->type == 'texte' |
|
| 2519 | - and $params[0][2]->type == 'texte' |
|
| 2520 | - and ($p = $params[0][0]->texte) == $params[0][2]->texte |
|
| 2521 | - and (($p == "'") or ($p == '"')) |
|
| 2522 | - and $params[0][1]->type == 'champ' |
|
| 2523 | - ) { |
|
| 2524 | - $val[] = "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p"; |
|
| 2525 | - } else { |
|
| 2526 | - foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) { |
|
| 2527 | - $a = calculer_liste($p, $idb, $boucles, $parent); |
|
| 2528 | - if (strcasecmp($op, 'IN') == 0) { |
|
| 2529 | - $val[] = $a; |
|
| 2530 | - } else { |
|
| 2531 | - $val[] = kwote($a, $boucles[$idb]->sql_serveur, '@@defaultcast@@'); |
|
| 2532 | - } // toujours quoter en char ici |
|
| 2533 | - } |
|
| 2534 | - } |
|
| 2535 | - } |
|
| 2536 | - |
|
| 2537 | - $fct = $args_sql = ''; |
|
| 2538 | - // fonction SQL ? |
|
| 2539 | - // chercher FONCTION(champ) tel que CONCAT(titre,descriptif) |
|
| 2540 | - if (preg_match('/^(.*)' . SQL_ARGS . '$/', $col, $m)) { |
|
| 2541 | - $fct = $m[1]; |
|
| 2542 | - preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a); |
|
| 2543 | - $col = $a[1]; |
|
| 2544 | - if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) { |
|
| 2545 | - $col = $m[1]; |
|
| 2546 | - $args_sql = $m[2]; |
|
| 2547 | - } |
|
| 2548 | - $args_sql .= $a[2]; |
|
| 2549 | - } |
|
| 2550 | - |
|
| 2551 | - return [$fct, $col, $op, $val, $args_sql]; |
|
| 2466 | + // cas d'une valeur comparee a elle-meme ou son referent |
|
| 2467 | + if (count($crit->param) == 0) { |
|
| 2468 | + $op = '='; |
|
| 2469 | + $col = $val = $crit->op; |
|
| 2470 | + if (preg_match('/^(.*)\.(.*)$/', $col, $r)) { |
|
| 2471 | + $val = $r[2]; |
|
| 2472 | + } |
|
| 2473 | + // Cas special {lang} : aller chercher $GLOBALS['spip_lang'] |
|
| 2474 | + if ($val == 'lang') { |
|
| 2475 | + $val = [kwote('$GLOBALS[\'spip_lang\']')]; |
|
| 2476 | + } else { |
|
| 2477 | + $defaut = null; |
|
| 2478 | + if ($val == 'id_parent') { |
|
| 2479 | + // Si id_parent, comparer l'id_parent avec l'id_objet |
|
| 2480 | + // de la boucle superieure.... faudrait verifier qu'il existe |
|
| 2481 | + // pour eviter l'erreur SQL |
|
| 2482 | + $val = $boucles[$idb]->primary; |
|
| 2483 | + // mais si pas de boucle superieure, prendre id_parent dans l'env |
|
| 2484 | + $defaut = "(\$Pile[0]['id_parent'] ?? null)"; |
|
| 2485 | + } elseif ($val == 'id_enfant') { |
|
| 2486 | + // Si id_enfant, comparer l'id_objet avec l'id_parent |
|
| 2487 | + // de la boucle superieure |
|
| 2488 | + $val = 'id_parent'; |
|
| 2489 | + } elseif ($crit->cond and ($col == 'date' or $col == 'date_redac')) { |
|
| 2490 | + // un critere conditionnel sur date est traite a part |
|
| 2491 | + // car la date est mise d'office par SPIP, |
|
| 2492 | + $defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])"; |
|
| 2493 | + } |
|
| 2494 | + |
|
| 2495 | + $val = calculer_argument_precedent($idb, $val, $boucles, $defaut); |
|
| 2496 | + $val = [kwote($val)]; |
|
| 2497 | + } |
|
| 2498 | + } else { |
|
| 2499 | + // comparaison explicite |
|
| 2500 | + // le phraseur impose que le premier param soit du texte |
|
| 2501 | + $params = $crit->param; |
|
| 2502 | + $op = $crit->op; |
|
| 2503 | + if ($op == '==') { |
|
| 2504 | + $op = 'REGEXP'; |
|
| 2505 | + } |
|
| 2506 | + $col = array_shift($params); |
|
| 2507 | + $col = $col[0]->texte; |
|
| 2508 | + |
|
| 2509 | + $val = []; |
|
| 2510 | + $parent = $boucles[$idb]->id_parent; |
|
| 2511 | + |
|
| 2512 | + // Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur, |
|
| 2513 | + // celui ne sachant pas ce qu'est un critere infixe |
|
| 2514 | + // et a fortiori son 2e operande qu'entoure " ou ' |
|
| 2515 | + if ( |
|
| 2516 | + count($params) == 1 |
|
| 2517 | + and (is_countable($params[0]) ? count($params[0]) : 0) == 3 |
|
| 2518 | + and $params[0][0]->type == 'texte' |
|
| 2519 | + and $params[0][2]->type == 'texte' |
|
| 2520 | + and ($p = $params[0][0]->texte) == $params[0][2]->texte |
|
| 2521 | + and (($p == "'") or ($p == '"')) |
|
| 2522 | + and $params[0][1]->type == 'champ' |
|
| 2523 | + ) { |
|
| 2524 | + $val[] = "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p"; |
|
| 2525 | + } else { |
|
| 2526 | + foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) { |
|
| 2527 | + $a = calculer_liste($p, $idb, $boucles, $parent); |
|
| 2528 | + if (strcasecmp($op, 'IN') == 0) { |
|
| 2529 | + $val[] = $a; |
|
| 2530 | + } else { |
|
| 2531 | + $val[] = kwote($a, $boucles[$idb]->sql_serveur, '@@defaultcast@@'); |
|
| 2532 | + } // toujours quoter en char ici |
|
| 2533 | + } |
|
| 2534 | + } |
|
| 2535 | + } |
|
| 2536 | + |
|
| 2537 | + $fct = $args_sql = ''; |
|
| 2538 | + // fonction SQL ? |
|
| 2539 | + // chercher FONCTION(champ) tel que CONCAT(titre,descriptif) |
|
| 2540 | + if (preg_match('/^(.*)' . SQL_ARGS . '$/', $col, $m)) { |
|
| 2541 | + $fct = $m[1]; |
|
| 2542 | + preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a); |
|
| 2543 | + $col = $a[1]; |
|
| 2544 | + if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) { |
|
| 2545 | + $col = $m[1]; |
|
| 2546 | + $args_sql = $m[2]; |
|
| 2547 | + } |
|
| 2548 | + $args_sql .= $a[2]; |
|
| 2549 | + } |
|
| 2550 | + |
|
| 2551 | + return [$fct, $col, $op, $val, $args_sql]; |
|
| 2552 | 2552 | } |
| 2553 | 2553 | |
| 2554 | 2554 | // compatibilite ancienne version |
| 2555 | 2555 | |
| 2556 | 2556 | function calculer_vieux_in($params) { |
| 2557 | - $deb = $params[0][0]; |
|
| 2558 | - $k = (is_countable($params) ? count($params) : 0) - 1; |
|
| 2559 | - $last = $params[$k]; |
|
| 2560 | - $j = (is_countable($last) ? count($last) : 0) - 1; |
|
| 2561 | - $last = $last[$j]; |
|
| 2562 | - $n = isset($last->texte) ? strlen($last->texte) : 0; |
|
| 2563 | - |
|
| 2564 | - if ( |
|
| 2565 | - !((isset($deb->texte[0]) and $deb->texte[0] == '(') |
|
| 2566 | - && (isset($last->texte[$n - 1]) and $last->texte[$n - 1] == ')')) |
|
| 2567 | - ) { |
|
| 2568 | - return $params; |
|
| 2569 | - } |
|
| 2570 | - $params[0][0]->texte = substr($deb->texte, 1); |
|
| 2571 | - // attention, on peut avoir k=0,j=0 ==> recalculer |
|
| 2572 | - $last = $params[$k][$j]; |
|
| 2573 | - $n = strlen($last->texte); |
|
| 2574 | - $params[$k][$j]->texte = substr($last->texte, 0, $n - 1); |
|
| 2575 | - $newp = []; |
|
| 2576 | - foreach ($params as $v) { |
|
| 2577 | - if ($v[0]->type != 'texte') { |
|
| 2578 | - $newp[] = $v; |
|
| 2579 | - } else { |
|
| 2580 | - foreach (explode(',', $v[0]->texte) as $x) { |
|
| 2581 | - $t = new Texte(); |
|
| 2582 | - $t->texte = $x; |
|
| 2583 | - $newp[] = [$t]; |
|
| 2584 | - } |
|
| 2585 | - } |
|
| 2586 | - } |
|
| 2587 | - |
|
| 2588 | - return $newp; |
|
| 2557 | + $deb = $params[0][0]; |
|
| 2558 | + $k = (is_countable($params) ? count($params) : 0) - 1; |
|
| 2559 | + $last = $params[$k]; |
|
| 2560 | + $j = (is_countable($last) ? count($last) : 0) - 1; |
|
| 2561 | + $last = $last[$j]; |
|
| 2562 | + $n = isset($last->texte) ? strlen($last->texte) : 0; |
|
| 2563 | + |
|
| 2564 | + if ( |
|
| 2565 | + !((isset($deb->texte[0]) and $deb->texte[0] == '(') |
|
| 2566 | + && (isset($last->texte[$n - 1]) and $last->texte[$n - 1] == ')')) |
|
| 2567 | + ) { |
|
| 2568 | + return $params; |
|
| 2569 | + } |
|
| 2570 | + $params[0][0]->texte = substr($deb->texte, 1); |
|
| 2571 | + // attention, on peut avoir k=0,j=0 ==> recalculer |
|
| 2572 | + $last = $params[$k][$j]; |
|
| 2573 | + $n = strlen($last->texte); |
|
| 2574 | + $params[$k][$j]->texte = substr($last->texte, 0, $n - 1); |
|
| 2575 | + $newp = []; |
|
| 2576 | + foreach ($params as $v) { |
|
| 2577 | + if ($v[0]->type != 'texte') { |
|
| 2578 | + $newp[] = $v; |
|
| 2579 | + } else { |
|
| 2580 | + foreach (explode(',', $v[0]->texte) as $x) { |
|
| 2581 | + $t = new Texte(); |
|
| 2582 | + $t->texte = $x; |
|
| 2583 | + $newp[] = [$t]; |
|
| 2584 | + } |
|
| 2585 | + } |
|
| 2586 | + } |
|
| 2587 | + |
|
| 2588 | + return $newp; |
|
| 2589 | 2589 | } |
| 2590 | 2590 | |
| 2591 | 2591 | /** |
@@ -2604,89 +2604,89 @@ discard block |
||
| 2604 | 2604 | * - nom de la colonne de date (si le calcul n'est pas relatif) |
| 2605 | 2605 | **/ |
| 2606 | 2606 | function calculer_critere_infixe_date($idb, &$boucles, $col) { |
| 2607 | - if (!preg_match(',^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z_]+)?$,', $col, $regs)) { |
|
| 2608 | - return ''; |
|
| 2609 | - } |
|
| 2610 | - |
|
| 2611 | - $boucle = $boucles[$idb]; |
|
| 2612 | - $table = $boucle->show; |
|
| 2613 | - |
|
| 2614 | - // si c'est une colonne de la table, ne rien faire |
|
| 2615 | - if (isset($table['field'][$col])) { |
|
| 2616 | - return ''; |
|
| 2617 | - } |
|
| 2618 | - |
|
| 2619 | - if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) { |
|
| 2620 | - return ''; |
|
| 2621 | - } |
|
| 2622 | - $pred = $date_orig = $GLOBALS['table_date'][$table['id_table']] ?? $table['date']; |
|
| 2623 | - |
|
| 2624 | - $col = $regs[1]; |
|
| 2625 | - if (isset($regs[3]) and $suite = $regs[3]) { |
|
| 2626 | - # Recherche de l'existence du champ date_xxxx, |
|
| 2627 | - # si oui choisir ce champ, sinon choisir xxxx |
|
| 2628 | - |
|
| 2629 | - if (isset($table['field']["date$suite"])) { |
|
| 2630 | - $date_orig = 'date' . $suite; |
|
| 2631 | - } else { |
|
| 2632 | - $date_orig = substr($suite, 1); |
|
| 2633 | - } |
|
| 2634 | - $pred = $date_orig; |
|
| 2635 | - } else { |
|
| 2636 | - if (isset($regs[2]) and $rel = $regs[2]) { |
|
| 2637 | - $pred = 'date'; |
|
| 2638 | - } |
|
| 2639 | - } |
|
| 2640 | - |
|
| 2641 | - $date_compare = "\"' . normaliser_date(" . |
|
| 2642 | - calculer_argument_precedent($idb, $pred, $boucles) . |
|
| 2643 | - ") . '\""; |
|
| 2644 | - |
|
| 2645 | - $col_vraie = $date_orig; |
|
| 2646 | - $date_orig = $boucle->id_table . '.' . $date_orig; |
|
| 2647 | - |
|
| 2648 | - switch ($col) { |
|
| 2649 | - case 'date': |
|
| 2650 | - $col = $date_orig; |
|
| 2651 | - break; |
|
| 2652 | - case 'jour': |
|
| 2653 | - $col = "DAYOFMONTH($date_orig)"; |
|
| 2654 | - break; |
|
| 2655 | - case 'mois': |
|
| 2656 | - $col = "MONTH($date_orig)"; |
|
| 2657 | - break; |
|
| 2658 | - case 'annee': |
|
| 2659 | - $col = "YEAR($date_orig)"; |
|
| 2660 | - break; |
|
| 2661 | - case 'heure': |
|
| 2662 | - $col = "DATE_FORMAT($date_orig, \\'%H:%i\\')"; |
|
| 2663 | - break; |
|
| 2664 | - case 'age': |
|
| 2665 | - $col = calculer_param_date("\'' . date('Y-m-d H:i:00') . '\'", $date_orig); |
|
| 2666 | - $col_vraie = '';// comparer a un int (par defaut) |
|
| 2667 | - break; |
|
| 2668 | - case 'age_relatif': |
|
| 2669 | - $col = calculer_param_date($date_compare, $date_orig); |
|
| 2670 | - $col_vraie = '';// comparer a un int (par defaut) |
|
| 2671 | - break; |
|
| 2672 | - case 'jour_relatif': |
|
| 2673 | - $col = '(TO_DAYS(' . $date_compare . ')-TO_DAYS(' . $date_orig . '))'; |
|
| 2674 | - $col_vraie = '';// comparer a un int (par defaut) |
|
| 2675 | - break; |
|
| 2676 | - case 'mois_relatif': |
|
| 2677 | - $col = 'MONTH(' . $date_compare . ')-MONTH(' . |
|
| 2678 | - $date_orig . ')+12*(YEAR(' . $date_compare . |
|
| 2679 | - ')-YEAR(' . $date_orig . '))'; |
|
| 2680 | - $col_vraie = '';// comparer a un int (par defaut) |
|
| 2681 | - break; |
|
| 2682 | - case 'annee_relatif': |
|
| 2683 | - $col = 'YEAR(' . $date_compare . ')-YEAR(' . |
|
| 2684 | - $date_orig . ')'; |
|
| 2685 | - $col_vraie = '';// comparer a un int (par defaut) |
|
| 2686 | - break; |
|
| 2687 | - } |
|
| 2688 | - |
|
| 2689 | - return [$col, $col_vraie]; |
|
| 2607 | + if (!preg_match(',^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z_]+)?$,', $col, $regs)) { |
|
| 2608 | + return ''; |
|
| 2609 | + } |
|
| 2610 | + |
|
| 2611 | + $boucle = $boucles[$idb]; |
|
| 2612 | + $table = $boucle->show; |
|
| 2613 | + |
|
| 2614 | + // si c'est une colonne de la table, ne rien faire |
|
| 2615 | + if (isset($table['field'][$col])) { |
|
| 2616 | + return ''; |
|
| 2617 | + } |
|
| 2618 | + |
|
| 2619 | + if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) { |
|
| 2620 | + return ''; |
|
| 2621 | + } |
|
| 2622 | + $pred = $date_orig = $GLOBALS['table_date'][$table['id_table']] ?? $table['date']; |
|
| 2623 | + |
|
| 2624 | + $col = $regs[1]; |
|
| 2625 | + if (isset($regs[3]) and $suite = $regs[3]) { |
|
| 2626 | + # Recherche de l'existence du champ date_xxxx, |
|
| 2627 | + # si oui choisir ce champ, sinon choisir xxxx |
|
| 2628 | + |
|
| 2629 | + if (isset($table['field']["date$suite"])) { |
|
| 2630 | + $date_orig = 'date' . $suite; |
|
| 2631 | + } else { |
|
| 2632 | + $date_orig = substr($suite, 1); |
|
| 2633 | + } |
|
| 2634 | + $pred = $date_orig; |
|
| 2635 | + } else { |
|
| 2636 | + if (isset($regs[2]) and $rel = $regs[2]) { |
|
| 2637 | + $pred = 'date'; |
|
| 2638 | + } |
|
| 2639 | + } |
|
| 2640 | + |
|
| 2641 | + $date_compare = "\"' . normaliser_date(" . |
|
| 2642 | + calculer_argument_precedent($idb, $pred, $boucles) . |
|
| 2643 | + ") . '\""; |
|
| 2644 | + |
|
| 2645 | + $col_vraie = $date_orig; |
|
| 2646 | + $date_orig = $boucle->id_table . '.' . $date_orig; |
|
| 2647 | + |
|
| 2648 | + switch ($col) { |
|
| 2649 | + case 'date': |
|
| 2650 | + $col = $date_orig; |
|
| 2651 | + break; |
|
| 2652 | + case 'jour': |
|
| 2653 | + $col = "DAYOFMONTH($date_orig)"; |
|
| 2654 | + break; |
|
| 2655 | + case 'mois': |
|
| 2656 | + $col = "MONTH($date_orig)"; |
|
| 2657 | + break; |
|
| 2658 | + case 'annee': |
|
| 2659 | + $col = "YEAR($date_orig)"; |
|
| 2660 | + break; |
|
| 2661 | + case 'heure': |
|
| 2662 | + $col = "DATE_FORMAT($date_orig, \\'%H:%i\\')"; |
|
| 2663 | + break; |
|
| 2664 | + case 'age': |
|
| 2665 | + $col = calculer_param_date("\'' . date('Y-m-d H:i:00') . '\'", $date_orig); |
|
| 2666 | + $col_vraie = '';// comparer a un int (par defaut) |
|
| 2667 | + break; |
|
| 2668 | + case 'age_relatif': |
|
| 2669 | + $col = calculer_param_date($date_compare, $date_orig); |
|
| 2670 | + $col_vraie = '';// comparer a un int (par defaut) |
|
| 2671 | + break; |
|
| 2672 | + case 'jour_relatif': |
|
| 2673 | + $col = '(TO_DAYS(' . $date_compare . ')-TO_DAYS(' . $date_orig . '))'; |
|
| 2674 | + $col_vraie = '';// comparer a un int (par defaut) |
|
| 2675 | + break; |
|
| 2676 | + case 'mois_relatif': |
|
| 2677 | + $col = 'MONTH(' . $date_compare . ')-MONTH(' . |
|
| 2678 | + $date_orig . ')+12*(YEAR(' . $date_compare . |
|
| 2679 | + ')-YEAR(' . $date_orig . '))'; |
|
| 2680 | + $col_vraie = '';// comparer a un int (par defaut) |
|
| 2681 | + break; |
|
| 2682 | + case 'annee_relatif': |
|
| 2683 | + $col = 'YEAR(' . $date_compare . ')-YEAR(' . |
|
| 2684 | + $date_orig . ')'; |
|
| 2685 | + $col_vraie = '';// comparer a un int (par defaut) |
|
| 2686 | + break; |
|
| 2687 | + } |
|
| 2688 | + |
|
| 2689 | + return [$col, $col_vraie]; |
|
| 2690 | 2690 | } |
| 2691 | 2691 | |
| 2692 | 2692 | /** |
@@ -2705,16 +2705,16 @@ discard block |
||
| 2705 | 2705 | * de colonne SQL et une date. |
| 2706 | 2706 | **/ |
| 2707 | 2707 | function calculer_param_date($date_compare, $date_orig) { |
| 2708 | - if (preg_match(",'\" *\.(.*)\. *\"',", $date_compare, $r)) { |
|
| 2709 | - $init = "'\" . (\$x = $r[1]) . \"'"; |
|
| 2710 | - $date_compare = '\'$x\''; |
|
| 2711 | - } else { |
|
| 2712 | - $init = $date_compare; |
|
| 2713 | - } |
|
| 2714 | - |
|
| 2715 | - return |
|
| 2716 | - // optimisation : mais prevoir le support SQLite avant |
|
| 2717 | - "TIMESTAMPDIFF(HOUR,$date_orig,$init)/24"; |
|
| 2708 | + if (preg_match(",'\" *\.(.*)\. *\"',", $date_compare, $r)) { |
|
| 2709 | + $init = "'\" . (\$x = $r[1]) . \"'"; |
|
| 2710 | + $date_compare = '\'$x\''; |
|
| 2711 | + } else { |
|
| 2712 | + $init = $date_compare; |
|
| 2713 | + } |
|
| 2714 | + |
|
| 2715 | + return |
|
| 2716 | + // optimisation : mais prevoir le support SQLite avant |
|
| 2717 | + "TIMESTAMPDIFF(HOUR,$date_orig,$init)/24"; |
|
| 2718 | 2718 | } |
| 2719 | 2719 | |
| 2720 | 2720 | /** |
@@ -2732,20 +2732,20 @@ discard block |
||
| 2732 | 2732 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 2733 | 2733 | */ |
| 2734 | 2734 | function critere_DATA_source_dist($idb, &$boucles, $crit) { |
| 2735 | - $boucle = &$boucles[$idb]; |
|
| 2736 | - |
|
| 2737 | - $args = []; |
|
| 2738 | - foreach ($crit->param as &$param) { |
|
| 2739 | - array_push( |
|
| 2740 | - $args, |
|
| 2741 | - calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) |
|
| 2742 | - ); |
|
| 2743 | - } |
|
| 2735 | + $boucle = &$boucles[$idb]; |
|
| 2744 | 2736 | |
| 2745 | - $boucle->hash .= ' |
|
| 2737 | + $args = []; |
|
| 2738 | + foreach ($crit->param as &$param) { |
|
| 2739 | + array_push( |
|
| 2740 | + $args, |
|
| 2741 | + calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) |
|
| 2742 | + ); |
|
| 2743 | + } |
|
| 2744 | + |
|
| 2745 | + $boucle->hash .= ' |
|
| 2746 | 2746 | $command[\'sourcemode\'] = ' . array_shift($args) . ";\n"; |
| 2747 | 2747 | |
| 2748 | - $boucle->hash .= ' |
|
| 2748 | + $boucle->hash .= ' |
|
| 2749 | 2749 | $command[\'source\'] = array(' . join(', ', $args) . ");\n"; |
| 2750 | 2750 | } |
| 2751 | 2751 | |
@@ -2763,8 +2763,8 @@ discard block |
||
| 2763 | 2763 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 2764 | 2764 | */ |
| 2765 | 2765 | function critere_DATA_datacache_dist($idb, &$boucles, $crit) { |
| 2766 | - $boucle = &$boucles[$idb]; |
|
| 2767 | - $boucle->hash .= ' |
|
| 2766 | + $boucle = &$boucles[$idb]; |
|
| 2767 | + $boucle->hash .= ' |
|
| 2768 | 2768 | $command[\'datacache\'] = ' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent) . ';'; |
| 2769 | 2769 | } |
| 2770 | 2770 | |
@@ -2780,12 +2780,12 @@ discard block |
||
| 2780 | 2780 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 2781 | 2781 | */ |
| 2782 | 2782 | function critere_php_args_dist($idb, &$boucles, $crit) { |
| 2783 | - $boucle = &$boucles[$idb]; |
|
| 2784 | - $boucle->hash .= '$command[\'args\']=array();'; |
|
| 2785 | - foreach ($crit->param as $param) { |
|
| 2786 | - $boucle->hash .= ' |
|
| 2783 | + $boucle = &$boucles[$idb]; |
|
| 2784 | + $boucle->hash .= '$command[\'args\']=array();'; |
|
| 2785 | + foreach ($crit->param as $param) { |
|
| 2786 | + $boucle->hash .= ' |
|
| 2787 | 2787 | $command[\'args\'][] = ' . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ';'; |
| 2788 | - } |
|
| 2788 | + } |
|
| 2789 | 2789 | } |
| 2790 | 2790 | |
| 2791 | 2791 | /** |
@@ -2802,16 +2802,16 @@ discard block |
||
| 2802 | 2802 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 2803 | 2803 | */ |
| 2804 | 2804 | function critere_DATA_liste_dist($idb, &$boucles, $crit) { |
| 2805 | - $boucle = &$boucles[$idb]; |
|
| 2806 | - $boucle->hash .= "\n\t" . '$command[\'liste\'] = array();' . "\n"; |
|
| 2807 | - foreach ($crit->param as $param) { |
|
| 2808 | - $boucle->hash .= "\t" . '$command[\'liste\'][] = ' . calculer_liste( |
|
| 2809 | - $param, |
|
| 2810 | - $idb, |
|
| 2811 | - $boucles, |
|
| 2812 | - $boucles[$idb]->id_parent |
|
| 2813 | - ) . ";\n"; |
|
| 2814 | - } |
|
| 2805 | + $boucle = &$boucles[$idb]; |
|
| 2806 | + $boucle->hash .= "\n\t" . '$command[\'liste\'] = array();' . "\n"; |
|
| 2807 | + foreach ($crit->param as $param) { |
|
| 2808 | + $boucle->hash .= "\t" . '$command[\'liste\'][] = ' . calculer_liste( |
|
| 2809 | + $param, |
|
| 2810 | + $idb, |
|
| 2811 | + $boucles, |
|
| 2812 | + $boucles[$idb]->id_parent |
|
| 2813 | + ) . ";\n"; |
|
| 2814 | + } |
|
| 2815 | 2815 | } |
| 2816 | 2816 | |
| 2817 | 2817 | /** |
@@ -2836,16 +2836,16 @@ discard block |
||
| 2836 | 2836 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 2837 | 2837 | */ |
| 2838 | 2838 | function critere_DATA_enum_dist($idb, &$boucles, $crit) { |
| 2839 | - $boucle = &$boucles[$idb]; |
|
| 2840 | - $boucle->hash .= "\n\t" . '$command[\'enum\'] = array();' . "\n"; |
|
| 2841 | - foreach ($crit->param as $param) { |
|
| 2842 | - $boucle->hash .= "\t" . '$command[\'enum\'][] = ' . calculer_liste( |
|
| 2843 | - $param, |
|
| 2844 | - $idb, |
|
| 2845 | - $boucles, |
|
| 2846 | - $boucles[$idb]->id_parent |
|
| 2847 | - ) . ";\n"; |
|
| 2848 | - } |
|
| 2839 | + $boucle = &$boucles[$idb]; |
|
| 2840 | + $boucle->hash .= "\n\t" . '$command[\'enum\'] = array();' . "\n"; |
|
| 2841 | + foreach ($crit->param as $param) { |
|
| 2842 | + $boucle->hash .= "\t" . '$command[\'enum\'][] = ' . calculer_liste( |
|
| 2843 | + $param, |
|
| 2844 | + $idb, |
|
| 2845 | + $boucles, |
|
| 2846 | + $boucles[$idb]->id_parent |
|
| 2847 | + ) . ";\n"; |
|
| 2848 | + } |
|
| 2849 | 2849 | } |
| 2850 | 2850 | |
| 2851 | 2851 | /** |
@@ -2860,11 +2860,11 @@ discard block |
||
| 2860 | 2860 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 2861 | 2861 | */ |
| 2862 | 2862 | function critere_DATA_datapath_dist($idb, &$boucles, $crit) { |
| 2863 | - $boucle = &$boucles[$idb]; |
|
| 2864 | - foreach ($crit->param as $param) { |
|
| 2865 | - $boucle->hash .= ' |
|
| 2863 | + $boucle = &$boucles[$idb]; |
|
| 2864 | + foreach ($crit->param as $param) { |
|
| 2865 | + $boucle->hash .= ' |
|
| 2866 | 2866 | $command[\'datapath\'][] = ' . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ';'; |
| 2867 | - } |
|
| 2867 | + } |
|
| 2868 | 2868 | } |
| 2869 | 2869 | |
| 2870 | 2870 | |
@@ -2896,20 +2896,20 @@ discard block |
||
| 2896 | 2896 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 2897 | 2897 | */ |
| 2898 | 2898 | function critere_si_dist($idb, &$boucles, $crit) { |
| 2899 | - $boucle = &$boucles[$idb]; |
|
| 2900 | - // il faut initialiser 1 fois le tableau a chaque appel de la boucle |
|
| 2901 | - // (par exemple lorsque notre boucle est appelee dans une autre boucle) |
|
| 2902 | - // mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle ! |
|
| 2903 | - $boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n"; |
|
| 2904 | - if ($crit->param) { |
|
| 2905 | - foreach ($crit->param as $param) { |
|
| 2906 | - $boucle->hash .= "\t\$command['si'][] = " |
|
| 2907 | - . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ";\n"; |
|
| 2908 | - } |
|
| 2909 | - // interdire {si 0} aussi ! |
|
| 2910 | - } else { |
|
| 2911 | - $boucle->hash .= '$command[\'si\'][] = 0;'; |
|
| 2912 | - } |
|
| 2899 | + $boucle = &$boucles[$idb]; |
|
| 2900 | + // il faut initialiser 1 fois le tableau a chaque appel de la boucle |
|
| 2901 | + // (par exemple lorsque notre boucle est appelee dans une autre boucle) |
|
| 2902 | + // mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle ! |
|
| 2903 | + $boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n"; |
|
| 2904 | + if ($crit->param) { |
|
| 2905 | + foreach ($crit->param as $param) { |
|
| 2906 | + $boucle->hash .= "\t\$command['si'][] = " |
|
| 2907 | + . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ";\n"; |
|
| 2908 | + } |
|
| 2909 | + // interdire {si 0} aussi ! |
|
| 2910 | + } else { |
|
| 2911 | + $boucle->hash .= '$command[\'si\'][] = 0;'; |
|
| 2912 | + } |
|
| 2913 | 2913 | } |
| 2914 | 2914 | |
| 2915 | 2915 | /** |
@@ -2926,8 +2926,8 @@ discard block |
||
| 2926 | 2926 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 2927 | 2927 | */ |
| 2928 | 2928 | function critere_POUR_tableau_dist($idb, &$boucles, $crit) { |
| 2929 | - $boucle = &$boucles[$idb]; |
|
| 2930 | - $boucle->hash .= ' |
|
| 2929 | + $boucle = &$boucles[$idb]; |
|
| 2930 | + $boucle->hash .= ' |
|
| 2931 | 2931 | $command[\'source\'] = array(' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent) . '); |
| 2932 | 2932 | $command[\'sourcemode\'] = \'table\';'; |
| 2933 | 2933 | } |
@@ -2948,27 +2948,27 @@ discard block |
||
| 2948 | 2948 | */ |
| 2949 | 2949 | function critere_noeud_dist($idb, &$boucles, $crit) { |
| 2950 | 2950 | |
| 2951 | - $not = $crit->not; |
|
| 2952 | - $boucle = &$boucles[$idb]; |
|
| 2953 | - $primary = $boucle->primary; |
|
| 2951 | + $not = $crit->not; |
|
| 2952 | + $boucle = &$boucles[$idb]; |
|
| 2953 | + $primary = $boucle->primary; |
|
| 2954 | 2954 | |
| 2955 | - if (!$primary or strpos($primary, ',')) { |
|
| 2956 | - erreur_squelette(_T('zbug_doublon_sur_table_sans_cle_primaire'), $boucle); |
|
| 2955 | + if (!$primary or strpos($primary, ',')) { |
|
| 2956 | + erreur_squelette(_T('zbug_doublon_sur_table_sans_cle_primaire'), $boucle); |
|
| 2957 | 2957 | |
| 2958 | - return; |
|
| 2959 | - } |
|
| 2960 | - $table = $boucle->type_requete; |
|
| 2961 | - $table_sql = table_objet_sql(objet_type($table)); |
|
| 2958 | + return; |
|
| 2959 | + } |
|
| 2960 | + $table = $boucle->type_requete; |
|
| 2961 | + $table_sql = table_objet_sql(objet_type($table)); |
|
| 2962 | 2962 | |
| 2963 | - $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent'; |
|
| 2963 | + $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent'; |
|
| 2964 | 2964 | |
| 2965 | - $in = 'IN'; |
|
| 2966 | - $where = ["'IN'", "'$boucle->id_table." . "$primary'", "'('.sql_get_select('$id_parent', '$table_sql').')'"]; |
|
| 2967 | - if ($not) { |
|
| 2968 | - $where = ["'NOT'", $where]; |
|
| 2969 | - } |
|
| 2965 | + $in = 'IN'; |
|
| 2966 | + $where = ["'IN'", "'$boucle->id_table." . "$primary'", "'('.sql_get_select('$id_parent', '$table_sql').')'"]; |
|
| 2967 | + if ($not) { |
|
| 2968 | + $where = ["'NOT'", $where]; |
|
| 2969 | + } |
|
| 2970 | 2970 | |
| 2971 | - $boucle->where[] = $where; |
|
| 2971 | + $boucle->where[] = $where; |
|
| 2972 | 2972 | } |
| 2973 | 2973 | |
| 2974 | 2974 | /** |
@@ -2984,8 +2984,8 @@ discard block |
||
| 2984 | 2984 | * @param Critere $crit Paramètres du critère dans cette boucle |
| 2985 | 2985 | */ |
| 2986 | 2986 | function critere_feuille_dist($idb, &$boucles, $crit) { |
| 2987 | - $not = $crit->not; |
|
| 2988 | - $crit->not = $not ? false : true; |
|
| 2989 | - critere_noeud_dist($idb, $boucles, $crit); |
|
| 2990 | - $crit->not = $not; |
|
| 2987 | + $not = $crit->not; |
|
| 2988 | + $crit->not = $not ? false : true; |
|
| 2989 | + critere_noeud_dist($idb, $boucles, $crit); |
|
| 2990 | + $crit->not = $not; |
|
| 2991 | 2991 | } |