@@ -22,7 +22,7 @@ discard block |
||
| 22 | 22 | **/ |
| 23 | 23 | |
| 24 | 24 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 25 | - return; |
|
| 25 | + return; |
|
| 26 | 26 | } |
| 27 | 27 | include_spip('inc/filtres'); |
| 28 | 28 | include_spip('inc/lang'); |
@@ -44,21 +44,21 @@ discard block |
||
| 44 | 44 | **/ |
| 45 | 45 | function definir_puce() { |
| 46 | 46 | |
| 47 | - // Attention au sens, qui n'est pas defini de la meme facon dans |
|
| 48 | - // l'espace prive (spip_lang est la langue de l'interface, lang_dir |
|
| 49 | - // celle du texte) et public (spip_lang est la langue du texte) |
|
| 50 | - $dir = _DIR_RESTREINT ? lang_dir() : lang_dir($GLOBALS['spip_lang']); |
|
| 47 | + // Attention au sens, qui n'est pas defini de la meme facon dans |
|
| 48 | + // l'espace prive (spip_lang est la langue de l'interface, lang_dir |
|
| 49 | + // celle du texte) et public (spip_lang est la langue du texte) |
|
| 50 | + $dir = _DIR_RESTREINT ? lang_dir() : lang_dir($GLOBALS['spip_lang']); |
|
| 51 | 51 | |
| 52 | - $p = 'puce' . (test_espace_prive() ? '_prive' : ''); |
|
| 53 | - if ($dir == 'rtl') { |
|
| 54 | - $p .= '_rtl'; |
|
| 55 | - } |
|
| 52 | + $p = 'puce' . (test_espace_prive() ? '_prive' : ''); |
|
| 53 | + if ($dir == 'rtl') { |
|
| 54 | + $p .= '_rtl'; |
|
| 55 | + } |
|
| 56 | 56 | |
| 57 | - if (!isset($GLOBALS[$p])) { |
|
| 58 | - $GLOBALS[$p] = '<span class="spip-puce ' . $dir . '"><b>–</b></span>'; |
|
| 59 | - } |
|
| 57 | + if (!isset($GLOBALS[$p])) { |
|
| 58 | + $GLOBALS[$p] = '<span class="spip-puce ' . $dir . '"><b>–</b></span>'; |
|
| 59 | + } |
|
| 60 | 60 | |
| 61 | - return $GLOBALS[$p]; |
|
| 61 | + return $GLOBALS[$p]; |
|
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | /** |
@@ -66,30 +66,30 @@ discard block |
||
| 66 | 66 | */ |
| 67 | 67 | function spip_balisage_code(string $corps, bool $bloc = false, string $attributs = '', string $langage = ''): string { |
| 68 | 68 | |
| 69 | - $echap = spip_htmlspecialchars($corps); // il ne faut pas passer dans entites_html, ne pas transformer les &#xxx; du code ! |
|
| 70 | - $class = 'spip_code ' . ($bloc ? 'spip_code_block' : 'spip_code_inline'); |
|
| 71 | - if ($attributs) { |
|
| 72 | - $attributs = ' ' . trim($attributs); |
|
| 73 | - } |
|
| 74 | - if ($langage) { |
|
| 75 | - $class .= " language-$langage"; |
|
| 76 | - $attributs .= ' data-language="' . $langage . '"'; |
|
| 77 | - } |
|
| 78 | - if ($bloc) { |
|
| 79 | - $html = '<div class="precode">' |
|
| 80 | - . "<pre class=\"$class\" dir=\"ltr\" style=\"text-align: left;\"$attributs>" |
|
| 81 | - . '<code>' |
|
| 82 | - . $echap |
|
| 83 | - . '</code>' |
|
| 84 | - . '</pre>' |
|
| 85 | - . '</div>'; |
|
| 86 | - } else { |
|
| 87 | - $echap = str_replace("\t", ' ', $echap); |
|
| 88 | - $echap = str_replace(' ', ' ', $echap); |
|
| 89 | - $html = "<code class=\"$class\" dir=\"ltr\"$attributs>" . $echap . '</code>'; |
|
| 90 | - } |
|
| 91 | - |
|
| 92 | - return $html; |
|
| 69 | + $echap = spip_htmlspecialchars($corps); // il ne faut pas passer dans entites_html, ne pas transformer les &#xxx; du code ! |
|
| 70 | + $class = 'spip_code ' . ($bloc ? 'spip_code_block' : 'spip_code_inline'); |
|
| 71 | + if ($attributs) { |
|
| 72 | + $attributs = ' ' . trim($attributs); |
|
| 73 | + } |
|
| 74 | + if ($langage) { |
|
| 75 | + $class .= " language-$langage"; |
|
| 76 | + $attributs .= ' data-language="' . $langage . '"'; |
|
| 77 | + } |
|
| 78 | + if ($bloc) { |
|
| 79 | + $html = '<div class="precode">' |
|
| 80 | + . "<pre class=\"$class\" dir=\"ltr\" style=\"text-align: left;\"$attributs>" |
|
| 81 | + . '<code>' |
|
| 82 | + . $echap |
|
| 83 | + . '</code>' |
|
| 84 | + . '</pre>' |
|
| 85 | + . '</div>'; |
|
| 86 | + } else { |
|
| 87 | + $echap = str_replace("\t", ' ', $echap); |
|
| 88 | + $echap = str_replace(' ', ' ', $echap); |
|
| 89 | + $html = "<code class=\"$class\" dir=\"ltr\"$attributs>" . $echap . '</code>'; |
|
| 90 | + } |
|
| 91 | + |
|
| 92 | + return $html; |
|
| 93 | 93 | } |
| 94 | 94 | |
| 95 | 95 | |
@@ -112,83 +112,83 @@ discard block |
||
| 112 | 112 | * @return string |
| 113 | 113 | */ |
| 114 | 114 | function code_echappement($rempl, $source = '', $no_transform = false, $mode = null) { |
| 115 | - if (!is_string($rempl) || !strlen($rempl)) { |
|
| 116 | - return ''; |
|
| 117 | - } |
|
| 115 | + if (!is_string($rempl) || !strlen($rempl)) { |
|
| 116 | + return ''; |
|
| 117 | + } |
|
| 118 | 118 | |
| 119 | - return CollecteurHtmlTag::echappementHtmlBase64((string)$rempl, (string)$source, in_array($mode, ['div', 'span']) ? $mode === 'div' : null); |
|
| 119 | + return CollecteurHtmlTag::echappementHtmlBase64((string)$rempl, (string)$source, in_array($mode, ['div', 'span']) ? $mode === 'div' : null); |
|
| 120 | 120 | } |
| 121 | 121 | |
| 122 | 122 | |
| 123 | 123 | // Echapper les <html>...</ html> |
| 124 | 124 | function traiter_echap_html_dist($regs, $options = []) { |
| 125 | - return $regs['innerHtml']; |
|
| 125 | + return $regs['innerHtml']; |
|
| 126 | 126 | } |
| 127 | 127 | |
| 128 | 128 | // Echapper les <pre>...</ pre> |
| 129 | 129 | function traiter_echap_pre_dist($regs, $options = []) { |
| 130 | - // echapper les <code> dans <pre> |
|
| 131 | - $pre = $regs['innerHtml']; |
|
| 132 | - |
|
| 133 | - // echapper les < dans <code> |
|
| 134 | - if (str_contains($pre, '<')) { |
|
| 135 | - $collecteurCode = new CollecteurHtmlTag('code'); |
|
| 136 | - $collections = $collecteurCode->collecter($pre); |
|
| 137 | - $collections = array_reverse($collections); |
|
| 138 | - foreach ($collections as $c) { |
|
| 139 | - $code = $c['opening'] . spip_htmlspecialchars($c['innerHtml']) . $c['closing']; |
|
| 140 | - $pre = substr_replace($pre, $code, $c['pos'], $c['length']); |
|
| 141 | - } |
|
| 142 | - } |
|
| 143 | - return "<pre>$pre</pre>"; |
|
| 130 | + // echapper les <code> dans <pre> |
|
| 131 | + $pre = $regs['innerHtml']; |
|
| 132 | + |
|
| 133 | + // echapper les < dans <code> |
|
| 134 | + if (str_contains($pre, '<')) { |
|
| 135 | + $collecteurCode = new CollecteurHtmlTag('code'); |
|
| 136 | + $collections = $collecteurCode->collecter($pre); |
|
| 137 | + $collections = array_reverse($collections); |
|
| 138 | + foreach ($collections as $c) { |
|
| 139 | + $code = $c['opening'] . spip_htmlspecialchars($c['innerHtml']) . $c['closing']; |
|
| 140 | + $pre = substr_replace($pre, $code, $c['pos'], $c['length']); |
|
| 141 | + } |
|
| 142 | + } |
|
| 143 | + return "<pre>$pre</pre>"; |
|
| 144 | 144 | } |
| 145 | 145 | |
| 146 | 146 | // Echapper les <code>...</ code> |
| 147 | 147 | function traiter_echap_code_dist($regs, $options = []) { |
| 148 | - $corps = $regs['innerHtml']; |
|
| 149 | - $att = $regs['attributs']; |
|
| 148 | + $corps = $regs['innerHtml']; |
|
| 149 | + $att = $regs['attributs']; |
|
| 150 | 150 | |
| 151 | - // ne pas mettre le <div...> s'il n'y a qu'une ligne |
|
| 152 | - if (str_contains($corps, "\n")) { |
|
| 153 | - // supprimer les sauts de ligne debut/fin |
|
| 154 | - // (mais pas les espaces => ascii art). |
|
| 155 | - $corps = preg_replace("/^[\n\r]+|[\n\r]+$/s", '', $corps); |
|
| 151 | + // ne pas mettre le <div...> s'il n'y a qu'une ligne |
|
| 152 | + if (str_contains($corps, "\n")) { |
|
| 153 | + // supprimer les sauts de ligne debut/fin |
|
| 154 | + // (mais pas les espaces => ascii art). |
|
| 155 | + $corps = preg_replace("/^[\n\r]+|[\n\r]+$/s", '', $corps); |
|
| 156 | 156 | |
| 157 | - $echap = spip_balisage_code($corps, true, $att); |
|
| 158 | - } else { |
|
| 159 | - $echap = spip_balisage_code($corps, false, $att); |
|
| 160 | - } |
|
| 157 | + $echap = spip_balisage_code($corps, true, $att); |
|
| 158 | + } else { |
|
| 159 | + $echap = spip_balisage_code($corps, false, $att); |
|
| 160 | + } |
|
| 161 | 161 | |
| 162 | - return $echap; |
|
| 162 | + return $echap; |
|
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | // Echapper les <cadre>...</ cadre> aka <frame>...</ frame> |
| 166 | 166 | function traiter_echap_cadre_dist($regs, $options = []) { |
| 167 | - $echap = trim(entites_html($regs['innerHtml'])); |
|
| 168 | - // compter les lignes un peu plus finement qu'avec les \n |
|
| 169 | - $lignes = explode("\n", trim($echap)); |
|
| 170 | - $n = 0; |
|
| 171 | - foreach ($lignes as $l) { |
|
| 172 | - $n += floor(strlen($l) / 60) + 1; |
|
| 173 | - } |
|
| 174 | - $n = max($n, 2); |
|
| 175 | - $echap = "\n<textarea readonly='readonly' cols='40' rows='$n' class='spip_cadre spip_cadre_block' dir='ltr'>$echap</textarea>"; |
|
| 176 | - |
|
| 177 | - return $echap; |
|
| 167 | + $echap = trim(entites_html($regs['innerHtml'])); |
|
| 168 | + // compter les lignes un peu plus finement qu'avec les \n |
|
| 169 | + $lignes = explode("\n", trim($echap)); |
|
| 170 | + $n = 0; |
|
| 171 | + foreach ($lignes as $l) { |
|
| 172 | + $n += floor(strlen($l) / 60) + 1; |
|
| 173 | + } |
|
| 174 | + $n = max($n, 2); |
|
| 175 | + $echap = "\n<textarea readonly='readonly' cols='40' rows='$n' class='spip_cadre spip_cadre_block' dir='ltr'>$echap</textarea>"; |
|
| 176 | + |
|
| 177 | + return $echap; |
|
| 178 | 178 | } |
| 179 | 179 | |
| 180 | 180 | function traiter_echap_frame_dist($regs, $options = []) { |
| 181 | - return traiter_echap_cadre_dist($regs); |
|
| 181 | + return traiter_echap_cadre_dist($regs); |
|
| 182 | 182 | } |
| 183 | 183 | |
| 184 | 184 | function traiter_echap_script_dist($regs, $options = []) { |
| 185 | - // rendre joli (et inactif) si c'est un script language=php |
|
| 186 | - if (strpos($regs['opening'], 'php')) { |
|
| 187 | - return highlight_string($regs['raw'], true); |
|
| 188 | - } |
|
| 185 | + // rendre joli (et inactif) si c'est un script language=php |
|
| 186 | + if (strpos($regs['opening'], 'php')) { |
|
| 187 | + return highlight_string($regs['raw'], true); |
|
| 188 | + } |
|
| 189 | 189 | |
| 190 | - // Cas normal : le script passe tel quel |
|
| 191 | - return $regs['raw']; |
|
| 190 | + // Cas normal : le script passe tel quel |
|
| 191 | + return $regs['raw']; |
|
| 192 | 192 | } |
| 193 | 193 | |
| 194 | 194 | defined('_PROTEGE_BLOCS') || define('_PROTEGE_BLOCS', ',<(' . implode('|', CollecteurHtmlTag::$listeBalisesAProteger) . ')(\b[^>]*)?>(.*)</\1>,UimsS'); |
@@ -207,69 +207,69 @@ discard block |
||
| 207 | 207 | * @return string|string[] |
| 208 | 208 | */ |
| 209 | 209 | function echappe_html( |
| 210 | - $letexte, |
|
| 211 | - $source = '', |
|
| 212 | - $no_transform = false, |
|
| 213 | - $html_tags = null, |
|
| 214 | - $callback_prefix = '', |
|
| 215 | - $callback_options = [] |
|
| 210 | + $letexte, |
|
| 211 | + $source = '', |
|
| 212 | + $no_transform = false, |
|
| 213 | + $html_tags = null, |
|
| 214 | + $callback_prefix = '', |
|
| 215 | + $callback_options = [] |
|
| 216 | 216 | ) { |
| 217 | - if (!is_string($letexte) || !strlen($letexte)) { |
|
| 218 | - return $letexte; |
|
| 219 | - } |
|
| 220 | - |
|
| 221 | - if ($no_transform !== false) { |
|
| 222 | - trigger_deprecation('spip', '5.0', 'Using "%s" arg is deprecated, use directly "%s" instead.', '$no_transform', 'Spip\Texte\Collecteur\HtmlTag::proteger_balisesHtml', __FUNCTION__); |
|
| 223 | - } |
|
| 224 | - |
|
| 225 | - // appels legacy avec un '' |
|
| 226 | - if (empty($html_tags)) { |
|
| 227 | - $html_tags = null; |
|
| 228 | - } |
|
| 229 | - |
|
| 230 | - // legacy : les appels fournissaient une preg pour repérer les balises HTML |
|
| 231 | - if ($html_tags && !is_array($html_tags)) { |
|
| 232 | - trigger_deprecation('spip', '5.0', 'Using a preg for "%s" arg is deprecated, use a tag array instead.', '$html_tags', __FUNCTION__); |
|
| 233 | - $t = explode(')', $html_tags, 2); |
|
| 234 | - $t = reset($t); |
|
| 235 | - $t = explode('(', $t, 2); |
|
| 236 | - $t = end($t); |
|
| 237 | - $html_tags = explode('|', $t); |
|
| 238 | - } |
|
| 239 | - |
|
| 240 | - $callbacks = []; |
|
| 241 | - if (!$no_transform) { |
|
| 242 | - $callback_secure_prefix = ($callback_options['secure_prefix'] ?? ''); |
|
| 243 | - foreach ($html_tags ?: CollecteurHtmlTag::$listeBalisesAProteger as $tag) { |
|
| 244 | - if ( |
|
| 245 | - function_exists($f = $callback_prefix . $callback_secure_prefix . 'traiter_echap_' . $tag) |
|
| 246 | - || function_exists($f = $f . '_dist') |
|
| 247 | - || $callback_secure_prefix && ( |
|
| 248 | - function_exists($f = $callback_prefix . 'traiter_echap_' . $tag) |
|
| 249 | - || function_exists($f = $f . '_dist') |
|
| 250 | - ) |
|
| 251 | - ) { |
|
| 252 | - $callbacks[$tag] = $f; |
|
| 253 | - } |
|
| 254 | - } |
|
| 255 | - } |
|
| 256 | - |
|
| 257 | - $letexte = CollecteurHtmlTag::proteger_balisesHtml($letexte, $source, $html_tags, $callbacks, $callback_options); |
|
| 258 | - |
|
| 259 | - if ($no_transform) { |
|
| 260 | - return $letexte; |
|
| 261 | - } |
|
| 262 | - |
|
| 263 | - // Echapper le php pour faire joli (ici, c'est pas pour la securite) |
|
| 264 | - // seulement si on a echappe les <script> |
|
| 265 | - // (derogatoire car on ne peut pas faire passer < ? ... ? > |
|
| 266 | - // dans une callback autonommee + la preg pour collecter est un peu spécifique |
|
| 267 | - if (in_array('script', $html_tags ?: CollecteurHtmlTag::$listeBalisesAProteger)) { |
|
| 268 | - $htmlTagCollecteur = new CollecteurHtmlTag('?', '@<[?].*($|[?]>)@UsS', ''); |
|
| 269 | - $letexte = $htmlTagCollecteur->echapper_enHtmlBase64($letexte, $source, fn ($c, $o) => highlight_string($c['raw'], true)); |
|
| 270 | - } |
|
| 271 | - |
|
| 272 | - return $letexte; |
|
| 217 | + if (!is_string($letexte) || !strlen($letexte)) { |
|
| 218 | + return $letexte; |
|
| 219 | + } |
|
| 220 | + |
|
| 221 | + if ($no_transform !== false) { |
|
| 222 | + trigger_deprecation('spip', '5.0', 'Using "%s" arg is deprecated, use directly "%s" instead.', '$no_transform', 'Spip\Texte\Collecteur\HtmlTag::proteger_balisesHtml', __FUNCTION__); |
|
| 223 | + } |
|
| 224 | + |
|
| 225 | + // appels legacy avec un '' |
|
| 226 | + if (empty($html_tags)) { |
|
| 227 | + $html_tags = null; |
|
| 228 | + } |
|
| 229 | + |
|
| 230 | + // legacy : les appels fournissaient une preg pour repérer les balises HTML |
|
| 231 | + if ($html_tags && !is_array($html_tags)) { |
|
| 232 | + trigger_deprecation('spip', '5.0', 'Using a preg for "%s" arg is deprecated, use a tag array instead.', '$html_tags', __FUNCTION__); |
|
| 233 | + $t = explode(')', $html_tags, 2); |
|
| 234 | + $t = reset($t); |
|
| 235 | + $t = explode('(', $t, 2); |
|
| 236 | + $t = end($t); |
|
| 237 | + $html_tags = explode('|', $t); |
|
| 238 | + } |
|
| 239 | + |
|
| 240 | + $callbacks = []; |
|
| 241 | + if (!$no_transform) { |
|
| 242 | + $callback_secure_prefix = ($callback_options['secure_prefix'] ?? ''); |
|
| 243 | + foreach ($html_tags ?: CollecteurHtmlTag::$listeBalisesAProteger as $tag) { |
|
| 244 | + if ( |
|
| 245 | + function_exists($f = $callback_prefix . $callback_secure_prefix . 'traiter_echap_' . $tag) |
|
| 246 | + || function_exists($f = $f . '_dist') |
|
| 247 | + || $callback_secure_prefix && ( |
|
| 248 | + function_exists($f = $callback_prefix . 'traiter_echap_' . $tag) |
|
| 249 | + || function_exists($f = $f . '_dist') |
|
| 250 | + ) |
|
| 251 | + ) { |
|
| 252 | + $callbacks[$tag] = $f; |
|
| 253 | + } |
|
| 254 | + } |
|
| 255 | + } |
|
| 256 | + |
|
| 257 | + $letexte = CollecteurHtmlTag::proteger_balisesHtml($letexte, $source, $html_tags, $callbacks, $callback_options); |
|
| 258 | + |
|
| 259 | + if ($no_transform) { |
|
| 260 | + return $letexte; |
|
| 261 | + } |
|
| 262 | + |
|
| 263 | + // Echapper le php pour faire joli (ici, c'est pas pour la securite) |
|
| 264 | + // seulement si on a echappe les <script> |
|
| 265 | + // (derogatoire car on ne peut pas faire passer < ? ... ? > |
|
| 266 | + // dans une callback autonommee + la preg pour collecter est un peu spécifique |
|
| 267 | + if (in_array('script', $html_tags ?: CollecteurHtmlTag::$listeBalisesAProteger)) { |
|
| 268 | + $htmlTagCollecteur = new CollecteurHtmlTag('?', '@<[?].*($|[?]>)@UsS', ''); |
|
| 269 | + $letexte = $htmlTagCollecteur->echapper_enHtmlBase64($letexte, $source, fn ($c, $o) => highlight_string($c['raw'], true)); |
|
| 270 | + } |
|
| 271 | + |
|
| 272 | + return $letexte; |
|
| 273 | 273 | } |
| 274 | 274 | |
| 275 | 275 | /** |
@@ -283,27 +283,27 @@ discard block |
||
| 283 | 283 | * @return array|mixed|string|string[] |
| 284 | 284 | */ |
| 285 | 285 | function echappe_retour($letexte, $source = '', $filtre = '') { |
| 286 | - if (!is_string($letexte) || !strlen($letexte)) { |
|
| 287 | - return $letexte; |
|
| 288 | - } |
|
| 289 | - return CollecteurHtmlTag::retablir_depuisHtmlBase64((string)$letexte, (string)$source, (string)$filtre); |
|
| 286 | + if (!is_string($letexte) || !strlen($letexte)) { |
|
| 287 | + return $letexte; |
|
| 288 | + } |
|
| 289 | + return CollecteurHtmlTag::retablir_depuisHtmlBase64((string)$letexte, (string)$source, (string)$filtre); |
|
| 290 | 290 | } |
| 291 | 291 | |
| 292 | 292 | // Reinserer le javascript de confiance (venant des modeles) |
| 293 | 293 | |
| 294 | 294 | function echappe_retour_modeles($letexte, $interdire_scripts = false) { |
| 295 | - if (!is_string($letexte) || !strlen($letexte)) { |
|
| 296 | - return $letexte; |
|
| 297 | - } |
|
| 298 | - $letexte = CollecteurHtmlTag::retablir_depuisHtmlBase64((string)$letexte); |
|
| 299 | - |
|
| 300 | - // Dans les appels directs hors squelette, securiser aussi ici |
|
| 301 | - // c'est interdire_scripts() qui rétablit les scripts des modeles echappés avec _PROTEGE_JS_MODELES et _PROTEGE_PHP_MODELES |
|
| 302 | - if ($interdire_scripts) { |
|
| 303 | - $letexte = interdire_scripts($letexte); |
|
| 304 | - } |
|
| 305 | - |
|
| 306 | - return trim($letexte); |
|
| 295 | + if (!is_string($letexte) || !strlen($letexte)) { |
|
| 296 | + return $letexte; |
|
| 297 | + } |
|
| 298 | + $letexte = CollecteurHtmlTag::retablir_depuisHtmlBase64((string)$letexte); |
|
| 299 | + |
|
| 300 | + // Dans les appels directs hors squelette, securiser aussi ici |
|
| 301 | + // c'est interdire_scripts() qui rétablit les scripts des modeles echappés avec _PROTEGE_JS_MODELES et _PROTEGE_PHP_MODELES |
|
| 302 | + if ($interdire_scripts) { |
|
| 303 | + $letexte = interdire_scripts($letexte); |
|
| 304 | + } |
|
| 305 | + |
|
| 306 | + return trim($letexte); |
|
| 307 | 307 | } |
| 308 | 308 | |
| 309 | 309 | |
@@ -331,129 +331,129 @@ discard block |
||
| 331 | 331 | * texte coupé |
| 332 | 332 | **/ |
| 333 | 333 | function couper($texte, $taille = 50, $suite = null) { |
| 334 | - if ($taille <= 0) { |
|
| 335 | - return ''; |
|
| 336 | - } |
|
| 337 | - $length = spip_strlen($texte); |
|
| 338 | - if (!$length) { |
|
| 339 | - return ''; |
|
| 340 | - } |
|
| 341 | - $offset = 400 + 2 * $taille; |
|
| 342 | - while ( |
|
| 343 | - $offset < $length |
|
| 344 | - && spip_strlen(preg_replace(',<(!--|\w|/)[^>]+>,Uims', '', spip_substr($texte, 0, $offset))) < $taille |
|
| 345 | - ) { |
|
| 346 | - $offset *= 2; |
|
| 347 | - } |
|
| 348 | - if ( |
|
| 349 | - $offset < $length |
|
| 350 | - && ($p_tag_ouvrant = strpos($texte, '<', $offset)) !== null |
|
| 351 | - ) { |
|
| 352 | - $p_tag_fermant = strpos($texte, '>', $offset); |
|
| 353 | - // prolonger la coupe jusqu'au tag fermant suivant eventuel |
|
| 354 | - if ($p_tag_fermant && ($p_tag_fermant < $p_tag_ouvrant)) { |
|
| 355 | - $offset = $p_tag_fermant + 1; |
|
| 356 | - } |
|
| 357 | - } |
|
| 358 | - // éviter de travailler sur 10ko pour extraire 150 caractères |
|
| 359 | - $texte = spip_substr($texte, 0, $offset); |
|
| 360 | - |
|
| 361 | - if (!function_exists('nettoyer_raccourcis_typo')) { |
|
| 362 | - include_spip('inc/lien'); |
|
| 363 | - } |
|
| 364 | - $texte = nettoyer_raccourcis_typo($texte); |
|
| 365 | - |
|
| 366 | - // balises de sauts de ligne et paragraphe |
|
| 367 | - $texte = preg_replace('/<p( [^>]*)?' . '>/', "\r\r", $texte); |
|
| 368 | - $texte = preg_replace('/<br( [^>]*)?' . '>/', "\n", $texte); |
|
| 369 | - |
|
| 370 | - // on repasse les doubles \n en \r que nettoyer_raccourcis_typo() a pu modifier |
|
| 371 | - $texte = str_replace("\n\n", "\r\r", $texte); |
|
| 372 | - |
|
| 373 | - // supprimer les tags |
|
| 374 | - $texte = supprimer_tags($texte); |
|
| 375 | - $texte = trim(str_replace("\n", ' ', $texte)); |
|
| 376 | - |
|
| 377 | - // tester s'il est nécessaire de couper le texte |
|
| 378 | - if (spip_strlen($texte) <= $taille) { |
|
| 379 | - $points = ''; |
|
| 380 | - } else { |
|
| 381 | - // points de suite |
|
| 382 | - if (is_null($suite)) { |
|
| 383 | - $suite = (defined('_COUPER_SUITE') ? _COUPER_SUITE : ' (...)'); |
|
| 384 | - } |
|
| 385 | - $taille_suite = spip_strlen(filtrer_entites($suite)); |
|
| 386 | - |
|
| 387 | - // couper au mot precedent (ou au début de la chaîne si c'est le premier mot) |
|
| 388 | - // on coupe avec un caractère de plus que la taille demandée afin de pouvoir |
|
| 389 | - // détecter si le dernier mot du texte coupé est complet ou non. ce caractère |
|
| 390 | - // excédentaire est ensuite supprimé par l'appel à preg_replace() |
|
| 391 | - $long = spip_substr($texte, 0, max($taille + 1 - $taille_suite, 1)); |
|
| 392 | - $u = $GLOBALS['meta']['pcre_u']; |
|
| 393 | - $court = preg_replace('/(^|([^\s ])[\s ]+)([\s ]|[^\s ]+)?$/D' . $u, "\\2", $long); |
|
| 394 | - $points = $suite; |
|
| 395 | - |
|
| 396 | - // trop court ? ne pas faire de (...) |
|
| 397 | - if (spip_strlen($court) < max(0.75 * $taille, 2)) { |
|
| 398 | - $points = ''; |
|
| 399 | - $long = spip_substr($texte, 0, $taille + 1); |
|
| 400 | - preg_match('/(^|([^\s ])[\s ]+)([\s ]|[^\s ]+)?$/D' . $u, $long, $m); |
|
| 401 | - $texte = preg_replace('/(^|([^\s ])[\s ]+)([\s ]|[^\s ]+)?$/D' . $u, "\\2", $long); |
|
| 402 | - // encore trop court ? couper au caractere |
|
| 403 | - if (spip_strlen($texte) < 0.75 * $taille) { |
|
| 404 | - $texte = spip_substr($long, 0, $taille); |
|
| 405 | - } |
|
| 406 | - } else { |
|
| 407 | - $texte = $court; |
|
| 408 | - } |
|
| 409 | - } |
|
| 410 | - |
|
| 411 | - // remettre les paragraphes |
|
| 412 | - $texte = preg_replace("/\r\r+/", "\n\n", $texte); |
|
| 413 | - |
|
| 414 | - // supprimer l'eventuelle entite finale mal coupee |
|
| 415 | - $texte = preg_replace('/&#?[a-z0-9]*$/S', '', $texte); |
|
| 416 | - |
|
| 417 | - return quote_amp(trim($texte)) . $points; |
|
| 334 | + if ($taille <= 0) { |
|
| 335 | + return ''; |
|
| 336 | + } |
|
| 337 | + $length = spip_strlen($texte); |
|
| 338 | + if (!$length) { |
|
| 339 | + return ''; |
|
| 340 | + } |
|
| 341 | + $offset = 400 + 2 * $taille; |
|
| 342 | + while ( |
|
| 343 | + $offset < $length |
|
| 344 | + && spip_strlen(preg_replace(',<(!--|\w|/)[^>]+>,Uims', '', spip_substr($texte, 0, $offset))) < $taille |
|
| 345 | + ) { |
|
| 346 | + $offset *= 2; |
|
| 347 | + } |
|
| 348 | + if ( |
|
| 349 | + $offset < $length |
|
| 350 | + && ($p_tag_ouvrant = strpos($texte, '<', $offset)) !== null |
|
| 351 | + ) { |
|
| 352 | + $p_tag_fermant = strpos($texte, '>', $offset); |
|
| 353 | + // prolonger la coupe jusqu'au tag fermant suivant eventuel |
|
| 354 | + if ($p_tag_fermant && ($p_tag_fermant < $p_tag_ouvrant)) { |
|
| 355 | + $offset = $p_tag_fermant + 1; |
|
| 356 | + } |
|
| 357 | + } |
|
| 358 | + // éviter de travailler sur 10ko pour extraire 150 caractères |
|
| 359 | + $texte = spip_substr($texte, 0, $offset); |
|
| 360 | + |
|
| 361 | + if (!function_exists('nettoyer_raccourcis_typo')) { |
|
| 362 | + include_spip('inc/lien'); |
|
| 363 | + } |
|
| 364 | + $texte = nettoyer_raccourcis_typo($texte); |
|
| 365 | + |
|
| 366 | + // balises de sauts de ligne et paragraphe |
|
| 367 | + $texte = preg_replace('/<p( [^>]*)?' . '>/', "\r\r", $texte); |
|
| 368 | + $texte = preg_replace('/<br( [^>]*)?' . '>/', "\n", $texte); |
|
| 369 | + |
|
| 370 | + // on repasse les doubles \n en \r que nettoyer_raccourcis_typo() a pu modifier |
|
| 371 | + $texte = str_replace("\n\n", "\r\r", $texte); |
|
| 372 | + |
|
| 373 | + // supprimer les tags |
|
| 374 | + $texte = supprimer_tags($texte); |
|
| 375 | + $texte = trim(str_replace("\n", ' ', $texte)); |
|
| 376 | + |
|
| 377 | + // tester s'il est nécessaire de couper le texte |
|
| 378 | + if (spip_strlen($texte) <= $taille) { |
|
| 379 | + $points = ''; |
|
| 380 | + } else { |
|
| 381 | + // points de suite |
|
| 382 | + if (is_null($suite)) { |
|
| 383 | + $suite = (defined('_COUPER_SUITE') ? _COUPER_SUITE : ' (...)'); |
|
| 384 | + } |
|
| 385 | + $taille_suite = spip_strlen(filtrer_entites($suite)); |
|
| 386 | + |
|
| 387 | + // couper au mot precedent (ou au début de la chaîne si c'est le premier mot) |
|
| 388 | + // on coupe avec un caractère de plus que la taille demandée afin de pouvoir |
|
| 389 | + // détecter si le dernier mot du texte coupé est complet ou non. ce caractère |
|
| 390 | + // excédentaire est ensuite supprimé par l'appel à preg_replace() |
|
| 391 | + $long = spip_substr($texte, 0, max($taille + 1 - $taille_suite, 1)); |
|
| 392 | + $u = $GLOBALS['meta']['pcre_u']; |
|
| 393 | + $court = preg_replace('/(^|([^\s ])[\s ]+)([\s ]|[^\s ]+)?$/D' . $u, "\\2", $long); |
|
| 394 | + $points = $suite; |
|
| 395 | + |
|
| 396 | + // trop court ? ne pas faire de (...) |
|
| 397 | + if (spip_strlen($court) < max(0.75 * $taille, 2)) { |
|
| 398 | + $points = ''; |
|
| 399 | + $long = spip_substr($texte, 0, $taille + 1); |
|
| 400 | + preg_match('/(^|([^\s ])[\s ]+)([\s ]|[^\s ]+)?$/D' . $u, $long, $m); |
|
| 401 | + $texte = preg_replace('/(^|([^\s ])[\s ]+)([\s ]|[^\s ]+)?$/D' . $u, "\\2", $long); |
|
| 402 | + // encore trop court ? couper au caractere |
|
| 403 | + if (spip_strlen($texte) < 0.75 * $taille) { |
|
| 404 | + $texte = spip_substr($long, 0, $taille); |
|
| 405 | + } |
|
| 406 | + } else { |
|
| 407 | + $texte = $court; |
|
| 408 | + } |
|
| 409 | + } |
|
| 410 | + |
|
| 411 | + // remettre les paragraphes |
|
| 412 | + $texte = preg_replace("/\r\r+/", "\n\n", $texte); |
|
| 413 | + |
|
| 414 | + // supprimer l'eventuelle entite finale mal coupee |
|
| 415 | + $texte = preg_replace('/&#?[a-z0-9]*$/S', '', $texte); |
|
| 416 | + |
|
| 417 | + return quote_amp(trim($texte)) . $points; |
|
| 418 | 418 | } |
| 419 | 419 | |
| 420 | 420 | |
| 421 | 421 | function protege_js_modeles($texte) { |
| 422 | - if (isset($GLOBALS['visiteur_session']) && str_contains($texte, '<')) { |
|
| 423 | - $tags = [ |
|
| 424 | - 'javascript' => ['tag' => 'script', 'preg' => ',<script.*?($|</script.),isS', 'c' => '_PROTEGE_JS_MODELES'], |
|
| 425 | - 'php' => ['tag' => '?php', 'preg' => ',<\?php.*?($|\?' . '>),isS', 'c' => '_PROTEGE_PHP_MODELES'], |
|
| 426 | - ]; |
|
| 427 | - foreach ($tags as $k => $t) { |
|
| 428 | - if (stripos($texte, '<' . $t['tag']) !== false) { |
|
| 429 | - if (!defined($t['c'])) { |
|
| 430 | - include_spip('inc/acces'); |
|
| 431 | - define($t['c'], creer_uniqid()); |
|
| 432 | - } |
|
| 433 | - $collecteurHtmlTag = new CollecteurHtmlTag($t['tag'], $t['preg'], ''); |
|
| 434 | - $texte = $collecteurHtmlTag->echapper_enHtmlBase64($texte, $k . constant($t['c'])); |
|
| 435 | - } |
|
| 436 | - } |
|
| 437 | - } |
|
| 438 | - return $texte; |
|
| 422 | + if (isset($GLOBALS['visiteur_session']) && str_contains($texte, '<')) { |
|
| 423 | + $tags = [ |
|
| 424 | + 'javascript' => ['tag' => 'script', 'preg' => ',<script.*?($|</script.),isS', 'c' => '_PROTEGE_JS_MODELES'], |
|
| 425 | + 'php' => ['tag' => '?php', 'preg' => ',<\?php.*?($|\?' . '>),isS', 'c' => '_PROTEGE_PHP_MODELES'], |
|
| 426 | + ]; |
|
| 427 | + foreach ($tags as $k => $t) { |
|
| 428 | + if (stripos($texte, '<' . $t['tag']) !== false) { |
|
| 429 | + if (!defined($t['c'])) { |
|
| 430 | + include_spip('inc/acces'); |
|
| 431 | + define($t['c'], creer_uniqid()); |
|
| 432 | + } |
|
| 433 | + $collecteurHtmlTag = new CollecteurHtmlTag($t['tag'], $t['preg'], ''); |
|
| 434 | + $texte = $collecteurHtmlTag->echapper_enHtmlBase64($texte, $k . constant($t['c'])); |
|
| 435 | + } |
|
| 436 | + } |
|
| 437 | + } |
|
| 438 | + return $texte; |
|
| 439 | 439 | } |
| 440 | 440 | |
| 441 | 441 | |
| 442 | 442 | function echapper_faux_tags($letexte) { |
| 443 | - if (!str_contains($letexte, '<')) { |
|
| 444 | - return $letexte; |
|
| 445 | - } |
|
| 446 | - $textMatches = preg_split(',(</?[a-z!][^<>]*>),', $letexte, -1, PREG_SPLIT_DELIM_CAPTURE); |
|
| 447 | - |
|
| 448 | - $letexte = ''; |
|
| 449 | - while (is_countable($textMatches) ? count($textMatches) : 0) { |
|
| 450 | - // un texte a echapper |
|
| 451 | - $letexte .= str_replace('<', '<', array_shift($textMatches)); |
|
| 452 | - // un tag html qui a servit a faite le split |
|
| 453 | - $letexte .= array_shift($textMatches); |
|
| 454 | - } |
|
| 455 | - |
|
| 456 | - return $letexte; |
|
| 443 | + if (!str_contains($letexte, '<')) { |
|
| 444 | + return $letexte; |
|
| 445 | + } |
|
| 446 | + $textMatches = preg_split(',(</?[a-z!][^<>]*>),', $letexte, -1, PREG_SPLIT_DELIM_CAPTURE); |
|
| 447 | + |
|
| 448 | + $letexte = ''; |
|
| 449 | + while (is_countable($textMatches) ? count($textMatches) : 0) { |
|
| 450 | + // un texte a echapper |
|
| 451 | + $letexte .= str_replace('<', '<', array_shift($textMatches)); |
|
| 452 | + // un tag html qui a servit a faite le split |
|
| 453 | + $letexte .= array_shift($textMatches); |
|
| 454 | + } |
|
| 455 | + |
|
| 456 | + return $letexte; |
|
| 457 | 457 | } |
| 458 | 458 | |
| 459 | 459 | /** |
@@ -473,107 +473,107 @@ discard block |
||
| 473 | 473 | * @return string |
| 474 | 474 | */ |
| 475 | 475 | function echapper_html_suspect($texte, $options = [], $connect = null, $env = []) { |
| 476 | - static $echapper_html_suspect; |
|
| 477 | - if (!$texte || !is_string($texte)) { |
|
| 478 | - return $texte; |
|
| 479 | - } |
|
| 480 | - |
|
| 481 | - if (!isset($echapper_html_suspect)) { |
|
| 482 | - $echapper_html_suspect = charger_fonction('echapper_html_suspect', 'inc', true); |
|
| 483 | - } |
|
| 484 | - // si fonction personalisee, on delegue |
|
| 485 | - if ($echapper_html_suspect) { |
|
| 486 | - // on collecte le tableau d'arg minimal pour ne pas casser un appel a une fonction inc_echapper_html_suspect() selon l'ancienne signature |
|
| 487 | - $args = [$texte, $options]; |
|
| 488 | - if ($connect || !empty($env)) { |
|
| 489 | - $args[] = $connect; |
|
| 490 | - } |
|
| 491 | - if (!empty($env)) { |
|
| 492 | - $args[] = $env; |
|
| 493 | - } |
|
| 494 | - return $echapper_html_suspect(...$args); |
|
| 495 | - } |
|
| 496 | - |
|
| 497 | - if (is_bool($options)) { |
|
| 498 | - $options = ['strict' => $options]; |
|
| 499 | - } |
|
| 500 | - $strict = $options['strict'] ?? true; |
|
| 501 | - |
|
| 502 | - // pas de balise html ou pas d'attribut sur les balises ? c'est OK |
|
| 503 | - if ( |
|
| 504 | - !str_contains($texte, '<') |
|
| 505 | - || !str_contains($texte, '=') |
|
| 506 | - ) { |
|
| 507 | - return $texte; |
|
| 508 | - } |
|
| 509 | - |
|
| 510 | - // dans le prive, on veut afficher tout echappé pour la moderation |
|
| 511 | - if (!isset($env['espace_prive'])) { |
|
| 512 | - // conserver le comportement historique en cas d'appel court sans env |
|
| 513 | - $env['espace_prive'] = test_espace_prive(); |
|
| 514 | - } |
|
| 515 | - if (!empty($env['espace_prive']) || !empty($env['wysiwyg'])) { |
|
| 516 | - // quand c'est du texte qui passe par propre on est plus coulant tant qu'il y a pas d'attribut du type onxxx= |
|
| 517 | - // car sinon on declenche sur les modeles ou ressources |
|
| 518 | - if ( |
|
| 519 | - !$strict && (!str_contains($texte, 'on') || !preg_match(",<\w+.*\bon\w+\s*=,UimsS", $texte)) |
|
| 520 | - ) { |
|
| 521 | - return $texte; |
|
| 522 | - } |
|
| 523 | - |
|
| 524 | - $collecteurModeles = new CollecteurModeles(); |
|
| 525 | - $texte = $collecteurModeles->echapper($texte); |
|
| 526 | - $texte = echappe_js($texte); |
|
| 527 | - |
|
| 528 | - $texte_to_check = $texte; |
|
| 529 | - // si les raccourcis liens vont etre interprétés, il faut les expanser avant de vérifier que le html est safe |
|
| 530 | - // car un raccourci peut etre utilisé pour faire un lien malin |
|
| 531 | - // et un raccourci est potentiellement modifié par safehtml, ce qui fait un faux positif dans is_html_safe |
|
| 532 | - if (!empty($options['expanser_liens'])) { |
|
| 533 | - $texte_to_check = expanser_liens($texte_to_check, $connect, $env); |
|
| 534 | - } |
|
| 535 | - if (!is_html_safe($texte_to_check)) { |
|
| 536 | - $texte = $options['texte_source_affiche'] ?? $texte; |
|
| 537 | - $texte = preg_replace(",<(/?\w+\b[^>]*>),", "<tt><\\1</tt>", $texte); |
|
| 538 | - $texte = str_replace('<', '<', $texte); |
|
| 539 | - $texte = str_replace('<tt>', '<tt>', $texte); |
|
| 540 | - $texte = str_replace('</tt>', '</tt>', $texte); |
|
| 541 | - if (!function_exists('attribut_html')) { |
|
| 542 | - include_spip('inc/filtres'); |
|
| 543 | - } |
|
| 544 | - if (!empty($options['wrap_suspect'])) { |
|
| 545 | - $texte = wrap($texte, $options['wrap_suspect']); |
|
| 546 | - } |
|
| 547 | - $texte = "<mark class='danger-js' title='" . attribut_html(_T('erreur_contenu_suspect')) . "'>⚠️</mark> " . $texte; |
|
| 548 | - } |
|
| 549 | - |
|
| 550 | - $texte = $collecteurModeles->retablir($texte); |
|
| 551 | - } |
|
| 552 | - |
|
| 553 | - // si on est là dans le public c'est le mode parano |
|
| 554 | - // on veut donc un rendu propre et secure, et virer silencieusement ce qui est dangereux |
|
| 555 | - else { |
|
| 556 | - $collecteurLiens = $collecteurModeles = null; |
|
| 557 | - if (!empty($options['expanser_liens'])) { |
|
| 558 | - $texte = expanser_liens($texte, $connect, $env); |
|
| 559 | - } |
|
| 560 | - else { |
|
| 561 | - $collecteurLiens = new CollecteurLiens(); |
|
| 562 | - $texte = $collecteurLiens->echapper($texte, ['sanitize_callback' => 'safehtml']); |
|
| 563 | - |
|
| 564 | - $collecteurModeles = new CollecteurModeles(); |
|
| 565 | - $texte = $collecteurModeles->echapper($texte); |
|
| 566 | - } |
|
| 567 | - $texte = safehtml($texte); |
|
| 568 | - if ($collecteurModeles) { |
|
| 569 | - $texte = $collecteurModeles->retablir($texte); |
|
| 570 | - } |
|
| 571 | - if ($collecteurLiens) { |
|
| 572 | - $texte = $collecteurLiens->retablir($texte); |
|
| 573 | - } |
|
| 574 | - } |
|
| 575 | - |
|
| 576 | - return $texte; |
|
| 476 | + static $echapper_html_suspect; |
|
| 477 | + if (!$texte || !is_string($texte)) { |
|
| 478 | + return $texte; |
|
| 479 | + } |
|
| 480 | + |
|
| 481 | + if (!isset($echapper_html_suspect)) { |
|
| 482 | + $echapper_html_suspect = charger_fonction('echapper_html_suspect', 'inc', true); |
|
| 483 | + } |
|
| 484 | + // si fonction personalisee, on delegue |
|
| 485 | + if ($echapper_html_suspect) { |
|
| 486 | + // on collecte le tableau d'arg minimal pour ne pas casser un appel a une fonction inc_echapper_html_suspect() selon l'ancienne signature |
|
| 487 | + $args = [$texte, $options]; |
|
| 488 | + if ($connect || !empty($env)) { |
|
| 489 | + $args[] = $connect; |
|
| 490 | + } |
|
| 491 | + if (!empty($env)) { |
|
| 492 | + $args[] = $env; |
|
| 493 | + } |
|
| 494 | + return $echapper_html_suspect(...$args); |
|
| 495 | + } |
|
| 496 | + |
|
| 497 | + if (is_bool($options)) { |
|
| 498 | + $options = ['strict' => $options]; |
|
| 499 | + } |
|
| 500 | + $strict = $options['strict'] ?? true; |
|
| 501 | + |
|
| 502 | + // pas de balise html ou pas d'attribut sur les balises ? c'est OK |
|
| 503 | + if ( |
|
| 504 | + !str_contains($texte, '<') |
|
| 505 | + || !str_contains($texte, '=') |
|
| 506 | + ) { |
|
| 507 | + return $texte; |
|
| 508 | + } |
|
| 509 | + |
|
| 510 | + // dans le prive, on veut afficher tout echappé pour la moderation |
|
| 511 | + if (!isset($env['espace_prive'])) { |
|
| 512 | + // conserver le comportement historique en cas d'appel court sans env |
|
| 513 | + $env['espace_prive'] = test_espace_prive(); |
|
| 514 | + } |
|
| 515 | + if (!empty($env['espace_prive']) || !empty($env['wysiwyg'])) { |
|
| 516 | + // quand c'est du texte qui passe par propre on est plus coulant tant qu'il y a pas d'attribut du type onxxx= |
|
| 517 | + // car sinon on declenche sur les modeles ou ressources |
|
| 518 | + if ( |
|
| 519 | + !$strict && (!str_contains($texte, 'on') || !preg_match(",<\w+.*\bon\w+\s*=,UimsS", $texte)) |
|
| 520 | + ) { |
|
| 521 | + return $texte; |
|
| 522 | + } |
|
| 523 | + |
|
| 524 | + $collecteurModeles = new CollecteurModeles(); |
|
| 525 | + $texte = $collecteurModeles->echapper($texte); |
|
| 526 | + $texte = echappe_js($texte); |
|
| 527 | + |
|
| 528 | + $texte_to_check = $texte; |
|
| 529 | + // si les raccourcis liens vont etre interprétés, il faut les expanser avant de vérifier que le html est safe |
|
| 530 | + // car un raccourci peut etre utilisé pour faire un lien malin |
|
| 531 | + // et un raccourci est potentiellement modifié par safehtml, ce qui fait un faux positif dans is_html_safe |
|
| 532 | + if (!empty($options['expanser_liens'])) { |
|
| 533 | + $texte_to_check = expanser_liens($texte_to_check, $connect, $env); |
|
| 534 | + } |
|
| 535 | + if (!is_html_safe($texte_to_check)) { |
|
| 536 | + $texte = $options['texte_source_affiche'] ?? $texte; |
|
| 537 | + $texte = preg_replace(",<(/?\w+\b[^>]*>),", "<tt><\\1</tt>", $texte); |
|
| 538 | + $texte = str_replace('<', '<', $texte); |
|
| 539 | + $texte = str_replace('<tt>', '<tt>', $texte); |
|
| 540 | + $texte = str_replace('</tt>', '</tt>', $texte); |
|
| 541 | + if (!function_exists('attribut_html')) { |
|
| 542 | + include_spip('inc/filtres'); |
|
| 543 | + } |
|
| 544 | + if (!empty($options['wrap_suspect'])) { |
|
| 545 | + $texte = wrap($texte, $options['wrap_suspect']); |
|
| 546 | + } |
|
| 547 | + $texte = "<mark class='danger-js' title='" . attribut_html(_T('erreur_contenu_suspect')) . "'>⚠️</mark> " . $texte; |
|
| 548 | + } |
|
| 549 | + |
|
| 550 | + $texte = $collecteurModeles->retablir($texte); |
|
| 551 | + } |
|
| 552 | + |
|
| 553 | + // si on est là dans le public c'est le mode parano |
|
| 554 | + // on veut donc un rendu propre et secure, et virer silencieusement ce qui est dangereux |
|
| 555 | + else { |
|
| 556 | + $collecteurLiens = $collecteurModeles = null; |
|
| 557 | + if (!empty($options['expanser_liens'])) { |
|
| 558 | + $texte = expanser_liens($texte, $connect, $env); |
|
| 559 | + } |
|
| 560 | + else { |
|
| 561 | + $collecteurLiens = new CollecteurLiens(); |
|
| 562 | + $texte = $collecteurLiens->echapper($texte, ['sanitize_callback' => 'safehtml']); |
|
| 563 | + |
|
| 564 | + $collecteurModeles = new CollecteurModeles(); |
|
| 565 | + $texte = $collecteurModeles->echapper($texte); |
|
| 566 | + } |
|
| 567 | + $texte = safehtml($texte); |
|
| 568 | + if ($collecteurModeles) { |
|
| 569 | + $texte = $collecteurModeles->retablir($texte); |
|
| 570 | + } |
|
| 571 | + if ($collecteurLiens) { |
|
| 572 | + $texte = $collecteurLiens->retablir($texte); |
|
| 573 | + } |
|
| 574 | + } |
|
| 575 | + |
|
| 576 | + return $texte; |
|
| 577 | 577 | } |
| 578 | 578 | |
| 579 | 579 | |
@@ -594,48 +594,48 @@ discard block |
||
| 594 | 594 | * texte sécurisé |
| 595 | 595 | **/ |
| 596 | 596 | function safehtml($t) { |
| 597 | - static $safehtml; |
|
| 598 | - |
|
| 599 | - if (!$t || !is_string($t)) { |
|
| 600 | - return $t; |
|
| 601 | - } |
|
| 602 | - # attention safehtml nettoie deux ou trois caracteres de plus. A voir |
|
| 603 | - if (!str_contains($t, '<')) { |
|
| 604 | - return str_replace("\x00", '', $t); |
|
| 605 | - } |
|
| 606 | - |
|
| 607 | - $collecteurIdiomes = null; |
|
| 608 | - if (stripos($t, '<:') !== false) { |
|
| 609 | - $collecteurIdiomes = new CollecteurIdiomes(); |
|
| 610 | - $t = $collecteurIdiomes->echapper($t); |
|
| 611 | - } |
|
| 612 | - $collecteurMultis = null; |
|
| 613 | - if (stripos($t, '<multi') !== false) { |
|
| 614 | - $collecteurMultis = new CollecteurMultis(); |
|
| 615 | - $t = $collecteurMultis->echapper($t, ['sanitize_callback' => 'safehtml']); |
|
| 616 | - } |
|
| 617 | - |
|
| 618 | - if (!function_exists('interdire_scripts')) { |
|
| 619 | - include_spip('inc/texte'); |
|
| 620 | - } |
|
| 621 | - $t = interdire_scripts($t); // jolifier le php |
|
| 622 | - $t = echappe_js($t); |
|
| 623 | - |
|
| 624 | - if (!isset($safehtml)) { |
|
| 625 | - $safehtml = charger_fonction('safehtml', 'inc', true); |
|
| 626 | - } |
|
| 627 | - if ($safehtml) { |
|
| 628 | - $t = $safehtml($t); |
|
| 629 | - } |
|
| 630 | - |
|
| 631 | - if ($collecteurMultis) { |
|
| 632 | - $t = $collecteurMultis->retablir($t); |
|
| 633 | - } |
|
| 634 | - if ($collecteurIdiomes) { |
|
| 635 | - $t = $collecteurIdiomes->retablir($t); |
|
| 636 | - } |
|
| 637 | - |
|
| 638 | - return interdire_scripts($t); // interdire le php (2 precautions) |
|
| 597 | + static $safehtml; |
|
| 598 | + |
|
| 599 | + if (!$t || !is_string($t)) { |
|
| 600 | + return $t; |
|
| 601 | + } |
|
| 602 | + # attention safehtml nettoie deux ou trois caracteres de plus. A voir |
|
| 603 | + if (!str_contains($t, '<')) { |
|
| 604 | + return str_replace("\x00", '', $t); |
|
| 605 | + } |
|
| 606 | + |
|
| 607 | + $collecteurIdiomes = null; |
|
| 608 | + if (stripos($t, '<:') !== false) { |
|
| 609 | + $collecteurIdiomes = new CollecteurIdiomes(); |
|
| 610 | + $t = $collecteurIdiomes->echapper($t); |
|
| 611 | + } |
|
| 612 | + $collecteurMultis = null; |
|
| 613 | + if (stripos($t, '<multi') !== false) { |
|
| 614 | + $collecteurMultis = new CollecteurMultis(); |
|
| 615 | + $t = $collecteurMultis->echapper($t, ['sanitize_callback' => 'safehtml']); |
|
| 616 | + } |
|
| 617 | + |
|
| 618 | + if (!function_exists('interdire_scripts')) { |
|
| 619 | + include_spip('inc/texte'); |
|
| 620 | + } |
|
| 621 | + $t = interdire_scripts($t); // jolifier le php |
|
| 622 | + $t = echappe_js($t); |
|
| 623 | + |
|
| 624 | + if (!isset($safehtml)) { |
|
| 625 | + $safehtml = charger_fonction('safehtml', 'inc', true); |
|
| 626 | + } |
|
| 627 | + if ($safehtml) { |
|
| 628 | + $t = $safehtml($t); |
|
| 629 | + } |
|
| 630 | + |
|
| 631 | + if ($collecteurMultis) { |
|
| 632 | + $t = $collecteurMultis->retablir($t); |
|
| 633 | + } |
|
| 634 | + if ($collecteurIdiomes) { |
|
| 635 | + $t = $collecteurIdiomes->retablir($t); |
|
| 636 | + } |
|
| 637 | + |
|
| 638 | + return interdire_scripts($t); // interdire le php (2 precautions) |
|
| 639 | 639 | } |
| 640 | 640 | |
| 641 | 641 | |
@@ -643,29 +643,29 @@ discard block |
||
| 643 | 643 | * Detecter si un texte est "safe" ie non modifie significativement par safehtml() |
| 644 | 644 | */ |
| 645 | 645 | function is_html_safe(string $texte): bool { |
| 646 | - if ($is_html_safe = charger_fonction('is_html_safe', 'inc', true)) { |
|
| 647 | - return $is_html_safe($texte); |
|
| 648 | - } |
|
| 649 | - |
|
| 650 | - // simplifier les retour ligne pour etre certain de ce que l'on compare |
|
| 651 | - $texte = str_replace("\r\n", "\n", $texte); |
|
| 652 | - // safehtml reduit aussi potentiellement les |
|
| 653 | - $texte = str_replace(' ', ' ', $texte); |
|
| 654 | - // safehtml remplace les entités html |
|
| 655 | - if (str_contains($texte, '&') && str_contains($texte, ';')) { |
|
| 656 | - $texte = html2unicode($texte, true); |
|
| 657 | - } |
|
| 658 | - // safehtml remplace les entités numériques |
|
| 659 | - if (str_contains($texte, '&#')) { |
|
| 660 | - $texte = unicode2charset($texte); |
|
| 661 | - } |
|
| 662 | - |
|
| 663 | - $texte_safe = safehtml($texte); |
|
| 664 | - |
|
| 665 | - // on teste sur strlen car safehtml supprime le contenu dangereux |
|
| 666 | - // mais il peut aussi changer des ' en " sur les attributs html, |
|
| 667 | - // donc un test d'egalite est trop strict |
|
| 668 | - return strlen($texte_safe) === strlen($texte); |
|
| 646 | + if ($is_html_safe = charger_fonction('is_html_safe', 'inc', true)) { |
|
| 647 | + return $is_html_safe($texte); |
|
| 648 | + } |
|
| 649 | + |
|
| 650 | + // simplifier les retour ligne pour etre certain de ce que l'on compare |
|
| 651 | + $texte = str_replace("\r\n", "\n", $texte); |
|
| 652 | + // safehtml reduit aussi potentiellement les |
|
| 653 | + $texte = str_replace(' ', ' ', $texte); |
|
| 654 | + // safehtml remplace les entités html |
|
| 655 | + if (str_contains($texte, '&') && str_contains($texte, ';')) { |
|
| 656 | + $texte = html2unicode($texte, true); |
|
| 657 | + } |
|
| 658 | + // safehtml remplace les entités numériques |
|
| 659 | + if (str_contains($texte, '&#')) { |
|
| 660 | + $texte = unicode2charset($texte); |
|
| 661 | + } |
|
| 662 | + |
|
| 663 | + $texte_safe = safehtml($texte); |
|
| 664 | + |
|
| 665 | + // on teste sur strlen car safehtml supprime le contenu dangereux |
|
| 666 | + // mais il peut aussi changer des ' en " sur les attributs html, |
|
| 667 | + // donc un test d'egalite est trop strict |
|
| 668 | + return strlen($texte_safe) === strlen($texte); |
|
| 669 | 669 | } |
| 670 | 670 | |
| 671 | 671 | /** |
@@ -686,13 +686,13 @@ discard block |
||
| 686 | 686 | * texte sans les modèles d'image |
| 687 | 687 | **/ |
| 688 | 688 | function supprime_img($letexte, $message = null) { |
| 689 | - if ($message === null) { |
|
| 690 | - $message = '(' . _T('img_indisponible') . ')'; |
|
| 691 | - } |
|
| 692 | - |
|
| 693 | - return preg_replace( |
|
| 694 | - ',<(img|doc|emb)([0-9]+)(\|([^>]*))?' . '\s*/?' . '>,i', |
|
| 695 | - $message, |
|
| 696 | - $letexte |
|
| 697 | - ); |
|
| 689 | + if ($message === null) { |
|
| 690 | + $message = '(' . _T('img_indisponible') . ')'; |
|
| 691 | + } |
|
| 692 | + |
|
| 693 | + return preg_replace( |
|
| 694 | + ',<(img|doc|emb)([0-9]+)(\|([^>]*))?' . '\s*/?' . '>,i', |
|
| 695 | + $message, |
|
| 696 | + $letexte |
|
| 697 | + ); |
|
| 698 | 698 | } |
@@ -556,8 +556,7 @@ |
||
| 556 | 556 | $collecteurLiens = $collecteurModeles = null; |
| 557 | 557 | if (!empty($options['expanser_liens'])) { |
| 558 | 558 | $texte = expanser_liens($texte, $connect, $env); |
| 559 | - } |
|
| 560 | - else { |
|
| 559 | + } else { |
|
| 561 | 560 | $collecteurLiens = new CollecteurLiens(); |
| 562 | 561 | $texte = $collecteurLiens->echapper($texte, ['sanitize_callback' => 'safehtml']); |
| 563 | 562 | |
@@ -19,170 +19,170 @@ discard block |
||
| 19 | 19 | **/ |
| 20 | 20 | |
| 21 | 21 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 22 | - return; |
|
| 22 | + return; |
|
| 23 | 23 | } |
| 24 | 24 | |
| 25 | 25 | function assembler($fond, string $connect = '') { |
| 26 | 26 | |
| 27 | - $chemin_cache = null; |
|
| 28 | - $lastmodified = null; |
|
| 29 | - $res = null; |
|
| 30 | - // flag_preserver est modifie ici, et utilise en globale |
|
| 31 | - // use_cache sert a informer le bouton d'admin pr savoir s'il met un * |
|
| 32 | - // contexte est utilise en globale dans le formulaire d'admin |
|
| 33 | - |
|
| 34 | - $GLOBALS['contexte'] = calculer_contexte(); |
|
| 35 | - $page = ['contexte_implicite' => calculer_contexte_implicite()]; |
|
| 36 | - $page['contexte_implicite']['cache'] = $fond . preg_replace( |
|
| 37 | - ',\.[a-zA-Z0-9]*$,', |
|
| 38 | - '', |
|
| 39 | - preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI']) |
|
| 40 | - ); |
|
| 41 | - // Cette fonction est utilisee deux fois |
|
| 42 | - $cacher = charger_fonction('cacher', 'public', true); |
|
| 43 | - // Les quatre derniers parametres sont modifies par la fonction: |
|
| 44 | - // emplacement, validite, et, s'il est valide, contenu & age |
|
| 45 | - if ($cacher) { |
|
| 46 | - $res = $cacher($GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, $page, $lastmodified); |
|
| 47 | - } else { |
|
| 48 | - $GLOBALS['use_cache'] = -1; |
|
| 49 | - } |
|
| 50 | - // Si un resultat est retourne, c'est un message d'impossibilite |
|
| 51 | - if ($res) { |
|
| 52 | - return ['texte' => $res]; |
|
| 53 | - } |
|
| 54 | - |
|
| 55 | - if (!$chemin_cache || !$lastmodified) { |
|
| 56 | - $lastmodified = time(); |
|
| 57 | - } |
|
| 58 | - |
|
| 59 | - $headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD'); |
|
| 60 | - $calculer_page = true; |
|
| 61 | - |
|
| 62 | - // Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client}) |
|
| 63 | - // une perennite valide a meme reponse qu'une requete HEAD (par defaut les |
|
| 64 | - // pages sont dynamiques) |
|
| 65 | - if ( |
|
| 66 | - isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) |
|
| 67 | - && (!defined('_VAR_MODE') || !_VAR_MODE) |
|
| 68 | - && $chemin_cache && isset($page['entetes']) |
|
| 69 | - && isset($page['entetes']['Cache-Control']) |
|
| 70 | - && strstr($page['entetes']['Cache-Control'], 'max-age=') |
|
| 71 | - && !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/') |
|
| 72 | - ) { |
|
| 73 | - $since = preg_replace( |
|
| 74 | - '/;.*/', |
|
| 75 | - '', |
|
| 76 | - $_SERVER['HTTP_IF_MODIFIED_SINCE'] |
|
| 77 | - ); |
|
| 78 | - $since = str_replace('GMT', '', $since); |
|
| 79 | - if (trim($since) == gmdate('D, d M Y H:i:s', $lastmodified)) { |
|
| 80 | - $page['status'] = 304; |
|
| 81 | - $headers_only = true; |
|
| 82 | - $calculer_page = false; |
|
| 83 | - } |
|
| 84 | - } |
|
| 85 | - |
|
| 86 | - // Si requete HEAD ou Last-modified compatible, ignorer le texte |
|
| 87 | - // et pas de content-type (pour contrer le bouton admin de inc-public) |
|
| 88 | - if (!$calculer_page) { |
|
| 89 | - $page['texte'] = ''; |
|
| 90 | - } else { |
|
| 91 | - // si la page est prise dans le cache |
|
| 92 | - if (!$GLOBALS['use_cache']) { |
|
| 93 | - // Informer les boutons d'admin du contexte |
|
| 94 | - // (fourni par urls_decoder_url ci-dessous lors de la mise en cache) |
|
| 95 | - $GLOBALS['contexte'] = $page['contexte']; |
|
| 96 | - |
|
| 97 | - // vider les globales url propres qui ne doivent plus etre utilisees en cas |
|
| 98 | - // d'inversion url => objet |
|
| 99 | - // plus necessaire si on utilise bien la fonction urls_decoder_url |
|
| 100 | - #unset($_SERVER['REDIRECT_url_propre']); |
|
| 101 | - #unset($_ENV['url_propre']); |
|
| 102 | - } else { |
|
| 103 | - // Compat ascendante : |
|
| 104 | - // 1. $contexte est global |
|
| 105 | - // (a evacuer car urls_decoder_url gere ce probleme ?) |
|
| 106 | - // et calculer la page |
|
| 107 | - if (!test_espace_prive()) { |
|
| 108 | - include_spip('inc/urls'); |
|
| 109 | - [$fond, $GLOBALS['contexte'], $url_redirect] = urls_decoder_url( |
|
| 110 | - nettoyer_uri(), |
|
| 111 | - $fond, |
|
| 112 | - $GLOBALS['contexte'], |
|
| 113 | - true |
|
| 114 | - ); |
|
| 115 | - } |
|
| 116 | - // squelette par defaut |
|
| 117 | - if (!strlen($fond ?? '')) { |
|
| 118 | - $fond = 'sommaire'; |
|
| 119 | - } |
|
| 120 | - |
|
| 121 | - // produire la page : peut mettre a jour $lastmodified |
|
| 122 | - $produire_page = charger_fonction('produire_page', 'public'); |
|
| 123 | - $page = $produire_page( |
|
| 124 | - $fond, |
|
| 125 | - $GLOBALS['contexte'], |
|
| 126 | - $GLOBALS['use_cache'], |
|
| 127 | - $chemin_cache, |
|
| 128 | - null, |
|
| 129 | - $page, |
|
| 130 | - $lastmodified, |
|
| 131 | - $connect |
|
| 132 | - ); |
|
| 133 | - if ($page === '') { |
|
| 134 | - $erreur = _T( |
|
| 135 | - 'info_erreur_squelette2', |
|
| 136 | - ['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES] |
|
| 137 | - ); |
|
| 138 | - erreur_squelette($erreur); |
|
| 139 | - // eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4 |
|
| 140 | - $page = ['texte' => '', 'erreur' => $erreur]; |
|
| 141 | - } |
|
| 142 | - } |
|
| 143 | - |
|
| 144 | - if ($page && $chemin_cache) { |
|
| 145 | - $page['cache'] = $chemin_cache; |
|
| 146 | - } |
|
| 147 | - |
|
| 148 | - auto_content_type($page); |
|
| 149 | - |
|
| 150 | - $GLOBALS['flag_preserver'] |= headers_sent(); |
|
| 151 | - |
|
| 152 | - // Definir les entetes si ce n'est fait |
|
| 153 | - if (!$GLOBALS['flag_preserver']) { |
|
| 154 | - // Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions |
|
| 155 | - if ( |
|
| 156 | - trim($page['texte']) === '' |
|
| 157 | - && _VAR_MODE !== 'debug' |
|
| 158 | - && !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur |
|
| 159 | - ) { |
|
| 160 | - $GLOBALS['contexte']['fond_erreur'] = $fond; |
|
| 161 | - $page = message_page_indisponible($page, $GLOBALS['contexte']); |
|
| 162 | - } |
|
| 163 | - // pas de cache client en mode 'observation' |
|
| 164 | - if (defined('_VAR_MODE') && _VAR_MODE) { |
|
| 165 | - $page['entetes']['Cache-Control'] = 'no-cache,must-revalidate'; |
|
| 166 | - $page['entetes']['Pragma'] = 'no-cache'; |
|
| 167 | - } |
|
| 168 | - } |
|
| 169 | - } |
|
| 170 | - |
|
| 171 | - // Entete Last-Modified: |
|
| 172 | - // eviter d'etre incoherent en envoyant un lastmodified identique |
|
| 173 | - // a celui qu'on a refuse d'honorer plus haut (cf. #655) |
|
| 174 | - if ( |
|
| 175 | - $lastmodified && !isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && !isset($page['entetes']['Last-Modified']) |
|
| 176 | - ) { |
|
| 177 | - $page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT'; |
|
| 178 | - } |
|
| 179 | - |
|
| 180 | - // fermer la connexion apres les headers si requete HEAD |
|
| 181 | - if ($headers_only) { |
|
| 182 | - $page['entetes']['Connection'] = 'close'; |
|
| 183 | - } |
|
| 184 | - |
|
| 185 | - return $page; |
|
| 27 | + $chemin_cache = null; |
|
| 28 | + $lastmodified = null; |
|
| 29 | + $res = null; |
|
| 30 | + // flag_preserver est modifie ici, et utilise en globale |
|
| 31 | + // use_cache sert a informer le bouton d'admin pr savoir s'il met un * |
|
| 32 | + // contexte est utilise en globale dans le formulaire d'admin |
|
| 33 | + |
|
| 34 | + $GLOBALS['contexte'] = calculer_contexte(); |
|
| 35 | + $page = ['contexte_implicite' => calculer_contexte_implicite()]; |
|
| 36 | + $page['contexte_implicite']['cache'] = $fond . preg_replace( |
|
| 37 | + ',\.[a-zA-Z0-9]*$,', |
|
| 38 | + '', |
|
| 39 | + preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI']) |
|
| 40 | + ); |
|
| 41 | + // Cette fonction est utilisee deux fois |
|
| 42 | + $cacher = charger_fonction('cacher', 'public', true); |
|
| 43 | + // Les quatre derniers parametres sont modifies par la fonction: |
|
| 44 | + // emplacement, validite, et, s'il est valide, contenu & age |
|
| 45 | + if ($cacher) { |
|
| 46 | + $res = $cacher($GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, $page, $lastmodified); |
|
| 47 | + } else { |
|
| 48 | + $GLOBALS['use_cache'] = -1; |
|
| 49 | + } |
|
| 50 | + // Si un resultat est retourne, c'est un message d'impossibilite |
|
| 51 | + if ($res) { |
|
| 52 | + return ['texte' => $res]; |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + if (!$chemin_cache || !$lastmodified) { |
|
| 56 | + $lastmodified = time(); |
|
| 57 | + } |
|
| 58 | + |
|
| 59 | + $headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD'); |
|
| 60 | + $calculer_page = true; |
|
| 61 | + |
|
| 62 | + // Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client}) |
|
| 63 | + // une perennite valide a meme reponse qu'une requete HEAD (par defaut les |
|
| 64 | + // pages sont dynamiques) |
|
| 65 | + if ( |
|
| 66 | + isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) |
|
| 67 | + && (!defined('_VAR_MODE') || !_VAR_MODE) |
|
| 68 | + && $chemin_cache && isset($page['entetes']) |
|
| 69 | + && isset($page['entetes']['Cache-Control']) |
|
| 70 | + && strstr($page['entetes']['Cache-Control'], 'max-age=') |
|
| 71 | + && !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/') |
|
| 72 | + ) { |
|
| 73 | + $since = preg_replace( |
|
| 74 | + '/;.*/', |
|
| 75 | + '', |
|
| 76 | + $_SERVER['HTTP_IF_MODIFIED_SINCE'] |
|
| 77 | + ); |
|
| 78 | + $since = str_replace('GMT', '', $since); |
|
| 79 | + if (trim($since) == gmdate('D, d M Y H:i:s', $lastmodified)) { |
|
| 80 | + $page['status'] = 304; |
|
| 81 | + $headers_only = true; |
|
| 82 | + $calculer_page = false; |
|
| 83 | + } |
|
| 84 | + } |
|
| 85 | + |
|
| 86 | + // Si requete HEAD ou Last-modified compatible, ignorer le texte |
|
| 87 | + // et pas de content-type (pour contrer le bouton admin de inc-public) |
|
| 88 | + if (!$calculer_page) { |
|
| 89 | + $page['texte'] = ''; |
|
| 90 | + } else { |
|
| 91 | + // si la page est prise dans le cache |
|
| 92 | + if (!$GLOBALS['use_cache']) { |
|
| 93 | + // Informer les boutons d'admin du contexte |
|
| 94 | + // (fourni par urls_decoder_url ci-dessous lors de la mise en cache) |
|
| 95 | + $GLOBALS['contexte'] = $page['contexte']; |
|
| 96 | + |
|
| 97 | + // vider les globales url propres qui ne doivent plus etre utilisees en cas |
|
| 98 | + // d'inversion url => objet |
|
| 99 | + // plus necessaire si on utilise bien la fonction urls_decoder_url |
|
| 100 | + #unset($_SERVER['REDIRECT_url_propre']); |
|
| 101 | + #unset($_ENV['url_propre']); |
|
| 102 | + } else { |
|
| 103 | + // Compat ascendante : |
|
| 104 | + // 1. $contexte est global |
|
| 105 | + // (a evacuer car urls_decoder_url gere ce probleme ?) |
|
| 106 | + // et calculer la page |
|
| 107 | + if (!test_espace_prive()) { |
|
| 108 | + include_spip('inc/urls'); |
|
| 109 | + [$fond, $GLOBALS['contexte'], $url_redirect] = urls_decoder_url( |
|
| 110 | + nettoyer_uri(), |
|
| 111 | + $fond, |
|
| 112 | + $GLOBALS['contexte'], |
|
| 113 | + true |
|
| 114 | + ); |
|
| 115 | + } |
|
| 116 | + // squelette par defaut |
|
| 117 | + if (!strlen($fond ?? '')) { |
|
| 118 | + $fond = 'sommaire'; |
|
| 119 | + } |
|
| 120 | + |
|
| 121 | + // produire la page : peut mettre a jour $lastmodified |
|
| 122 | + $produire_page = charger_fonction('produire_page', 'public'); |
|
| 123 | + $page = $produire_page( |
|
| 124 | + $fond, |
|
| 125 | + $GLOBALS['contexte'], |
|
| 126 | + $GLOBALS['use_cache'], |
|
| 127 | + $chemin_cache, |
|
| 128 | + null, |
|
| 129 | + $page, |
|
| 130 | + $lastmodified, |
|
| 131 | + $connect |
|
| 132 | + ); |
|
| 133 | + if ($page === '') { |
|
| 134 | + $erreur = _T( |
|
| 135 | + 'info_erreur_squelette2', |
|
| 136 | + ['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES] |
|
| 137 | + ); |
|
| 138 | + erreur_squelette($erreur); |
|
| 139 | + // eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4 |
|
| 140 | + $page = ['texte' => '', 'erreur' => $erreur]; |
|
| 141 | + } |
|
| 142 | + } |
|
| 143 | + |
|
| 144 | + if ($page && $chemin_cache) { |
|
| 145 | + $page['cache'] = $chemin_cache; |
|
| 146 | + } |
|
| 147 | + |
|
| 148 | + auto_content_type($page); |
|
| 149 | + |
|
| 150 | + $GLOBALS['flag_preserver'] |= headers_sent(); |
|
| 151 | + |
|
| 152 | + // Definir les entetes si ce n'est fait |
|
| 153 | + if (!$GLOBALS['flag_preserver']) { |
|
| 154 | + // Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions |
|
| 155 | + if ( |
|
| 156 | + trim($page['texte']) === '' |
|
| 157 | + && _VAR_MODE !== 'debug' |
|
| 158 | + && !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur |
|
| 159 | + ) { |
|
| 160 | + $GLOBALS['contexte']['fond_erreur'] = $fond; |
|
| 161 | + $page = message_page_indisponible($page, $GLOBALS['contexte']); |
|
| 162 | + } |
|
| 163 | + // pas de cache client en mode 'observation' |
|
| 164 | + if (defined('_VAR_MODE') && _VAR_MODE) { |
|
| 165 | + $page['entetes']['Cache-Control'] = 'no-cache,must-revalidate'; |
|
| 166 | + $page['entetes']['Pragma'] = 'no-cache'; |
|
| 167 | + } |
|
| 168 | + } |
|
| 169 | + } |
|
| 170 | + |
|
| 171 | + // Entete Last-Modified: |
|
| 172 | + // eviter d'etre incoherent en envoyant un lastmodified identique |
|
| 173 | + // a celui qu'on a refuse d'honorer plus haut (cf. #655) |
|
| 174 | + if ( |
|
| 175 | + $lastmodified && !isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && !isset($page['entetes']['Last-Modified']) |
|
| 176 | + ) { |
|
| 177 | + $page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT'; |
|
| 178 | + } |
|
| 179 | + |
|
| 180 | + // fermer la connexion apres les headers si requete HEAD |
|
| 181 | + if ($headers_only) { |
|
| 182 | + $page['entetes']['Connection'] = 'close'; |
|
| 183 | + } |
|
| 184 | + |
|
| 185 | + return $page; |
|
| 186 | 186 | } |
| 187 | 187 | |
| 188 | 188 | /** |
@@ -201,27 +201,27 @@ discard block |
||
| 201 | 201 | * @return array Un tableau du contexte de la page |
| 202 | 202 | */ |
| 203 | 203 | function calculer_contexte() { |
| 204 | - static $preg_ignore_variables; |
|
| 205 | - if (empty($preg_ignore_variables)) { |
|
| 206 | - if (!defined('_CONTEXTE_IGNORE_LISTE_VARIABLES')) { |
|
| 207 | - nettoyer_uri_var(''); |
|
| 208 | - } |
|
| 209 | - $preg_ignore_variables = '/(' . implode('|',_CONTEXTE_IGNORE_LISTE_VARIABLES) . ')/'; |
|
| 210 | - } |
|
| 211 | - |
|
| 212 | - $contexte = []; |
|
| 213 | - foreach ($_GET as $var => $val) { |
|
| 214 | - if (!preg_match($preg_ignore_variables, $var)) { |
|
| 215 | - $contexte[$var] = $val; |
|
| 216 | - } |
|
| 217 | - } |
|
| 218 | - foreach ($_POST as $var => $val) { |
|
| 219 | - if (!preg_match($preg_ignore_variables, $var)) { |
|
| 220 | - $contexte[$var] = $val; |
|
| 221 | - } |
|
| 222 | - } |
|
| 223 | - |
|
| 224 | - return $contexte; |
|
| 204 | + static $preg_ignore_variables; |
|
| 205 | + if (empty($preg_ignore_variables)) { |
|
| 206 | + if (!defined('_CONTEXTE_IGNORE_LISTE_VARIABLES')) { |
|
| 207 | + nettoyer_uri_var(''); |
|
| 208 | + } |
|
| 209 | + $preg_ignore_variables = '/(' . implode('|',_CONTEXTE_IGNORE_LISTE_VARIABLES) . ')/'; |
|
| 210 | + } |
|
| 211 | + |
|
| 212 | + $contexte = []; |
|
| 213 | + foreach ($_GET as $var => $val) { |
|
| 214 | + if (!preg_match($preg_ignore_variables, $var)) { |
|
| 215 | + $contexte[$var] = $val; |
|
| 216 | + } |
|
| 217 | + } |
|
| 218 | + foreach ($_POST as $var => $val) { |
|
| 219 | + if (!preg_match($preg_ignore_variables, $var)) { |
|
| 220 | + $contexte[$var] = $val; |
|
| 221 | + } |
|
| 222 | + } |
|
| 223 | + |
|
| 224 | + return $contexte; |
|
| 225 | 225 | } |
| 226 | 226 | |
| 227 | 227 | /** |
@@ -232,25 +232,25 @@ discard block |
||
| 232 | 232 | * @return array |
| 233 | 233 | */ |
| 234 | 234 | function calculer_contexte_implicite() { |
| 235 | - static $notes = null; |
|
| 236 | - if (is_null($notes)) { |
|
| 237 | - $notes = charger_fonction('notes', 'inc', true); |
|
| 238 | - } |
|
| 239 | - $contexte_implicite = [ |
|
| 240 | - 'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ? |
|
| 241 | - 'host' => ($_SERVER['HTTP_HOST'] ?? null), |
|
| 242 | - 'https' => ($_SERVER['HTTPS'] ?? ''), |
|
| 243 | - 'espace' => test_espace_prive(), |
|
| 244 | - 'marqueur' => ($GLOBALS['marqueur'] ?? ''), |
|
| 245 | - 'marqueur_skel' => ($GLOBALS['marqueur_skel'] ?? ''), |
|
| 246 | - 'notes' => $notes ? $notes('', 'contexter_cache') : '', |
|
| 247 | - 'spip_version_code' => $GLOBALS['spip_version_code'], |
|
| 248 | - ]; |
|
| 249 | - if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { |
|
| 250 | - $contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST']; |
|
| 251 | - } |
|
| 252 | - |
|
| 253 | - return $contexte_implicite; |
|
| 235 | + static $notes = null; |
|
| 236 | + if (is_null($notes)) { |
|
| 237 | + $notes = charger_fonction('notes', 'inc', true); |
|
| 238 | + } |
|
| 239 | + $contexte_implicite = [ |
|
| 240 | + 'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ? |
|
| 241 | + 'host' => ($_SERVER['HTTP_HOST'] ?? null), |
|
| 242 | + 'https' => ($_SERVER['HTTPS'] ?? ''), |
|
| 243 | + 'espace' => test_espace_prive(), |
|
| 244 | + 'marqueur' => ($GLOBALS['marqueur'] ?? ''), |
|
| 245 | + 'marqueur_skel' => ($GLOBALS['marqueur_skel'] ?? ''), |
|
| 246 | + 'notes' => $notes ? $notes('', 'contexter_cache') : '', |
|
| 247 | + 'spip_version_code' => $GLOBALS['spip_version_code'], |
|
| 248 | + ]; |
|
| 249 | + if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { |
|
| 250 | + $contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST']; |
|
| 251 | + } |
|
| 252 | + |
|
| 253 | + return $contexte_implicite; |
|
| 254 | 254 | } |
| 255 | 255 | |
| 256 | 256 | // |
@@ -259,56 +259,56 @@ discard block |
||
| 259 | 259 | |
| 260 | 260 | function auto_content_type($page) { |
| 261 | 261 | |
| 262 | - if (!isset($GLOBALS['flag_preserver'])) { |
|
| 263 | - $GLOBALS['flag_preserver'] = ($page && preg_match( |
|
| 264 | - '/header\s*\(\s*.content\-type:/isx', |
|
| 265 | - $page['texte'] |
|
| 266 | - ) || (isset($page['entetes']['Content-Type']))); |
|
| 267 | - } |
|
| 262 | + if (!isset($GLOBALS['flag_preserver'])) { |
|
| 263 | + $GLOBALS['flag_preserver'] = ($page && preg_match( |
|
| 264 | + '/header\s*\(\s*.content\-type:/isx', |
|
| 265 | + $page['texte'] |
|
| 266 | + ) || (isset($page['entetes']['Content-Type']))); |
|
| 267 | + } |
|
| 268 | 268 | } |
| 269 | 269 | |
| 270 | 270 | function inclure_page($fond, $contexte, string $connect = '') { |
| 271 | - $use_cache = null; |
|
| 272 | - $chemin_cache = null; |
|
| 273 | - $lastinclude = null; |
|
| 274 | - $res = null; |
|
| 275 | - static $cacher, $produire_page; |
|
| 276 | - |
|
| 277 | - // enlever le fond de contexte inclus car sinon il prend la main |
|
| 278 | - // dans les sous inclusions -> boucle infinie d'inclusion identique |
|
| 279 | - // (cette precaution n'est probablement plus utile) |
|
| 280 | - unset($contexte['fond']); |
|
| 281 | - $page = ['contexte_implicite' => calculer_contexte_implicite()]; |
|
| 282 | - $page['contexte_implicite']['cache'] = $fond; |
|
| 283 | - if (is_null($cacher)) { |
|
| 284 | - $cacher = charger_fonction('cacher', 'public', true); |
|
| 285 | - } |
|
| 286 | - // Les quatre derniers parametres sont modifies par la fonction: |
|
| 287 | - // emplacement, validite, et, s'il est valide, contenu & age |
|
| 288 | - if ($cacher) { |
|
| 289 | - $res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude); |
|
| 290 | - } else { |
|
| 291 | - $use_cache = -1; |
|
| 292 | - } |
|
| 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; |
|
| 271 | + $use_cache = null; |
|
| 272 | + $chemin_cache = null; |
|
| 273 | + $lastinclude = null; |
|
| 274 | + $res = null; |
|
| 275 | + static $cacher, $produire_page; |
|
| 276 | + |
|
| 277 | + // enlever le fond de contexte inclus car sinon il prend la main |
|
| 278 | + // dans les sous inclusions -> boucle infinie d'inclusion identique |
|
| 279 | + // (cette precaution n'est probablement plus utile) |
|
| 280 | + unset($contexte['fond']); |
|
| 281 | + $page = ['contexte_implicite' => calculer_contexte_implicite()]; |
|
| 282 | + $page['contexte_implicite']['cache'] = $fond; |
|
| 283 | + if (is_null($cacher)) { |
|
| 284 | + $cacher = charger_fonction('cacher', 'public', true); |
|
| 285 | + } |
|
| 286 | + // Les quatre derniers parametres sont modifies par la fonction: |
|
| 287 | + // emplacement, validite, et, s'il est valide, contenu & age |
|
| 288 | + if ($cacher) { |
|
| 289 | + $res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude); |
|
| 290 | + } else { |
|
| 291 | + $use_cache = -1; |
|
| 292 | + } |
|
| 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 | - && $use_cache > -1 |
|
| 347 | - && is_array($page) |
|
| 348 | - && count($page) |
|
| 349 | - && isset($page['entetes']['X-Spip-Cache']) |
|
| 350 | - && $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 | + && $use_cache > -1 |
|
| 347 | + && is_array($page) |
|
| 348 | + && count($page) |
|
| 349 | + && isset($page['entetes']['X-Spip-Cache']) |
|
| 350 | + && $page['entetes']['X-Spip-Cache'] > 0 |
|
| 351 | + ) { |
|
| 352 | + if (is_null($cacher)) { |
|
| 353 | + $cacher = charger_fonction('cacher', 'public', true); |
|
| 354 | + } |
|
| 355 | + $lastinclude = time(); |
|
| 356 | + if ($cacher) { |
|
| 357 | + $cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude); |
|
| 358 | + } else { |
|
| 359 | + $use_cache = -1; |
|
| 360 | + } |
|
| 361 | + } |
|
| 362 | + |
|
| 363 | + return $page; |
|
| 364 | 364 | } |
| 365 | 365 | |
| 366 | 366 | // Fonction inseree par le compilateur dans le code compile. |
@@ -374,14 +374,14 @@ discard block |
||
| 374 | 374 | // 4: langue |
| 375 | 375 | |
| 376 | 376 | function inserer_balise_dynamique($contexte_exec, $contexte_compil) { |
| 377 | - arguments_balise_dyn_depuis_modele(null, 'reset'); |
|
| 378 | - |
|
| 379 | - if (!is_array($contexte_exec)) { |
|
| 380 | - echo $contexte_exec; |
|
| 381 | - } // message d'erreur etc |
|
| 382 | - else { |
|
| 383 | - inclure_balise_dynamique($contexte_exec, true, $contexte_compil); |
|
| 384 | - } |
|
| 377 | + arguments_balise_dyn_depuis_modele(null, 'reset'); |
|
| 378 | + |
|
| 379 | + if (!is_array($contexte_exec)) { |
|
| 380 | + echo $contexte_exec; |
|
| 381 | + } // message d'erreur etc |
|
| 382 | + else { |
|
| 383 | + inclure_balise_dynamique($contexte_exec, true, $contexte_compil); |
|
| 384 | + } |
|
| 385 | 385 | } |
| 386 | 386 | |
| 387 | 387 | /** |
@@ -394,101 +394,101 @@ discard block |
||
| 394 | 394 | * @return string|void |
| 395 | 395 | */ |
| 396 | 396 | function inclure_balise_dynamique($texte, $echo = true, $contexte_compil = []) { |
| 397 | - if (is_array($texte)) { |
|
| 398 | - [$fond, $delainc, $contexte_inclus] = $texte; |
|
| 399 | - |
|
| 400 | - // delais a l'ancienne, c'est pratiquement mort |
|
| 401 | - $d = $GLOBALS['delais'] ?? null; |
|
| 402 | - $GLOBALS['delais'] = $delainc; |
|
| 403 | - |
|
| 404 | - $page = recuperer_fond( |
|
| 405 | - $fond, |
|
| 406 | - $contexte_inclus, |
|
| 407 | - ['trim' => false, 'raw' => true, 'compil' => $contexte_compil] |
|
| 408 | - ); |
|
| 409 | - |
|
| 410 | - $texte = $page['texte']; |
|
| 411 | - |
|
| 412 | - $GLOBALS['delais'] = $d; |
|
| 413 | - // Faire remonter les entetes |
|
| 414 | - if ( |
|
| 415 | - isset($page['entetes']) |
|
| 416 | - && is_array($page['entetes']) |
|
| 417 | - ) { |
|
| 418 | - // mais pas toutes |
|
| 419 | - unset($page['entetes']['X-Spip-Cache']); |
|
| 420 | - unset($page['entetes']['Content-Type']); |
|
| 421 | - if (isset($GLOBALS['page']) && is_array($GLOBALS['page'])) { |
|
| 422 | - if (!is_array($GLOBALS['page']['entetes'])) { |
|
| 423 | - $GLOBALS['page']['entetes'] = []; |
|
| 424 | - } |
|
| 425 | - $GLOBALS['page']['entetes'] = |
|
| 426 | - array_merge($GLOBALS['page']['entetes'], $page['entetes']); |
|
| 427 | - } |
|
| 428 | - } |
|
| 429 | - // _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines |
|
| 430 | - if ( |
|
| 431 | - isset($page['contexte']['_pipelines']) |
|
| 432 | - && is_array($page['contexte']['_pipelines']) |
|
| 433 | - && count($page['contexte']['_pipelines']) |
|
| 434 | - ) { |
|
| 435 | - foreach ($page['contexte']['_pipelines'] as $pipe => $args) { |
|
| 436 | - $args['contexte'] = $page['contexte']; |
|
| 437 | - unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul |
|
| 438 | - $texte = pipeline( |
|
| 439 | - $pipe, |
|
| 440 | - [ |
|
| 441 | - 'data' => $texte, |
|
| 442 | - 'args' => $args |
|
| 443 | - ] |
|
| 444 | - ); |
|
| 445 | - } |
|
| 446 | - } |
|
| 447 | - } |
|
| 448 | - |
|
| 449 | - if (defined('_VAR_MODE') && _VAR_MODE == 'debug') { |
|
| 450 | - // compatibilite : avant on donnait le numero de ligne ou rien. |
|
| 451 | - $ligne = intval($contexte_compil[3] ?? $contexte_compil); |
|
| 452 | - $GLOBALS['debug_objets']['resultat'][$ligne] = $texte; |
|
| 453 | - } |
|
| 454 | - if ($echo) { |
|
| 455 | - echo $texte; |
|
| 456 | - } else { |
|
| 457 | - return $texte; |
|
| 458 | - } |
|
| 397 | + if (is_array($texte)) { |
|
| 398 | + [$fond, $delainc, $contexte_inclus] = $texte; |
|
| 399 | + |
|
| 400 | + // delais a l'ancienne, c'est pratiquement mort |
|
| 401 | + $d = $GLOBALS['delais'] ?? null; |
|
| 402 | + $GLOBALS['delais'] = $delainc; |
|
| 403 | + |
|
| 404 | + $page = recuperer_fond( |
|
| 405 | + $fond, |
|
| 406 | + $contexte_inclus, |
|
| 407 | + ['trim' => false, 'raw' => true, 'compil' => $contexte_compil] |
|
| 408 | + ); |
|
| 409 | + |
|
| 410 | + $texte = $page['texte']; |
|
| 411 | + |
|
| 412 | + $GLOBALS['delais'] = $d; |
|
| 413 | + // Faire remonter les entetes |
|
| 414 | + if ( |
|
| 415 | + isset($page['entetes']) |
|
| 416 | + && is_array($page['entetes']) |
|
| 417 | + ) { |
|
| 418 | + // mais pas toutes |
|
| 419 | + unset($page['entetes']['X-Spip-Cache']); |
|
| 420 | + unset($page['entetes']['Content-Type']); |
|
| 421 | + if (isset($GLOBALS['page']) && is_array($GLOBALS['page'])) { |
|
| 422 | + if (!is_array($GLOBALS['page']['entetes'])) { |
|
| 423 | + $GLOBALS['page']['entetes'] = []; |
|
| 424 | + } |
|
| 425 | + $GLOBALS['page']['entetes'] = |
|
| 426 | + array_merge($GLOBALS['page']['entetes'], $page['entetes']); |
|
| 427 | + } |
|
| 428 | + } |
|
| 429 | + // _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines |
|
| 430 | + if ( |
|
| 431 | + isset($page['contexte']['_pipelines']) |
|
| 432 | + && is_array($page['contexte']['_pipelines']) |
|
| 433 | + && count($page['contexte']['_pipelines']) |
|
| 434 | + ) { |
|
| 435 | + foreach ($page['contexte']['_pipelines'] as $pipe => $args) { |
|
| 436 | + $args['contexte'] = $page['contexte']; |
|
| 437 | + unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul |
|
| 438 | + $texte = pipeline( |
|
| 439 | + $pipe, |
|
| 440 | + [ |
|
| 441 | + 'data' => $texte, |
|
| 442 | + 'args' => $args |
|
| 443 | + ] |
|
| 444 | + ); |
|
| 445 | + } |
|
| 446 | + } |
|
| 447 | + } |
|
| 448 | + |
|
| 449 | + if (defined('_VAR_MODE') && _VAR_MODE == 'debug') { |
|
| 450 | + // compatibilite : avant on donnait le numero de ligne ou rien. |
|
| 451 | + $ligne = intval($contexte_compil[3] ?? $contexte_compil); |
|
| 452 | + $GLOBALS['debug_objets']['resultat'][$ligne] = $texte; |
|
| 453 | + } |
|
| 454 | + if ($echo) { |
|
| 455 | + echo $texte; |
|
| 456 | + } else { |
|
| 457 | + return $texte; |
|
| 458 | + } |
|
| 459 | 459 | } |
| 460 | 460 | |
| 461 | 461 | function message_page_indisponible($page, $contexte) { |
| 462 | - static $deja = false; |
|
| 463 | - if ($deja) { |
|
| 464 | - return 'erreur'; |
|
| 465 | - } |
|
| 466 | - $codes = [ |
|
| 467 | - '404' => '404 Not Found', |
|
| 468 | - '503' => '503 Service Unavailable', |
|
| 469 | - ]; |
|
| 470 | - |
|
| 471 | - $contexte['status'] = ($page !== false) ? '404' : '503'; |
|
| 472 | - $contexte['code'] = $codes[$contexte['status']]; |
|
| 473 | - $contexte['fond'] = '404'; // gere les 2 erreurs |
|
| 474 | - if (!isset($contexte['lang'])) { |
|
| 475 | - include_spip('inc/lang'); |
|
| 476 | - $contexte['lang'] = $GLOBALS['spip_lang']; |
|
| 477 | - } |
|
| 478 | - |
|
| 479 | - $deja = true; |
|
| 480 | - // passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent |
|
| 481 | - // ex restriction d'acces => 401 |
|
| 482 | - $contexte = pipeline('page_indisponible', $contexte); |
|
| 483 | - |
|
| 484 | - // produire la page d'erreur |
|
| 485 | - $page = inclure_page($contexte['fond'], $contexte); |
|
| 486 | - if (!$page) { |
|
| 487 | - $page = inclure_page('404', $contexte); |
|
| 488 | - } |
|
| 489 | - $page['status'] = $contexte['status']; |
|
| 490 | - |
|
| 491 | - return $page; |
|
| 462 | + static $deja = false; |
|
| 463 | + if ($deja) { |
|
| 464 | + return 'erreur'; |
|
| 465 | + } |
|
| 466 | + $codes = [ |
|
| 467 | + '404' => '404 Not Found', |
|
| 468 | + '503' => '503 Service Unavailable', |
|
| 469 | + ]; |
|
| 470 | + |
|
| 471 | + $contexte['status'] = ($page !== false) ? '404' : '503'; |
|
| 472 | + $contexte['code'] = $codes[$contexte['status']]; |
|
| 473 | + $contexte['fond'] = '404'; // gere les 2 erreurs |
|
| 474 | + if (!isset($contexte['lang'])) { |
|
| 475 | + include_spip('inc/lang'); |
|
| 476 | + $contexte['lang'] = $GLOBALS['spip_lang']; |
|
| 477 | + } |
|
| 478 | + |
|
| 479 | + $deja = true; |
|
| 480 | + // passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent |
|
| 481 | + // ex restriction d'acces => 401 |
|
| 482 | + $contexte = pipeline('page_indisponible', $contexte); |
|
| 483 | + |
|
| 484 | + // produire la page d'erreur |
|
| 485 | + $page = inclure_page($contexte['fond'], $contexte); |
|
| 486 | + if (!$page) { |
|
| 487 | + $page = inclure_page('404', $contexte); |
|
| 488 | + } |
|
| 489 | + $page['status'] = $contexte['status']; |
|
| 490 | + |
|
| 491 | + return $page; |
|
| 492 | 492 | } |
| 493 | 493 | |
| 494 | 494 | /** |
@@ -500,44 +500,44 @@ discard block |
||
| 500 | 500 | * @return mixed |
| 501 | 501 | */ |
| 502 | 502 | function arguments_balise_dyn_depuis_modele($arg, $operation = 'set') { |
| 503 | - static $balise_dyn_appellee_par_modele = null; |
|
| 504 | - switch ($operation) { |
|
| 505 | - case 'read': |
|
| 506 | - return $balise_dyn_appellee_par_modele; |
|
| 507 | - case 'reset': |
|
| 508 | - $balise_dyn_appellee_par_modele = null; |
|
| 509 | - return null; |
|
| 510 | - case 'set': |
|
| 511 | - default: |
|
| 512 | - $balise_dyn_appellee_par_modele = $arg; |
|
| 513 | - return $arg; |
|
| 514 | - } |
|
| 503 | + static $balise_dyn_appellee_par_modele = null; |
|
| 504 | + switch ($operation) { |
|
| 505 | + case 'read': |
|
| 506 | + return $balise_dyn_appellee_par_modele; |
|
| 507 | + case 'reset': |
|
| 508 | + $balise_dyn_appellee_par_modele = null; |
|
| 509 | + return null; |
|
| 510 | + case 'set': |
|
| 511 | + default: |
|
| 512 | + $balise_dyn_appellee_par_modele = $arg; |
|
| 513 | + return $arg; |
|
| 514 | + } |
|
| 515 | 515 | } |
| 516 | 516 | |
| 517 | 517 | // temporairement ici : a mettre dans le futur inc/modeles |
| 518 | 518 | // creer_contexte_de_modele('left', 'autostart=true', ...) renvoie un array() |
| 519 | 519 | function creer_contexte_de_modele($args) { |
| 520 | - $contexte = []; |
|
| 521 | - foreach ($args as $var => $val) { |
|
| 522 | - if (is_int($var)) { // argument pas formate |
|
| 523 | - if (in_array($val, ['left', 'right', 'center'])) { |
|
| 524 | - $var = 'align'; |
|
| 525 | - $contexte[$var] = $val; |
|
| 526 | - } else { |
|
| 527 | - $args = explode('=', $val); |
|
| 528 | - if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args |
|
| 529 | - $contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1); |
|
| 530 | - } else // notation abregee |
|
| 531 | - { |
|
| 532 | - $contexte[trim($val)] = trim($val); |
|
| 533 | - } |
|
| 534 | - } |
|
| 535 | - } else { |
|
| 536 | - $contexte[$var] = $val; |
|
| 537 | - } |
|
| 538 | - } |
|
| 539 | - |
|
| 540 | - return $contexte; |
|
| 520 | + $contexte = []; |
|
| 521 | + foreach ($args as $var => $val) { |
|
| 522 | + if (is_int($var)) { // argument pas formate |
|
| 523 | + if (in_array($val, ['left', 'right', 'center'])) { |
|
| 524 | + $var = 'align'; |
|
| 525 | + $contexte[$var] = $val; |
|
| 526 | + } else { |
|
| 527 | + $args = explode('=', $val); |
|
| 528 | + if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args |
|
| 529 | + $contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1); |
|
| 530 | + } else // notation abregee |
|
| 531 | + { |
|
| 532 | + $contexte[trim($val)] = trim($val); |
|
| 533 | + } |
|
| 534 | + } |
|
| 535 | + } else { |
|
| 536 | + $contexte[$var] = $val; |
|
| 537 | + } |
|
| 538 | + } |
|
| 539 | + |
|
| 540 | + return $contexte; |
|
| 541 | 541 | } |
| 542 | 542 | |
| 543 | 543 | /** |
@@ -552,45 +552,45 @@ discard block |
||
| 552 | 552 | * @return string |
| 553 | 553 | */ |
| 554 | 554 | function styliser_modele($modele, $id, $contexte = null) { |
| 555 | - static $styliseurs = null; |
|
| 556 | - if (is_null($styliseurs)) { |
|
| 557 | - $tables_objet = lister_tables_objets_sql(); |
|
| 558 | - foreach ($tables_objet as $table => $desc) { |
|
| 559 | - if ( |
|
| 560 | - isset($desc['modeles']) |
|
| 561 | - && $desc['modeles'] |
|
| 562 | - && isset($desc['modeles_styliser']) |
|
| 563 | - && $desc['modeles_styliser'] |
|
| 564 | - && function_exists($desc['modeles_styliser']) |
|
| 565 | - ) { |
|
| 566 | - $primary = id_table_objet($table); |
|
| 567 | - foreach ($desc['modeles'] as $m) { |
|
| 568 | - $styliseurs[$m] = ['primary' => $primary, 'callback' => $desc['modeles_styliser']]; |
|
| 569 | - } |
|
| 570 | - } |
|
| 571 | - } |
|
| 572 | - } |
|
| 573 | - |
|
| 574 | - if (isset($styliseurs[$modele])) { |
|
| 575 | - $styliseur = $styliseurs[$modele]['callback']; |
|
| 576 | - $primary = $styliseurs[$modele]['primary']; |
|
| 577 | - if (is_null($id) && $contexte) { |
|
| 578 | - if (isset($contexte['id'])) { |
|
| 579 | - $id = $contexte['id']; |
|
| 580 | - } elseif (isset($contexte[$primary])) { |
|
| 581 | - $id = $contexte[$primary]; |
|
| 582 | - } |
|
| 583 | - } |
|
| 584 | - if (is_null($id)) { |
|
| 585 | - $msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]); |
|
| 586 | - erreur_squelette($msg); |
|
| 587 | - // on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant |
|
| 588 | - $id = 0; |
|
| 589 | - } |
|
| 590 | - $modele = $styliseur($modele, $id); |
|
| 591 | - } |
|
| 592 | - |
|
| 593 | - return $modele; |
|
| 555 | + static $styliseurs = null; |
|
| 556 | + if (is_null($styliseurs)) { |
|
| 557 | + $tables_objet = lister_tables_objets_sql(); |
|
| 558 | + foreach ($tables_objet as $table => $desc) { |
|
| 559 | + if ( |
|
| 560 | + isset($desc['modeles']) |
|
| 561 | + && $desc['modeles'] |
|
| 562 | + && isset($desc['modeles_styliser']) |
|
| 563 | + && $desc['modeles_styliser'] |
|
| 564 | + && function_exists($desc['modeles_styliser']) |
|
| 565 | + ) { |
|
| 566 | + $primary = id_table_objet($table); |
|
| 567 | + foreach ($desc['modeles'] as $m) { |
|
| 568 | + $styliseurs[$m] = ['primary' => $primary, 'callback' => $desc['modeles_styliser']]; |
|
| 569 | + } |
|
| 570 | + } |
|
| 571 | + } |
|
| 572 | + } |
|
| 573 | + |
|
| 574 | + if (isset($styliseurs[$modele])) { |
|
| 575 | + $styliseur = $styliseurs[$modele]['callback']; |
|
| 576 | + $primary = $styliseurs[$modele]['primary']; |
|
| 577 | + if (is_null($id) && $contexte) { |
|
| 578 | + if (isset($contexte['id'])) { |
|
| 579 | + $id = $contexte['id']; |
|
| 580 | + } elseif (isset($contexte[$primary])) { |
|
| 581 | + $id = $contexte[$primary]; |
|
| 582 | + } |
|
| 583 | + } |
|
| 584 | + if (is_null($id)) { |
|
| 585 | + $msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]); |
|
| 586 | + erreur_squelette($msg); |
|
| 587 | + // on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant |
|
| 588 | + $id = 0; |
|
| 589 | + } |
|
| 590 | + $modele = $styliseur($modele, $id); |
|
| 591 | + } |
|
| 592 | + |
|
| 593 | + return $modele; |
|
| 594 | 594 | } |
| 595 | 595 | |
| 596 | 596 | /** |
@@ -605,116 +605,116 @@ discard block |
||
| 605 | 605 | */ |
| 606 | 606 | function inclure_modele($type, $id, $params, $lien, string $connect = '', $env = []) { |
| 607 | 607 | |
| 608 | - static $compteur; |
|
| 609 | - if (++$compteur > 10) { |
|
| 610 | - return ''; |
|
| 611 | - } # ne pas boucler indefiniment |
|
| 612 | - |
|
| 613 | - $type = strtolower($type); |
|
| 614 | - $type = styliser_modele($type, $id); |
|
| 615 | - |
|
| 616 | - $fond = $class = ''; |
|
| 617 | - |
|
| 618 | - $params = array_filter(explode('|', $params)); |
|
| 619 | - if ($params) { |
|
| 620 | - $soustype = current($params); |
|
| 621 | - $soustype = strtolower(trim($soustype)); |
|
| 622 | - if (in_array($soustype, ['left', 'right', 'center', 'ajax'])) { |
|
| 623 | - $soustype = next($params); |
|
| 624 | - $soustype = strtolower($soustype); |
|
| 625 | - } |
|
| 626 | - |
|
| 627 | - if (preg_match(',^[a-z0-9_]+$,', $soustype)) { |
|
| 628 | - if (!trouve_modele($fond = ($type . '_' . $soustype))) { |
|
| 629 | - $fond = ''; |
|
| 630 | - $class = $soustype; |
|
| 631 | - } |
|
| 632 | - // enlever le sous type des params |
|
| 633 | - $params = array_diff($params, [$soustype]); |
|
| 634 | - } |
|
| 635 | - } |
|
| 636 | - |
|
| 637 | - // Si ca marche pas en precisant le sous-type, prendre le type |
|
| 638 | - if (!$fond && !trouve_modele($fond = $type)) { |
|
| 639 | - spip_log("Modele $type introuvable", _LOG_INFO_IMPORTANTE); |
|
| 640 | - $compteur--; |
|
| 641 | - return false; |
|
| 642 | - } |
|
| 643 | - $fond = 'modeles/' . $fond; |
|
| 644 | - // Creer le contexte |
|
| 645 | - $contexte = $env; |
|
| 646 | - // securiser le contexte des modèles : tout ce qui arrive de _request() doit être sanitizé |
|
| 647 | - foreach ($contexte as $k => &$v) { |
|
| 648 | - if (!is_null(_request($k)) && (!is_scalar($v) || (_request($k) === $v))) { |
|
| 649 | - include_spip('inc/texte_mini'); |
|
| 650 | - if (is_scalar($v)) { |
|
| 651 | - $v = spip_securise_valeur_env_modele($v); |
|
| 652 | - } else { |
|
| 653 | - array_walk_recursive($v, function (&$value, $index) { |
|
| 654 | - $value = spip_securise_valeur_env_modele($value); |
|
| 655 | - }); |
|
| 656 | - } |
|
| 657 | - } |
|
| 658 | - } |
|
| 659 | - |
|
| 660 | - $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 |
|
| 661 | - |
|
| 662 | - // Le numero du modele est mis dans l'environnement |
|
| 663 | - // d'une part sous l'identifiant "id" |
|
| 664 | - // et d'autre part sous l'identifiant de la cle primaire |
|
| 665 | - // par la fonction id_table_objet, |
|
| 666 | - // (<article1> =>> article =>> id_article =>> id_article=1) |
|
| 667 | - $_id = id_table_objet($type); |
|
| 668 | - $contexte['id'] = $contexte[$_id] = $id; |
|
| 669 | - |
|
| 670 | - if (isset($class)) { |
|
| 671 | - $contexte['class'] = $class; |
|
| 672 | - } |
|
| 673 | - |
|
| 674 | - // Si un lien a ete passe en parametre, ex: [<modele1>->url] ou [<modele1|title_du_lien{hreflang}->url] |
|
| 675 | - if ($lien) { |
|
| 676 | - # un eventuel guillemet (") sera reechappe par #ENV |
|
| 677 | - $contexte['lien'] = str_replace('"', '"', $lien['href']); |
|
| 678 | - $contexte['lien_class'] = $lien['class']; |
|
| 679 | - $contexte['lien_mime'] = $lien['mime']; |
|
| 680 | - $contexte['lien_title'] = $lien['title']; |
|
| 681 | - $contexte['lien_hreflang'] = $lien['hreflang']; |
|
| 682 | - } |
|
| 683 | - |
|
| 684 | - // Traiter les parametres |
|
| 685 | - // par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en> |
|
| 686 | - $arg_list = creer_contexte_de_modele($params); |
|
| 687 | - $contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args |
|
| 688 | - $contexte = array_merge($contexte, $arg_list); |
|
| 689 | - |
|
| 690 | - // Appliquer le modele avec le contexte |
|
| 691 | - $retour = recuperer_fond($fond, $contexte, [], $connect); |
|
| 692 | - |
|
| 693 | - // Regarder si le modele tient compte des liens (il *doit* alors indiquer |
|
| 694 | - // spip_lien_ok dans les classes de son conteneur de premier niveau ; |
|
| 695 | - // sinon, s'il y a un lien, on l'ajoute classiquement |
|
| 696 | - if ( |
|
| 697 | - strstr( |
|
| 698 | - ' ' . ($classes = extraire_attribut($retour, 'class')) . ' ', |
|
| 699 | - 'spip_lien_ok' |
|
| 700 | - ) |
|
| 701 | - ) { |
|
| 702 | - $retour = inserer_attribut( |
|
| 703 | - $retour, |
|
| 704 | - 'class', |
|
| 705 | - trim(str_replace(' spip_lien_ok ', ' ', " $classes ")) |
|
| 706 | - ); |
|
| 707 | - } else { |
|
| 708 | - if ($lien) { |
|
| 709 | - $retour = '<a href="' . $lien['href'] . '" class="' . $lien['class'] . '">' . $retour . '</a>'; |
|
| 710 | - } |
|
| 711 | - } |
|
| 712 | - |
|
| 713 | - $compteur--; |
|
| 714 | - |
|
| 715 | - return (isset($arg_list['ajax']) && $arg_list['ajax'] == 'ajax') |
|
| 716 | - ? encoder_contexte_ajax($contexte, '', $retour) |
|
| 717 | - : $retour; |
|
| 608 | + static $compteur; |
|
| 609 | + if (++$compteur > 10) { |
|
| 610 | + return ''; |
|
| 611 | + } # ne pas boucler indefiniment |
|
| 612 | + |
|
| 613 | + $type = strtolower($type); |
|
| 614 | + $type = styliser_modele($type, $id); |
|
| 615 | + |
|
| 616 | + $fond = $class = ''; |
|
| 617 | + |
|
| 618 | + $params = array_filter(explode('|', $params)); |
|
| 619 | + if ($params) { |
|
| 620 | + $soustype = current($params); |
|
| 621 | + $soustype = strtolower(trim($soustype)); |
|
| 622 | + if (in_array($soustype, ['left', 'right', 'center', 'ajax'])) { |
|
| 623 | + $soustype = next($params); |
|
| 624 | + $soustype = strtolower($soustype); |
|
| 625 | + } |
|
| 626 | + |
|
| 627 | + if (preg_match(',^[a-z0-9_]+$,', $soustype)) { |
|
| 628 | + if (!trouve_modele($fond = ($type . '_' . $soustype))) { |
|
| 629 | + $fond = ''; |
|
| 630 | + $class = $soustype; |
|
| 631 | + } |
|
| 632 | + // enlever le sous type des params |
|
| 633 | + $params = array_diff($params, [$soustype]); |
|
| 634 | + } |
|
| 635 | + } |
|
| 636 | + |
|
| 637 | + // Si ca marche pas en precisant le sous-type, prendre le type |
|
| 638 | + if (!$fond && !trouve_modele($fond = $type)) { |
|
| 639 | + spip_log("Modele $type introuvable", _LOG_INFO_IMPORTANTE); |
|
| 640 | + $compteur--; |
|
| 641 | + return false; |
|
| 642 | + } |
|
| 643 | + $fond = 'modeles/' . $fond; |
|
| 644 | + // Creer le contexte |
|
| 645 | + $contexte = $env; |
|
| 646 | + // securiser le contexte des modèles : tout ce qui arrive de _request() doit être sanitizé |
|
| 647 | + foreach ($contexte as $k => &$v) { |
|
| 648 | + if (!is_null(_request($k)) && (!is_scalar($v) || (_request($k) === $v))) { |
|
| 649 | + include_spip('inc/texte_mini'); |
|
| 650 | + if (is_scalar($v)) { |
|
| 651 | + $v = spip_securise_valeur_env_modele($v); |
|
| 652 | + } else { |
|
| 653 | + array_walk_recursive($v, function (&$value, $index) { |
|
| 654 | + $value = spip_securise_valeur_env_modele($value); |
|
| 655 | + }); |
|
| 656 | + } |
|
| 657 | + } |
|
| 658 | + } |
|
| 659 | + |
|
| 660 | + $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 |
|
| 661 | + |
|
| 662 | + // Le numero du modele est mis dans l'environnement |
|
| 663 | + // d'une part sous l'identifiant "id" |
|
| 664 | + // et d'autre part sous l'identifiant de la cle primaire |
|
| 665 | + // par la fonction id_table_objet, |
|
| 666 | + // (<article1> =>> article =>> id_article =>> id_article=1) |
|
| 667 | + $_id = id_table_objet($type); |
|
| 668 | + $contexte['id'] = $contexte[$_id] = $id; |
|
| 669 | + |
|
| 670 | + if (isset($class)) { |
|
| 671 | + $contexte['class'] = $class; |
|
| 672 | + } |
|
| 673 | + |
|
| 674 | + // Si un lien a ete passe en parametre, ex: [<modele1>->url] ou [<modele1|title_du_lien{hreflang}->url] |
|
| 675 | + if ($lien) { |
|
| 676 | + # un eventuel guillemet (") sera reechappe par #ENV |
|
| 677 | + $contexte['lien'] = str_replace('"', '"', $lien['href']); |
|
| 678 | + $contexte['lien_class'] = $lien['class']; |
|
| 679 | + $contexte['lien_mime'] = $lien['mime']; |
|
| 680 | + $contexte['lien_title'] = $lien['title']; |
|
| 681 | + $contexte['lien_hreflang'] = $lien['hreflang']; |
|
| 682 | + } |
|
| 683 | + |
|
| 684 | + // Traiter les parametres |
|
| 685 | + // par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en> |
|
| 686 | + $arg_list = creer_contexte_de_modele($params); |
|
| 687 | + $contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args |
|
| 688 | + $contexte = array_merge($contexte, $arg_list); |
|
| 689 | + |
|
| 690 | + // Appliquer le modele avec le contexte |
|
| 691 | + $retour = recuperer_fond($fond, $contexte, [], $connect); |
|
| 692 | + |
|
| 693 | + // Regarder si le modele tient compte des liens (il *doit* alors indiquer |
|
| 694 | + // spip_lien_ok dans les classes de son conteneur de premier niveau ; |
|
| 695 | + // sinon, s'il y a un lien, on l'ajoute classiquement |
|
| 696 | + if ( |
|
| 697 | + strstr( |
|
| 698 | + ' ' . ($classes = extraire_attribut($retour, 'class')) . ' ', |
|
| 699 | + 'spip_lien_ok' |
|
| 700 | + ) |
|
| 701 | + ) { |
|
| 702 | + $retour = inserer_attribut( |
|
| 703 | + $retour, |
|
| 704 | + 'class', |
|
| 705 | + trim(str_replace(' spip_lien_ok ', ' ', " $classes ")) |
|
| 706 | + ); |
|
| 707 | + } else { |
|
| 708 | + if ($lien) { |
|
| 709 | + $retour = '<a href="' . $lien['href'] . '" class="' . $lien['class'] . '">' . $retour . '</a>'; |
|
| 710 | + } |
|
| 711 | + } |
|
| 712 | + |
|
| 713 | + $compteur--; |
|
| 714 | + |
|
| 715 | + return (isset($arg_list['ajax']) && $arg_list['ajax'] == 'ajax') |
|
| 716 | + ? encoder_contexte_ajax($contexte, '', $retour) |
|
| 717 | + : $retour; |
|
| 718 | 718 | } |
| 719 | 719 | |
| 720 | 720 | /** |
@@ -728,15 +728,15 @@ discard block |
||
| 728 | 728 | * @return array|float|int|mixed|string|string[]|null |
| 729 | 729 | */ |
| 730 | 730 | function spip_securise_valeur_env_modele($valeur) { |
| 731 | - if (is_numeric($valeur) || is_bool($valeur) || is_null($valeur)) { |
|
| 732 | - return $valeur; |
|
| 733 | - } |
|
| 734 | - $valeur = (string)$valeur; |
|
| 735 | - if (str_starts_with($valeur, '@') && is_numeric(substr($valeur, 1))) { |
|
| 736 | - return $valeur; |
|
| 737 | - } |
|
| 738 | - // on laisse passer que les \w, les espaces et les -, le reste est supprimé |
|
| 739 | - return preg_replace(",[^\w\s-],", "", $valeur); |
|
| 731 | + if (is_numeric($valeur) || is_bool($valeur) || is_null($valeur)) { |
|
| 732 | + return $valeur; |
|
| 733 | + } |
|
| 734 | + $valeur = (string)$valeur; |
|
| 735 | + if (str_starts_with($valeur, '@') && is_numeric(substr($valeur, 1))) { |
|
| 736 | + return $valeur; |
|
| 737 | + } |
|
| 738 | + // on laisse passer que les \w, les espaces et les -, le reste est supprimé |
|
| 739 | + return preg_replace(",[^\w\s-],", "", $valeur); |
|
| 740 | 740 | } |
| 741 | 741 | |
| 742 | 742 | // Un inclure_page qui marche aussi pour l'espace prive |
@@ -745,99 +745,99 @@ discard block |
||
| 745 | 745 | // recuperer_fond($fond,$contexte,array('raw'=>true)) |
| 746 | 746 | function evaluer_fond($fond, $contexte = [], string $connect = '') { |
| 747 | 747 | |
| 748 | - $page = inclure_page($fond, $contexte, $connect); |
|
| 749 | - |
|
| 750 | - if (!$page) { |
|
| 751 | - return $page; |
|
| 752 | - } |
|
| 753 | - // eval $page et affecte $res |
|
| 754 | - include _ROOT_RESTREINT . 'public/evaluer_page.php'; |
|
| 755 | - |
|
| 756 | - // Lever un drapeau (global) si le fond utilise #SESSION |
|
| 757 | - // a destination de public/parametrer |
|
| 758 | - // pour remonter vers les inclusions appelantes |
|
| 759 | - // il faut bien lever ce drapeau apres avoir evalue le fond |
|
| 760 | - // pour ne pas faire descendre le flag vers les inclusions appelees |
|
| 761 | - if ( |
|
| 762 | - isset($page['invalideurs']) |
|
| 763 | - && isset($page['invalideurs']['session']) |
|
| 764 | - ) { |
|
| 765 | - $GLOBALS['cache_utilise_session'] = $page['invalideurs']['session']; |
|
| 766 | - } |
|
| 767 | - |
|
| 768 | - return $page; |
|
| 748 | + $page = inclure_page($fond, $contexte, $connect); |
|
| 749 | + |
|
| 750 | + if (!$page) { |
|
| 751 | + return $page; |
|
| 752 | + } |
|
| 753 | + // eval $page et affecte $res |
|
| 754 | + include _ROOT_RESTREINT . 'public/evaluer_page.php'; |
|
| 755 | + |
|
| 756 | + // Lever un drapeau (global) si le fond utilise #SESSION |
|
| 757 | + // a destination de public/parametrer |
|
| 758 | + // pour remonter vers les inclusions appelantes |
|
| 759 | + // il faut bien lever ce drapeau apres avoir evalue le fond |
|
| 760 | + // pour ne pas faire descendre le flag vers les inclusions appelees |
|
| 761 | + if ( |
|
| 762 | + isset($page['invalideurs']) |
|
| 763 | + && isset($page['invalideurs']['session']) |
|
| 764 | + ) { |
|
| 765 | + $GLOBALS['cache_utilise_session'] = $page['invalideurs']['session']; |
|
| 766 | + } |
|
| 767 | + |
|
| 768 | + return $page; |
|
| 769 | 769 | } |
| 770 | 770 | |
| 771 | 771 | |
| 772 | 772 | function page_base_href(&$texte) { |
| 773 | - static $set_html_base = null; |
|
| 774 | - if (is_null($set_html_base)) { |
|
| 775 | - if (!defined('_SET_HTML_BASE')) { |
|
| 776 | - // si la profondeur est superieure a 1 |
|
| 777 | - // est que ce n'est pas une url page ni une url action |
|
| 778 | - // activer par defaut |
|
| 779 | - $set_html_base = |
|
| 780 | - $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2) |
|
| 781 | - && _request(_SPIP_PAGE) !== 'login' |
|
| 782 | - && !_request('action'); |
|
| 783 | - } else { |
|
| 784 | - $set_html_base = _SET_HTML_BASE; |
|
| 785 | - } |
|
| 786 | - } |
|
| 787 | - |
|
| 788 | - if ( |
|
| 789 | - $set_html_base |
|
| 790 | - && isset($GLOBALS['html']) |
|
| 791 | - && $GLOBALS['html'] |
|
| 792 | - && $GLOBALS['profondeur_url'] > 0 |
|
| 793 | - && ($poshead = strpos($texte, '</head>')) !== false |
|
| 794 | - ) { |
|
| 795 | - $head = substr($texte, 0, $poshead); |
|
| 796 | - $insert = false; |
|
| 797 | - $href_base = false; |
|
| 798 | - if (!str_contains($head, '<base')) { |
|
| 799 | - $insert = true; |
|
| 800 | - } else { |
|
| 801 | - // si aucun <base ...> n'a de href il faut en inserer un |
|
| 802 | - // sinon juste re-ecrire les ancres si besoin |
|
| 803 | - $insert = true; |
|
| 804 | - include_spip('inc/filtres'); |
|
| 805 | - $bases = extraire_balises($head, 'base'); |
|
| 806 | - foreach ($bases as $base) { |
|
| 807 | - if ($href_base = extraire_attribut($base, 'href')) { |
|
| 808 | - $insert = false; |
|
| 809 | - break; |
|
| 810 | - } |
|
| 811 | - } |
|
| 812 | - } |
|
| 813 | - |
|
| 814 | - if ($insert) { |
|
| 815 | - include_spip('inc/filtres_mini'); |
|
| 816 | - // ajouter un base qui reglera tous les liens relatifs |
|
| 817 | - $href_base = url_absolue('./'); |
|
| 818 | - $base = "\n<base href=\"$href_base\" />"; |
|
| 819 | - if (($pos = strpos($head, '<head>')) !== false) { |
|
| 820 | - $head = substr_replace($head, $base, $pos + 6, 0); |
|
| 821 | - } elseif (preg_match(',<head[^>]*>,i', $head, $r)) { |
|
| 822 | - $head = str_replace($r[0], $r[0] . $base, $head); |
|
| 823 | - } |
|
| 824 | - $texte = $head . substr($texte, $poshead); |
|
| 825 | - } |
|
| 826 | - if ($href_base) { |
|
| 827 | - // gerer les ancres |
|
| 828 | - $base = $_SERVER['REQUEST_URI']; |
|
| 829 | - // pas de guillemets ni < dans l'URL qu'on insere dans le HTML |
|
| 830 | - if (str_contains($base, "'") || str_contains($base, '"') || str_contains($base, '<')) { |
|
| 831 | - $base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base); |
|
| 832 | - } |
|
| 833 | - if (str_contains($texte, "href='#")) { |
|
| 834 | - $texte = str_replace("href='#", "href='$base#", $texte); |
|
| 835 | - } |
|
| 836 | - if (str_contains($texte, 'href="#')) { |
|
| 837 | - $texte = str_replace('href="#', "href=\"$base#", $texte); |
|
| 838 | - } |
|
| 839 | - } |
|
| 840 | - } |
|
| 773 | + static $set_html_base = null; |
|
| 774 | + if (is_null($set_html_base)) { |
|
| 775 | + if (!defined('_SET_HTML_BASE')) { |
|
| 776 | + // si la profondeur est superieure a 1 |
|
| 777 | + // est que ce n'est pas une url page ni une url action |
|
| 778 | + // activer par defaut |
|
| 779 | + $set_html_base = |
|
| 780 | + $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2) |
|
| 781 | + && _request(_SPIP_PAGE) !== 'login' |
|
| 782 | + && !_request('action'); |
|
| 783 | + } else { |
|
| 784 | + $set_html_base = _SET_HTML_BASE; |
|
| 785 | + } |
|
| 786 | + } |
|
| 787 | + |
|
| 788 | + if ( |
|
| 789 | + $set_html_base |
|
| 790 | + && isset($GLOBALS['html']) |
|
| 791 | + && $GLOBALS['html'] |
|
| 792 | + && $GLOBALS['profondeur_url'] > 0 |
|
| 793 | + && ($poshead = strpos($texte, '</head>')) !== false |
|
| 794 | + ) { |
|
| 795 | + $head = substr($texte, 0, $poshead); |
|
| 796 | + $insert = false; |
|
| 797 | + $href_base = false; |
|
| 798 | + if (!str_contains($head, '<base')) { |
|
| 799 | + $insert = true; |
|
| 800 | + } else { |
|
| 801 | + // si aucun <base ...> n'a de href il faut en inserer un |
|
| 802 | + // sinon juste re-ecrire les ancres si besoin |
|
| 803 | + $insert = true; |
|
| 804 | + include_spip('inc/filtres'); |
|
| 805 | + $bases = extraire_balises($head, 'base'); |
|
| 806 | + foreach ($bases as $base) { |
|
| 807 | + if ($href_base = extraire_attribut($base, 'href')) { |
|
| 808 | + $insert = false; |
|
| 809 | + break; |
|
| 810 | + } |
|
| 811 | + } |
|
| 812 | + } |
|
| 813 | + |
|
| 814 | + if ($insert) { |
|
| 815 | + include_spip('inc/filtres_mini'); |
|
| 816 | + // ajouter un base qui reglera tous les liens relatifs |
|
| 817 | + $href_base = url_absolue('./'); |
|
| 818 | + $base = "\n<base href=\"$href_base\" />"; |
|
| 819 | + if (($pos = strpos($head, '<head>')) !== false) { |
|
| 820 | + $head = substr_replace($head, $base, $pos + 6, 0); |
|
| 821 | + } elseif (preg_match(',<head[^>]*>,i', $head, $r)) { |
|
| 822 | + $head = str_replace($r[0], $r[0] . $base, $head); |
|
| 823 | + } |
|
| 824 | + $texte = $head . substr($texte, $poshead); |
|
| 825 | + } |
|
| 826 | + if ($href_base) { |
|
| 827 | + // gerer les ancres |
|
| 828 | + $base = $_SERVER['REQUEST_URI']; |
|
| 829 | + // pas de guillemets ni < dans l'URL qu'on insere dans le HTML |
|
| 830 | + if (str_contains($base, "'") || str_contains($base, '"') || str_contains($base, '<')) { |
|
| 831 | + $base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base); |
|
| 832 | + } |
|
| 833 | + if (str_contains($texte, "href='#")) { |
|
| 834 | + $texte = str_replace("href='#", "href='$base#", $texte); |
|
| 835 | + } |
|
| 836 | + if (str_contains($texte, 'href="#')) { |
|
| 837 | + $texte = str_replace('href="#', "href=\"$base#", $texte); |
|
| 838 | + } |
|
| 839 | + } |
|
| 840 | + } |
|
| 841 | 841 | } |
| 842 | 842 | |
| 843 | 843 | |
@@ -847,7 +847,7 @@ discard block |
||
| 847 | 847 | * Ceux spécifiques à SPIP commencent par X-Spip |
| 848 | 848 | */ |
| 849 | 849 | function envoyer_entetes($entetes) { |
| 850 | - foreach ($entetes as $k => $v) { |
|
| 851 | - @header(strlen((string) $v) ? "$k: $v" : $k); |
|
| 852 | - } |
|
| 850 | + foreach ($entetes as $k => $v) { |
|
| 851 | + @header(strlen((string) $v) ? "$k: $v" : $k); |
|
| 852 | + } |
|
| 853 | 853 | } |
@@ -33,7 +33,7 @@ discard block |
||
| 33 | 33 | |
| 34 | 34 | $GLOBALS['contexte'] = calculer_contexte(); |
| 35 | 35 | $page = ['contexte_implicite' => calculer_contexte_implicite()]; |
| 36 | - $page['contexte_implicite']['cache'] = $fond . preg_replace( |
|
| 36 | + $page['contexte_implicite']['cache'] = $fond.preg_replace( |
|
| 37 | 37 | ',\.[a-zA-Z0-9]*$,', |
| 38 | 38 | '', |
| 39 | 39 | preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI']) |
@@ -133,7 +133,7 @@ discard block |
||
| 133 | 133 | if ($page === '') { |
| 134 | 134 | $erreur = _T( |
| 135 | 135 | 'info_erreur_squelette2', |
| 136 | - ['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES] |
|
| 136 | + ['fichier' => spip_htmlspecialchars($fond).'.'._EXTENSION_SQUELETTES] |
|
| 137 | 137 | ); |
| 138 | 138 | erreur_squelette($erreur); |
| 139 | 139 | // eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4 |
@@ -174,7 +174,7 @@ discard block |
||
| 174 | 174 | if ( |
| 175 | 175 | $lastmodified && !isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && !isset($page['entetes']['Last-Modified']) |
| 176 | 176 | ) { |
| 177 | - $page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT'; |
|
| 177 | + $page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified).' GMT'; |
|
| 178 | 178 | } |
| 179 | 179 | |
| 180 | 180 | // fermer la connexion apres les headers si requete HEAD |
@@ -206,7 +206,7 @@ discard block |
||
| 206 | 206 | if (!defined('_CONTEXTE_IGNORE_LISTE_VARIABLES')) { |
| 207 | 207 | nettoyer_uri_var(''); |
| 208 | 208 | } |
| 209 | - $preg_ignore_variables = '/(' . implode('|',_CONTEXTE_IGNORE_LISTE_VARIABLES) . ')/'; |
|
| 209 | + $preg_ignore_variables = '/('.implode('|', _CONTEXTE_IGNORE_LISTE_VARIABLES).')/'; |
|
| 210 | 210 | } |
| 211 | 211 | |
| 212 | 212 | $contexte = []; |
@@ -247,7 +247,7 @@ discard block |
||
| 247 | 247 | 'spip_version_code' => $GLOBALS['spip_version_code'], |
| 248 | 248 | ]; |
| 249 | 249 | if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { |
| 250 | - $contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST']; |
|
| 250 | + $contexte_implicite['host'] .= '|'.$_SERVER['HTTP_X_FORWARDED_HOST']; |
|
| 251 | 251 | } |
| 252 | 252 | |
| 253 | 253 | return $contexte_implicite; |
@@ -582,7 +582,7 @@ discard block |
||
| 582 | 582 | } |
| 583 | 583 | } |
| 584 | 584 | if (is_null($id)) { |
| 585 | - $msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]); |
|
| 585 | + $msg = "modeles/$modele : "._T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]); |
|
| 586 | 586 | erreur_squelette($msg); |
| 587 | 587 | // on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant |
| 588 | 588 | $id = 0; |
@@ -625,7 +625,7 @@ discard block |
||
| 625 | 625 | } |
| 626 | 626 | |
| 627 | 627 | if (preg_match(',^[a-z0-9_]+$,', $soustype)) { |
| 628 | - if (!trouve_modele($fond = ($type . '_' . $soustype))) { |
|
| 628 | + if (!trouve_modele($fond = ($type.'_'.$soustype))) { |
|
| 629 | 629 | $fond = ''; |
| 630 | 630 | $class = $soustype; |
| 631 | 631 | } |
@@ -640,7 +640,7 @@ discard block |
||
| 640 | 640 | $compteur--; |
| 641 | 641 | return false; |
| 642 | 642 | } |
| 643 | - $fond = 'modeles/' . $fond; |
|
| 643 | + $fond = 'modeles/'.$fond; |
|
| 644 | 644 | // Creer le contexte |
| 645 | 645 | $contexte = $env; |
| 646 | 646 | // securiser le contexte des modèles : tout ce qui arrive de _request() doit être sanitizé |
@@ -650,7 +650,7 @@ discard block |
||
| 650 | 650 | if (is_scalar($v)) { |
| 651 | 651 | $v = spip_securise_valeur_env_modele($v); |
| 652 | 652 | } else { |
| 653 | - array_walk_recursive($v, function (&$value, $index) { |
|
| 653 | + array_walk_recursive($v, function(&$value, $index) { |
|
| 654 | 654 | $value = spip_securise_valeur_env_modele($value); |
| 655 | 655 | }); |
| 656 | 656 | } |
@@ -695,7 +695,7 @@ discard block |
||
| 695 | 695 | // sinon, s'il y a un lien, on l'ajoute classiquement |
| 696 | 696 | if ( |
| 697 | 697 | strstr( |
| 698 | - ' ' . ($classes = extraire_attribut($retour, 'class')) . ' ', |
|
| 698 | + ' '.($classes = extraire_attribut($retour, 'class')).' ', |
|
| 699 | 699 | 'spip_lien_ok' |
| 700 | 700 | ) |
| 701 | 701 | ) { |
@@ -706,7 +706,7 @@ discard block |
||
| 706 | 706 | ); |
| 707 | 707 | } else { |
| 708 | 708 | if ($lien) { |
| 709 | - $retour = '<a href="' . $lien['href'] . '" class="' . $lien['class'] . '">' . $retour . '</a>'; |
|
| 709 | + $retour = '<a href="'.$lien['href'].'" class="'.$lien['class'].'">'.$retour.'</a>'; |
|
| 710 | 710 | } |
| 711 | 711 | } |
| 712 | 712 | |
@@ -731,7 +731,7 @@ discard block |
||
| 731 | 731 | if (is_numeric($valeur) || is_bool($valeur) || is_null($valeur)) { |
| 732 | 732 | return $valeur; |
| 733 | 733 | } |
| 734 | - $valeur = (string)$valeur; |
|
| 734 | + $valeur = (string) $valeur; |
|
| 735 | 735 | if (str_starts_with($valeur, '@') && is_numeric(substr($valeur, 1))) { |
| 736 | 736 | return $valeur; |
| 737 | 737 | } |
@@ -751,7 +751,7 @@ discard block |
||
| 751 | 751 | return $page; |
| 752 | 752 | } |
| 753 | 753 | // eval $page et affecte $res |
| 754 | - include _ROOT_RESTREINT . 'public/evaluer_page.php'; |
|
| 754 | + include _ROOT_RESTREINT.'public/evaluer_page.php'; |
|
| 755 | 755 | |
| 756 | 756 | // Lever un drapeau (global) si le fond utilise #SESSION |
| 757 | 757 | // a destination de public/parametrer |
@@ -819,16 +819,16 @@ discard block |
||
| 819 | 819 | if (($pos = strpos($head, '<head>')) !== false) { |
| 820 | 820 | $head = substr_replace($head, $base, $pos + 6, 0); |
| 821 | 821 | } elseif (preg_match(',<head[^>]*>,i', $head, $r)) { |
| 822 | - $head = str_replace($r[0], $r[0] . $base, $head); |
|
| 822 | + $head = str_replace($r[0], $r[0].$base, $head); |
|
| 823 | 823 | } |
| 824 | - $texte = $head . substr($texte, $poshead); |
|
| 824 | + $texte = $head.substr($texte, $poshead); |
|
| 825 | 825 | } |
| 826 | 826 | if ($href_base) { |
| 827 | 827 | // gerer les ancres |
| 828 | 828 | $base = $_SERVER['REQUEST_URI']; |
| 829 | 829 | // pas de guillemets ni < dans l'URL qu'on insere dans le HTML |
| 830 | 830 | if (str_contains($base, "'") || str_contains($base, '"') || str_contains($base, '<')) { |
| 831 | - $base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base); |
|
| 831 | + $base = str_replace(["'", '"', '<'], ['%27', '%22', '%3C'], $base); |
|
| 832 | 832 | } |
| 833 | 833 | if (str_contains($texte, "href='#")) { |
| 834 | 834 | $texte = str_replace("href='#", "href='$base#", $texte); |