Completed
Push — master ( 4aa2c5...a38486 )
by cam
01:23
created
ecrire/inc/presentation_mini.php 2 patches
Indentation   +136 added lines, -136 removed lines patch added patch discarded remove patch
@@ -16,7 +16,7 @@  discard block
 block discarded – undo
16 16
  * @package SPIP\Core\Affichage
17 17
  **/
18 18
 if (!defined('_ECRIRE_INC_VERSION')) {
19
-	return;
19
+    return;
20 20
 }
21 21
 
22 22
 /**
@@ -25,7 +25,7 @@  discard block
 block discarded – undo
25 25
  * @return string Code HTML
26 26
  */
27 27
 function debut_grand_cadre() {
28
- return "\n<div class = 'table_page'>\n";
28
+    return "\n<div class = 'table_page'>\n";
29 29
 }
30 30
 
31 31
 /**
@@ -34,7 +34,7 @@  discard block
 block discarded – undo
34 34
  * @return string Code HTML
35 35
  */
36 36
 function fin_grand_cadre() {
37
- return "\n</div>";
37
+    return "\n</div>";
38 38
 }
39 39
 
40 40
 // Debut de la colonne de gauche
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
  * @return string Code HTML
50 50
  */
51 51
 function debut_gauche() {
52
-	return "<div id = 'conteneur' class = ''>\n<div id = 'navigation' class = 'lat' role = 'contentinfo'>\n";
52
+    return "<div id = 'conteneur' class = ''>\n<div id = 'navigation' class = 'lat' role = 'contentinfo'>\n";
53 53
 }
54 54
 
55 55
 /**
@@ -58,7 +58,7 @@  discard block
 block discarded – undo
58 58
  * @return string Code HTML
59 59
  */
60 60
 function fin_gauche() {
61
- return "</div></div><br class = 'nettoyeur' />";
61
+    return "</div></div><br class = 'nettoyeur' />";
62 62
 }
63 63
 
64 64
 /**
@@ -67,13 +67,13 @@  discard block
 block discarded – undo
67 67
  * @return string Code HTML
68 68
  */
69 69
 function creer_colonne_droite() {
70
-	static $deja_colonne_droite;
71
-	if ($deja_colonne_droite) {
72
-		return '';
73
-	}
74
-	$deja_colonne_droite = true;
70
+    static $deja_colonne_droite;
71
+    if ($deja_colonne_droite) {
72
+        return '';
73
+    }
74
+    $deja_colonne_droite = true;
75 75
 
76
-	return "\n</div><div id='extra' class='lat' role='complementary'>";
76
+    return "\n</div><div id='extra' class='lat' role='complementary'>";
77 77
 }
78 78
 
79 79
 /**
@@ -82,10 +82,10 @@  discard block
 block discarded – undo
82 82
  * @return string Code HTML
83 83
  */
84 84
 function debut_droite() {
85
-	return liste_objets_bloques(_request('exec'))
86
-	. creer_colonne_droite()
87
-	. '</div>'
88
-	. "\n<div id='contenu'>";
85
+    return liste_objets_bloques(_request('exec'))
86
+    . creer_colonne_droite()
87
+    . '</div>'
88
+    . "\n<div id='contenu'>";
89 89
 }
90 90
 
91 91
 /**
@@ -107,32 +107,32 @@  discard block
 block discarded – undo
107 107
  *     Code HTML
108 108
  **/
109 109
 function liste_objets_bloques($exec, $contexte = [], $auteur = null): string {
110
-	$res = '';
111
-	include_spip('inc/config');
112
-	if (lire_config('articles_modif', 'non') !== 'non') {
113
-		include_spip('inc/drapeau_edition');
114
-		if (is_null($auteur)) {
115
-			$auteur = $GLOBALS['visiteur_session'];
116
-		}
117
-		if (
118
-			$en_cours = trouver_objet_exec($exec)
119
-			and $en_cours['edition']
120
-			and $type = $en_cours['type']
121
-			and ((isset($contexte[$en_cours['id_table_objet']]) and $id = $contexte[$en_cours['id_table_objet']])
122
-				or $id = _request($en_cours['id_table_objet']))
123
-		) {
124
-			// marquer le fait que l'objet est ouvert en edition par toto
125
-			// a telle date ; une alerte sera donnee aux autres redacteurs
126
-			signale_edition($id, $auteur, $type);
127
-		}
128
-
129
-		$objets_ouverts = liste_drapeau_edition($auteur['id_auteur']);
130
-		if (count($objets_ouverts)) {
131
-			$res .= recuperer_fond('prive/objets/liste/objets-en-edition', [], ['ajax' => true]);
132
-		}
133
-	}
134
-
135
-	return $res;
110
+    $res = '';
111
+    include_spip('inc/config');
112
+    if (lire_config('articles_modif', 'non') !== 'non') {
113
+        include_spip('inc/drapeau_edition');
114
+        if (is_null($auteur)) {
115
+            $auteur = $GLOBALS['visiteur_session'];
116
+        }
117
+        if (
118
+            $en_cours = trouver_objet_exec($exec)
119
+            and $en_cours['edition']
120
+            and $type = $en_cours['type']
121
+            and ((isset($contexte[$en_cours['id_table_objet']]) and $id = $contexte[$en_cours['id_table_objet']])
122
+                or $id = _request($en_cours['id_table_objet']))
123
+        ) {
124
+            // marquer le fait que l'objet est ouvert en edition par toto
125
+            // a telle date ; une alerte sera donnee aux autres redacteurs
126
+            signale_edition($id, $auteur, $type);
127
+        }
128
+
129
+        $objets_ouverts = liste_drapeau_edition($auteur['id_auteur']);
130
+        if (count($objets_ouverts)) {
131
+            $res .= recuperer_fond('prive/objets/liste/objets-en-edition', [], ['ajax' => true]);
132
+        }
133
+    }
134
+
135
+    return $res;
136 136
 }
137 137
 
138 138
 
@@ -146,20 +146,20 @@  discard block
 block discarded – undo
146 146
  * @return string Code HTML
147 147
  **/
148 148
 function fin_page() {
149
-	include_spip('inc/pipelines');
150
-	// avec &var_profile=1 on a le tableau de mesures SQL
151
-	$debug = ((_request('exec') !== 'valider_xml')
152
-		and ((_request('var_mode') == 'debug')
153
-			or (isset($GLOBALS['tableau_des_temps']) and $GLOBALS['tableau_des_temps'])
154
-			and isset($_COOKIE['spip_admin'])));
155
-	$t = '</div><div id="pied"><div class="largeur">'
156
-		. recuperer_fond('prive/squelettes/inclure/pied')
157
-		. '</div>'
158
-		. '</div></div>' // cf. div#page et div.largeur ouvertes dans conmmencer_page()
159
-		. ($debug ? erreur_squelette() : '')
160
-		. "</body></html>\n";
161
-
162
-	return f_queue($t);
149
+    include_spip('inc/pipelines');
150
+    // avec &var_profile=1 on a le tableau de mesures SQL
151
+    $debug = ((_request('exec') !== 'valider_xml')
152
+        and ((_request('var_mode') == 'debug')
153
+            or (isset($GLOBALS['tableau_des_temps']) and $GLOBALS['tableau_des_temps'])
154
+            and isset($_COOKIE['spip_admin'])));
155
+    $t = '</div><div id="pied"><div class="largeur">'
156
+        . recuperer_fond('prive/squelettes/inclure/pied')
157
+        . '</div>'
158
+        . '</div></div>' // cf. div#page et div.largeur ouvertes dans conmmencer_page()
159
+        . ($debug ? erreur_squelette() : '')
160
+        . "</body></html>\n";
161
+
162
+    return f_queue($t);
163 163
 }
164 164
 
165 165
 /**
@@ -174,22 +174,22 @@  discard block
 block discarded – undo
174 174
  * @return string Code HTML
175 175
  **/
176 176
 function html_tests_js() {
177
-	if (_SPIP_AJAX and !defined('_TESTER_NOSCRIPT')) {
178
-		// pour le pied de page (deja defini si on est validation XML)
179
-		define(
180
-			'_TESTER_NOSCRIPT',
181
-			"<noscript>\n<div style='display:none;'><img src='"
182
-			. generer_url_ecrire('test_ajax', 'js=-1')
183
-			. "' width='1' height='1' alt='' /></div></noscript>\n"
184
-		);
185
-	}
186
-
187
-	$rejouer = '';
188
-	if (defined('_SESSION_REJOUER')) {
189
-		$rejouer = (_SESSION_REJOUER === true) ? rejouer_session() : _SESSION_REJOUER;
190
-	}
191
-
192
-	return $rejouer . (defined('_TESTER_NOSCRIPT') ? _TESTER_NOSCRIPT : '');
177
+    if (_SPIP_AJAX and !defined('_TESTER_NOSCRIPT')) {
178
+        // pour le pied de page (deja defini si on est validation XML)
179
+        define(
180
+            '_TESTER_NOSCRIPT',
181
+            "<noscript>\n<div style='display:none;'><img src='"
182
+            . generer_url_ecrire('test_ajax', 'js=-1')
183
+            . "' width='1' height='1' alt='' /></div></noscript>\n"
184
+        );
185
+    }
186
+
187
+    $rejouer = '';
188
+    if (defined('_SESSION_REJOUER')) {
189
+        $rejouer = (_SESSION_REJOUER === true) ? rejouer_session() : _SESSION_REJOUER;
190
+    }
191
+
192
+    return $rejouer . (defined('_TESTER_NOSCRIPT') ? _TESTER_NOSCRIPT : '');
193 193
 }
194 194
 
195 195
 /**
@@ -199,25 +199,25 @@  discard block
 block discarded – undo
199 199
  **/
200 200
 function info_maj_spip() {
201 201
 
202
-	$maj = $GLOBALS['meta']['info_maj_spip'] ?? null;
203
-	if (!$maj) {
204
-		return '';
205
-	}
202
+    $maj = $GLOBALS['meta']['info_maj_spip'] ?? null;
203
+    if (!$maj) {
204
+        return '';
205
+    }
206 206
 
207
-	$maj = explode('|', $maj);
208
-	// c'est une ancienne notif, on a fait la maj depuis !
209
-	if ($GLOBALS['spip_version_branche'] !== reset($maj)) {
210
-		return '';
211
-	}
207
+    $maj = explode('|', $maj);
208
+    // c'est une ancienne notif, on a fait la maj depuis !
209
+    if ($GLOBALS['spip_version_branche'] !== reset($maj)) {
210
+        return '';
211
+    }
212 212
 
213
-	if (!autoriser('webmestre')) {
214
-		return '';
215
-	}
213
+    if (!autoriser('webmestre')) {
214
+        return '';
215
+    }
216 216
 
217
-	array_shift($maj);
218
-	$maj = implode('|', $maj);
217
+    array_shift($maj);
218
+    $maj = implode('|', $maj);
219 219
 
220
-	return "$maj<br />";
220
+    return "$maj<br />";
221 221
 }
222 222
 
223 223
 /**
@@ -228,43 +228,43 @@  discard block
 block discarded – undo
228 228
  **/
229 229
 function info_copyright() {
230 230
 
231
-	$version = $GLOBALS['spip_version_affichee'];
232
-
233
-	//
234
-	// Mention, le cas echeant, de la revision SVN courante
235
-	//
236
-	if ($vcs = version_vcs_courante(_DIR_RACINE, true)) {
237
-		if ($vcs['vcs'] === 'GIT') {
238
-			$url = 'https://git.spip.net/spip/spip/commit/' . $vcs['commit'];
239
-		} elseif ($vcs['vcs'] === 'SVN') {
240
-			$url = 'https://core.spip.net/projects/spip/repository/revisions/' . $vcs['commit'];
241
-		} else {
242
-			$url = '';
243
-		}
244
-		// affichage "GIT [master: abcdef]"
245
-		$commit = $vcs['commit_short'] ?? $vcs['commit'];
246
-		if ($url) {
247
-			$commit = "<a href=\"$url\" target=\"_blank\" rel=\"noopener noreferrer\">$commit</a>";
248
-		}
249
-		if ($vcs['branch']) {
250
-			$commit = $vcs['branch'] . ': ' . $commit;
251
-		}
252
-		$version .= " {$vcs['vcs']} [$commit]";
253
-	}
254
-
255
-	// et la version de l'ecran de securite
256
-	$secu = defined('_ECRAN_SECURITE')
257
-		? '<br />' . _T('ecran_securite', ['version' => _ECRAN_SECURITE])
258
-		: '';
259
-
260
-	return _T(
261
-		'info_copyright',
262
-		[
263
-			'spip' => "<b>SPIP $version</b> ",
264
-			'lien_gpl' => '<a href="https://www.gnu.org/licenses/gpl-3.0.html" class="aide popin">' . _T('info_copyright_gpl') . '</a>'
265
-		]
266
-	)
267
-	. $secu;
231
+    $version = $GLOBALS['spip_version_affichee'];
232
+
233
+    //
234
+    // Mention, le cas echeant, de la revision SVN courante
235
+    //
236
+    if ($vcs = version_vcs_courante(_DIR_RACINE, true)) {
237
+        if ($vcs['vcs'] === 'GIT') {
238
+            $url = 'https://git.spip.net/spip/spip/commit/' . $vcs['commit'];
239
+        } elseif ($vcs['vcs'] === 'SVN') {
240
+            $url = 'https://core.spip.net/projects/spip/repository/revisions/' . $vcs['commit'];
241
+        } else {
242
+            $url = '';
243
+        }
244
+        // affichage "GIT [master: abcdef]"
245
+        $commit = $vcs['commit_short'] ?? $vcs['commit'];
246
+        if ($url) {
247
+            $commit = "<a href=\"$url\" target=\"_blank\" rel=\"noopener noreferrer\">$commit</a>";
248
+        }
249
+        if ($vcs['branch']) {
250
+            $commit = $vcs['branch'] . ': ' . $commit;
251
+        }
252
+        $version .= " {$vcs['vcs']} [$commit]";
253
+    }
254
+
255
+    // et la version de l'ecran de securite
256
+    $secu = defined('_ECRAN_SECURITE')
257
+        ? '<br />' . _T('ecran_securite', ['version' => _ECRAN_SECURITE])
258
+        : '';
259
+
260
+    return _T(
261
+        'info_copyright',
262
+        [
263
+            'spip' => "<b>SPIP $version</b> ",
264
+            'lien_gpl' => '<a href="https://www.gnu.org/licenses/gpl-3.0.html" class="aide popin">' . _T('info_copyright_gpl') . '</a>'
265
+        ]
266
+    )
267
+    . $secu;
268 268
 }
269 269
 
270 270
 /**
@@ -279,17 +279,17 @@  discard block
 block discarded – undo
279 279
  * @return string             Code HTML
280 280
  **/
281 281
 function formulaire_recherche($page, $complement = '') {
282
-	$recherche = _request('recherche');
283
-	$recherche_aff = entites_html($recherche);
284
-	if (!strlen($recherche)) {
285
-		$recherche_aff = _T('info_rechercher');
286
-		$onfocus = " onfocus=\"this.value='';\"";
287
-	} else {
288
-		$onfocus = '';
289
-	}
290
-
291
-	$form = '<input type="text" size="10" value="' . $recherche_aff . '" name="recherche" class="recherche" accesskey="r"' . $onfocus . ' />';
292
-	$form .= "<input type='image' src='" . chemin_image('rechercher-20.png') . "' name='submit' class='submit' alt='" . _T('info_rechercher') . "' />";
293
-
294
-	return "<div class='spip_recherche'>" . generer_form_ecrire($page, $form . $complement, " method='get'") . '</div>';
282
+    $recherche = _request('recherche');
283
+    $recherche_aff = entites_html($recherche);
284
+    if (!strlen($recherche)) {
285
+        $recherche_aff = _T('info_rechercher');
286
+        $onfocus = " onfocus=\"this.value='';\"";
287
+    } else {
288
+        $onfocus = '';
289
+    }
290
+
291
+    $form = '<input type="text" size="10" value="' . $recherche_aff . '" name="recherche" class="recherche" accesskey="r"' . $onfocus . ' />';
292
+    $form .= "<input type='image' src='" . chemin_image('rechercher-20.png') . "' name='submit' class='submit' alt='" . _T('info_rechercher') . "' />";
293
+
294
+    return "<div class='spip_recherche'>" . generer_form_ecrire($page, $form . $complement, " method='get'") . '</div>';
295 295
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -189,7 +189,7 @@  discard block
 block discarded – undo
189 189
 		$rejouer = (_SESSION_REJOUER === true) ? rejouer_session() : _SESSION_REJOUER;
190 190
 	}
191 191
 
192
-	return $rejouer . (defined('_TESTER_NOSCRIPT') ? _TESTER_NOSCRIPT : '');
192
+	return $rejouer.(defined('_TESTER_NOSCRIPT') ? _TESTER_NOSCRIPT : '');
193 193
 }
194 194
 
195 195
 /**
@@ -235,9 +235,9 @@  discard block
 block discarded – undo
235 235
 	//
236 236
 	if ($vcs = version_vcs_courante(_DIR_RACINE, true)) {
237 237
 		if ($vcs['vcs'] === 'GIT') {
238
-			$url = 'https://git.spip.net/spip/spip/commit/' . $vcs['commit'];
238
+			$url = 'https://git.spip.net/spip/spip/commit/'.$vcs['commit'];
239 239
 		} elseif ($vcs['vcs'] === 'SVN') {
240
-			$url = 'https://core.spip.net/projects/spip/repository/revisions/' . $vcs['commit'];
240
+			$url = 'https://core.spip.net/projects/spip/repository/revisions/'.$vcs['commit'];
241 241
 		} else {
242 242
 			$url = '';
243 243
 		}
@@ -247,21 +247,21 @@  discard block
 block discarded – undo
247 247
 			$commit = "<a href=\"$url\" target=\"_blank\" rel=\"noopener noreferrer\">$commit</a>";
248 248
 		}
249 249
 		if ($vcs['branch']) {
250
-			$commit = $vcs['branch'] . ': ' . $commit;
250
+			$commit = $vcs['branch'].': '.$commit;
251 251
 		}
252 252
 		$version .= " {$vcs['vcs']} [$commit]";
253 253
 	}
254 254
 
255 255
 	// et la version de l'ecran de securite
256 256
 	$secu = defined('_ECRAN_SECURITE')
257
-		? '<br />' . _T('ecran_securite', ['version' => _ECRAN_SECURITE])
257
+		? '<br />'._T('ecran_securite', ['version' => _ECRAN_SECURITE])
258 258
 		: '';
259 259
 
260 260
 	return _T(
261 261
 		'info_copyright',
262 262
 		[
263 263
 			'spip' => "<b>SPIP $version</b> ",
264
-			'lien_gpl' => '<a href="https://www.gnu.org/licenses/gpl-3.0.html" class="aide popin">' . _T('info_copyright_gpl') . '</a>'
264
+			'lien_gpl' => '<a href="https://www.gnu.org/licenses/gpl-3.0.html" class="aide popin">'._T('info_copyright_gpl').'</a>'
265 265
 		]
266 266
 	)
267 267
 	. $secu;
@@ -288,8 +288,8 @@  discard block
 block discarded – undo
288 288
 		$onfocus = '';
289 289
 	}
290 290
 
291
-	$form = '<input type="text" size="10" value="' . $recherche_aff . '" name="recherche" class="recherche" accesskey="r"' . $onfocus . ' />';
292
-	$form .= "<input type='image' src='" . chemin_image('rechercher-20.png') . "' name='submit' class='submit' alt='" . _T('info_rechercher') . "' />";
291
+	$form = '<input type="text" size="10" value="'.$recherche_aff.'" name="recherche" class="recherche" accesskey="r"'.$onfocus.' />';
292
+	$form .= "<input type='image' src='".chemin_image('rechercher-20.png')."' name='submit' class='submit' alt='"._T('info_rechercher')."' />";
293 293
 
294
-	return "<div class='spip_recherche'>" . generer_form_ecrire($page, $form . $complement, " method='get'") . '</div>';
294
+	return "<div class='spip_recherche'>".generer_form_ecrire($page, $form.$complement, " method='get'").'</div>';
295 295
 }
Please login to merge, or discard this patch.
ecrire/src/Texte/Collecteur/AbstractCollecteur.php 3 patches
Indentation   +149 added lines, -149 removed lines patch added patch discarded remove patch
@@ -14,154 +14,154 @@
 block discarded – undo
14 14
 
15 15
 abstract class AbstractCollecteur {
16 16
 
17
-	protected static string $markPrefix = 'COLLECT';
18
-	protected string $markId;
19
-
20
-	/**
21
-	 * Collecteur générique des occurences d'une preg dans un texte avec leurs positions et longueur
22
-	 * @param string $texte
23
-	 *   texte à analyser pour la collecte
24
-	 * @param string $if_chars
25
-	 *   caractere(s) à tester avant de tenter la preg
26
-	 * @param string $start_with
27
-	 *   caractere(s) par lesquels commencent l'expression recherchée (permet de démarrer la preg à la prochaine occurence de cette chaine)
28
-	 * @param string $preg
29
-	 *   preg utilisée pour la collecte
30
-	 * @param int $max_items
31
-	 *   pour limiter le nombre de preg collectée (pour la detection simple de présence par exemple)
32
-	 * @return array
33
-	 */
34
-	protected static function collecteur(string $texte, string $if_chars, string $start_with, string $preg, int $max_items = 0): array {
35
-
36
-		$collection = [];
37
-		$pos = 0;
38
-		while (
39
-			(!$if_chars || strpos($texte, $if_chars, $pos) !== false)
40
-			and ($next = ($start_with ? strpos($texte, $start_with, $pos) : $pos)) !== false
41
-			and preg_match($preg, $texte, $r, PREG_OFFSET_CAPTURE, $next)) {
42
-
43
-			$found_pos = $r[0][1];
44
-			$found_length = strlen($r[0][0]);
45
-			$match = [
46
-				'raw' => $r[0][0],
47
-				'match' => array_column($r, 0),
48
-				'pos' => $found_pos,
49
-				'length' => $found_length
50
-			];
51
-
52
-			$collection[] = $match;
53
-
54
-			if ($max_items and count($collection) === $max_items) {
55
-				break;
56
-			}
57
-
58
-			$pos = $match['pos'] + $match['length'];
59
-		}
60
-
61
-		return $collection;
62
-	}
63
-
64
-	/**
65
-	 * Sanitizer une collection d'occurences
66
-	 *
67
-	 * @param array $collection
68
-	 * @param string $sanitize_callback
69
-	 * @return array
70
-	 */
71
-	protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
72
-		foreach ($collection as &$c) {
73
-			$c['raw'] = $sanitize_callback($c['raw']);
74
-		}
75
-
76
-		return $collection;
77
-	}
78
-
79
-	/**
80
-	 * @param string $texte
81
-	 * @param array $options
82
-	 * @return array
83
-	 */
84
-	public function collecter(string $texte, array $options = []): array {
85
-		$collection = [];
86
-		return $collection;
87
-	}
88
-
89
-	public function detecter($texte): bool {
90
-		if (!empty($this->markId) and strpos($texte, $this->markId) !== false) {
91
-			return true;
92
-		}
93
-		return !empty($this->collecter($texte, ['detecter_presence' => true]));
94
-	}
95
-
96
-	/**
97
-	 * Echapper les occurences de la collecte par un texte neutre du point de vue HTML
98
-	 *
99
-	 * @see retablir()
100
-	 * @param string $texte
101
-	 * @param array $options
102
-	 *   string $sanitize_callback
103
-	 * @return array
104
-	 *   texte, marqueur utilise pour echapper les modeles
105
-	 */
106
-	public function echapper(string $texte, array $options = []): string {
107
-		if (!function_exists('creer_uniqid')) {
108
-			include_spip('inc/acces');
109
-		}
110
-
111
-		$collection = $this->collecter($texte, $options);
112
-		if (!empty($options['sanitize_callback']) and is_callable($options['sanitize_callback'])) {
113
-			$collection = $this->sanitizer_collection($collection, $options['sanitize_callback']);
114
-		}
115
-
116
-		if (!empty($collection)) {
117
-			if (empty($this->markId)) {
118
-				// generer un marqueur qui n'existe pas dans le texte
119
-				do {
120
-					$this->markId = substr(md5(uniqid(static::class, 1)), 0, 7);
121
-					$this->markId = "@|".static::$markPrefix . $this->markId . "|";
122
-				} while (strpos($texte, $this->markId) !== false);
123
-			}
124
-
125
-			$offset_pos = 0;
126
-			foreach ($collection as $c) {
127
-				$rempl = $this->markId . base64_encode($c['raw']) . '|@';
128
-				$texte = substr_replace($texte, $rempl, $c['pos'] + $offset_pos, $c['length']);
129
-				$offset_pos += strlen($rempl) - $c['length'];
130
-			}
131
-		}
132
-
133
-		return $texte;
134
-	}
135
-
136
-
137
-	/**
138
-	 * Retablir les occurences échappées précédemment
139
-	 *
140
-	 * @see echapper()
141
-	 * @param string $texte
142
-	 * @return string
143
-	 */
144
-	function retablir(string $texte): string {
145
-
146
-		if (!empty($this->markId)) {
147
-			$lm = strlen($this->markId);
148
-			$pos = 0;
149
-			while (
150
-				($p = strpos($texte, $this->markId, $pos)) !== false
151
-				and $end = strpos($texte, '|@', $p + $lm)
152
-			) {
153
-				$base64 = substr($texte, $p + $lm, $end - ($p + $lm));
154
-				if ($c = base64_decode($base64, true)) {
155
-					$texte = substr_replace($texte, $c, $p, $end + 2 - $p);
156
-					$pos = $p + strlen($c);
157
-				}
158
-				else {
159
-					$pos = $end;
160
-				}
161
-			}
162
-		}
163
-
164
-		return $texte;
165
-	}
17
+    protected static string $markPrefix = 'COLLECT';
18
+    protected string $markId;
19
+
20
+    /**
21
+     * Collecteur générique des occurences d'une preg dans un texte avec leurs positions et longueur
22
+     * @param string $texte
23
+     *   texte à analyser pour la collecte
24
+     * @param string $if_chars
25
+     *   caractere(s) à tester avant de tenter la preg
26
+     * @param string $start_with
27
+     *   caractere(s) par lesquels commencent l'expression recherchée (permet de démarrer la preg à la prochaine occurence de cette chaine)
28
+     * @param string $preg
29
+     *   preg utilisée pour la collecte
30
+     * @param int $max_items
31
+     *   pour limiter le nombre de preg collectée (pour la detection simple de présence par exemple)
32
+     * @return array
33
+     */
34
+    protected static function collecteur(string $texte, string $if_chars, string $start_with, string $preg, int $max_items = 0): array {
35
+
36
+        $collection = [];
37
+        $pos = 0;
38
+        while (
39
+            (!$if_chars || strpos($texte, $if_chars, $pos) !== false)
40
+            and ($next = ($start_with ? strpos($texte, $start_with, $pos) : $pos)) !== false
41
+            and preg_match($preg, $texte, $r, PREG_OFFSET_CAPTURE, $next)) {
42
+
43
+            $found_pos = $r[0][1];
44
+            $found_length = strlen($r[0][0]);
45
+            $match = [
46
+                'raw' => $r[0][0],
47
+                'match' => array_column($r, 0),
48
+                'pos' => $found_pos,
49
+                'length' => $found_length
50
+            ];
51
+
52
+            $collection[] = $match;
53
+
54
+            if ($max_items and count($collection) === $max_items) {
55
+                break;
56
+            }
57
+
58
+            $pos = $match['pos'] + $match['length'];
59
+        }
60
+
61
+        return $collection;
62
+    }
63
+
64
+    /**
65
+     * Sanitizer une collection d'occurences
66
+     *
67
+     * @param array $collection
68
+     * @param string $sanitize_callback
69
+     * @return array
70
+     */
71
+    protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
72
+        foreach ($collection as &$c) {
73
+            $c['raw'] = $sanitize_callback($c['raw']);
74
+        }
75
+
76
+        return $collection;
77
+    }
78
+
79
+    /**
80
+     * @param string $texte
81
+     * @param array $options
82
+     * @return array
83
+     */
84
+    public function collecter(string $texte, array $options = []): array {
85
+        $collection = [];
86
+        return $collection;
87
+    }
88
+
89
+    public function detecter($texte): bool {
90
+        if (!empty($this->markId) and strpos($texte, $this->markId) !== false) {
91
+            return true;
92
+        }
93
+        return !empty($this->collecter($texte, ['detecter_presence' => true]));
94
+    }
95
+
96
+    /**
97
+     * Echapper les occurences de la collecte par un texte neutre du point de vue HTML
98
+     *
99
+     * @see retablir()
100
+     * @param string $texte
101
+     * @param array $options
102
+     *   string $sanitize_callback
103
+     * @return array
104
+     *   texte, marqueur utilise pour echapper les modeles
105
+     */
106
+    public function echapper(string $texte, array $options = []): string {
107
+        if (!function_exists('creer_uniqid')) {
108
+            include_spip('inc/acces');
109
+        }
110
+
111
+        $collection = $this->collecter($texte, $options);
112
+        if (!empty($options['sanitize_callback']) and is_callable($options['sanitize_callback'])) {
113
+            $collection = $this->sanitizer_collection($collection, $options['sanitize_callback']);
114
+        }
115
+
116
+        if (!empty($collection)) {
117
+            if (empty($this->markId)) {
118
+                // generer un marqueur qui n'existe pas dans le texte
119
+                do {
120
+                    $this->markId = substr(md5(uniqid(static::class, 1)), 0, 7);
121
+                    $this->markId = "@|".static::$markPrefix . $this->markId . "|";
122
+                } while (strpos($texte, $this->markId) !== false);
123
+            }
124
+
125
+            $offset_pos = 0;
126
+            foreach ($collection as $c) {
127
+                $rempl = $this->markId . base64_encode($c['raw']) . '|@';
128
+                $texte = substr_replace($texte, $rempl, $c['pos'] + $offset_pos, $c['length']);
129
+                $offset_pos += strlen($rempl) - $c['length'];
130
+            }
131
+        }
132
+
133
+        return $texte;
134
+    }
135
+
136
+
137
+    /**
138
+     * Retablir les occurences échappées précédemment
139
+     *
140
+     * @see echapper()
141
+     * @param string $texte
142
+     * @return string
143
+     */
144
+    function retablir(string $texte): string {
145
+
146
+        if (!empty($this->markId)) {
147
+            $lm = strlen($this->markId);
148
+            $pos = 0;
149
+            while (
150
+                ($p = strpos($texte, $this->markId, $pos)) !== false
151
+                and $end = strpos($texte, '|@', $p + $lm)
152
+            ) {
153
+                $base64 = substr($texte, $p + $lm, $end - ($p + $lm));
154
+                if ($c = base64_decode($base64, true)) {
155
+                    $texte = substr_replace($texte, $c, $p, $end + 2 - $p);
156
+                    $pos = $p + strlen($c);
157
+                }
158
+                else {
159
+                    $pos = $end;
160
+                }
161
+            }
162
+        }
163
+
164
+        return $texte;
165
+    }
166 166
 
167 167
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -118,13 +118,13 @@
 block discarded – undo
118 118
 				// generer un marqueur qui n'existe pas dans le texte
119 119
 				do {
120 120
 					$this->markId = substr(md5(uniqid(static::class, 1)), 0, 7);
121
-					$this->markId = "@|".static::$markPrefix . $this->markId . "|";
121
+					$this->markId = "@|".static::$markPrefix.$this->markId."|";
122 122
 				} while (strpos($texte, $this->markId) !== false);
123 123
 			}
124 124
 
125 125
 			$offset_pos = 0;
126 126
 			foreach ($collection as $c) {
127
-				$rempl = $this->markId . base64_encode($c['raw']) . '|@';
127
+				$rempl = $this->markId.base64_encode($c['raw']).'|@';
128 128
 				$texte = substr_replace($texte, $rempl, $c['pos'] + $offset_pos, $c['length']);
129 129
 				$offset_pos += strlen($rempl) - $c['length'];
130 130
 			}
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -154,8 +154,7 @@
 block discarded – undo
154 154
 				if ($c = base64_decode($base64, true)) {
155 155
 					$texte = substr_replace($texte, $c, $p, $end + 2 - $p);
156 156
 					$pos = $p + strlen($c);
157
-				}
158
-				else {
157
+				} else {
159 158
 					$pos = $end;
160 159
 				}
161 160
 			}
Please login to merge, or discard this patch.
ecrire/src/Texte/Collecteur/Idiomes.php 2 patches
Indentation   +110 added lines, -110 removed lines patch added patch discarded remove patch
@@ -23,115 +23,115 @@
 block discarded – undo
23 23
  */
24 24
 class Idiomes extends AbstractCollecteur {
25 25
 
26
-	protected static string $markPrefix = 'IDIOME';
27
-
28
-	/**
29
-	 * La preg pour découper et collecter les modèles
30
-	 * @var string
31
-	 */
32
-	protected string $preg_idiome;
33
-
34
-	public function __construct(?string $preg = null) {
35
-
36
-		$this->preg_idiome = ($preg ?: '@<:(?:([a-z0-9_]+):)?([a-z0-9_]+):>@isS');
37
-	}
38
-
39
-	/**
40
-	 * Sanitizer une collection d'occurences d'idiomes : on ne fait rien
41
-	 *
42
-	 * @param array $collection
43
-	 * @param string $sanitize_callback
44
-	 * @return array
45
-	 */
46
-	protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
47
-
48
-		return $collection;
49
-	}
50
-
51
-
52
-	/**
53
-	 * @param string $texte
54
-	 * @param array $options
55
-	 *   bool $collecter_liens
56
-	 * @return array
57
-	 */
58
-	public function collecter(string $texte, array $options = []): array {
59
-		if (!$texte) {
60
-			return [];
61
-		}
62
-
63
-		// collecter les matchs de la preg
64
-		$idiomes = $this->collecteur($texte, '', '<:', $this->preg_idiome, empty($options['detecter_presence']) ? 0 : 1);
65
-
66
-		// si on veut seulement detecter la présence, on peut retourner tel quel
67
-		if (empty($options['detecter_presence'])) {
68
-
69
-			$pos_prev = 0;
70
-			foreach ($idiomes as $k => &$idiome) {
71
-
72
-				$idiome['module'] = $idiome['match'][1];
73
-				$idiome['chaine'] = $idiome['match'][2];
74
-			}
75
-		}
76
-
77
-		return $idiomes;
78
-	}
79
-
80
-	/**
81
-	 * Traiter les idiomes d'un texte
82
-	 *
83
-	 * @uses inc_traduire_dist()
84
-	 * @uses code_echappement()
85
-	 * @uses echappe_retour()
86
-	 *
87
-	 * @param string $texte
88
-	 * @param array $options
89
-	 *   ?string $lang
90
-	 *   ?bool echappe_span
91
-	 * @return string
92
-	 */
93
-	public function traiter(string $texte, array $options) {
94
-		static $traduire;
95
-		if ($texte) {
96
-
97
-			$idiomes = $this->collecter($texte);
98
-			if (!empty($idiomes)) {
99
-				$lang = $options['lang'] ?? $GLOBALS['spip_lang'];
100
-				$echappe_span = $options['echappe_span'] ?? false;
101
-
102
-				if (is_null($traduire)) {
103
-					$traduire = charger_fonction('traduire', 'inc');
104
-					include_spip('inc/lang');
105
-				}
106
-
107
-				$offset_pos = 0;
108
-				foreach ($idiomes as $idiome) {
109
-
110
-					$cle = ($idiome['module'] ? $idiome['module'] . ':' : '') . $idiome['chaine'];
111
-					$desc = $traduire($cle, $lang, true);
112
-					$l = $desc->langue;
113
-
114
-					// si pas de traduction, on laissera l'écriture de l'idiome entier dans le texte.
115
-					if (strlen($desc->texte ?? '')) {
116
-						$trad = code_echappement($desc->texte, 'idiome', false);
117
-						if ($l !== $lang) {
118
-							$trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
119
-						}
120
-						if (lang_dir($l) !== lang_dir($lang)) {
121
-							$trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
122
-						}
123
-						if (!$echappe_span) {
124
-							$trad = echappe_retour($trad, 'idiome');
125
-						}
126
-						$texte = substr_replace($texte, $trad, $idiome['pos'] + $offset_pos, $idiome['length']);
127
-						$offset_pos += strlen($trad) - $idiome['length'];
128
-					}
129
-
130
-				}
131
-			}
132
-		}
133
-
134
-		return $texte;
135
-	}
26
+    protected static string $markPrefix = 'IDIOME';
27
+
28
+    /**
29
+     * La preg pour découper et collecter les modèles
30
+     * @var string
31
+     */
32
+    protected string $preg_idiome;
33
+
34
+    public function __construct(?string $preg = null) {
35
+
36
+        $this->preg_idiome = ($preg ?: '@<:(?:([a-z0-9_]+):)?([a-z0-9_]+):>@isS');
37
+    }
38
+
39
+    /**
40
+     * Sanitizer une collection d'occurences d'idiomes : on ne fait rien
41
+     *
42
+     * @param array $collection
43
+     * @param string $sanitize_callback
44
+     * @return array
45
+     */
46
+    protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
47
+
48
+        return $collection;
49
+    }
50
+
51
+
52
+    /**
53
+     * @param string $texte
54
+     * @param array $options
55
+     *   bool $collecter_liens
56
+     * @return array
57
+     */
58
+    public function collecter(string $texte, array $options = []): array {
59
+        if (!$texte) {
60
+            return [];
61
+        }
62
+
63
+        // collecter les matchs de la preg
64
+        $idiomes = $this->collecteur($texte, '', '<:', $this->preg_idiome, empty($options['detecter_presence']) ? 0 : 1);
65
+
66
+        // si on veut seulement detecter la présence, on peut retourner tel quel
67
+        if (empty($options['detecter_presence'])) {
68
+
69
+            $pos_prev = 0;
70
+            foreach ($idiomes as $k => &$idiome) {
71
+
72
+                $idiome['module'] = $idiome['match'][1];
73
+                $idiome['chaine'] = $idiome['match'][2];
74
+            }
75
+        }
76
+
77
+        return $idiomes;
78
+    }
79
+
80
+    /**
81
+     * Traiter les idiomes d'un texte
82
+     *
83
+     * @uses inc_traduire_dist()
84
+     * @uses code_echappement()
85
+     * @uses echappe_retour()
86
+     *
87
+     * @param string $texte
88
+     * @param array $options
89
+     *   ?string $lang
90
+     *   ?bool echappe_span
91
+     * @return string
92
+     */
93
+    public function traiter(string $texte, array $options) {
94
+        static $traduire;
95
+        if ($texte) {
96
+
97
+            $idiomes = $this->collecter($texte);
98
+            if (!empty($idiomes)) {
99
+                $lang = $options['lang'] ?? $GLOBALS['spip_lang'];
100
+                $echappe_span = $options['echappe_span'] ?? false;
101
+
102
+                if (is_null($traduire)) {
103
+                    $traduire = charger_fonction('traduire', 'inc');
104
+                    include_spip('inc/lang');
105
+                }
106
+
107
+                $offset_pos = 0;
108
+                foreach ($idiomes as $idiome) {
109
+
110
+                    $cle = ($idiome['module'] ? $idiome['module'] . ':' : '') . $idiome['chaine'];
111
+                    $desc = $traduire($cle, $lang, true);
112
+                    $l = $desc->langue;
113
+
114
+                    // si pas de traduction, on laissera l'écriture de l'idiome entier dans le texte.
115
+                    if (strlen($desc->texte ?? '')) {
116
+                        $trad = code_echappement($desc->texte, 'idiome', false);
117
+                        if ($l !== $lang) {
118
+                            $trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
119
+                        }
120
+                        if (lang_dir($l) !== lang_dir($lang)) {
121
+                            $trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
122
+                        }
123
+                        if (!$echappe_span) {
124
+                            $trad = echappe_retour($trad, 'idiome');
125
+                        }
126
+                        $texte = substr_replace($texte, $trad, $idiome['pos'] + $offset_pos, $idiome['length']);
127
+                        $offset_pos += strlen($trad) - $idiome['length'];
128
+                    }
129
+
130
+                }
131
+            }
132
+        }
133
+
134
+        return $texte;
135
+    }
136 136
 
137 137
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -107,7 +107,7 @@
 block discarded – undo
107 107
 				$offset_pos = 0;
108 108
 				foreach ($idiomes as $idiome) {
109 109
 
110
-					$cle = ($idiome['module'] ? $idiome['module'] . ':' : '') . $idiome['chaine'];
110
+					$cle = ($idiome['module'] ? $idiome['module'].':' : '').$idiome['chaine'];
111 111
 					$desc = $traduire($cle, $lang, true);
112 112
 					$l = $desc->langue;
113 113
 
Please login to merge, or discard this patch.
ecrire/src/Texte/Collecteur/Modeles.php 2 patches
Indentation   +197 added lines, -197 removed lines patch added patch discarded remove patch
@@ -22,202 +22,202 @@
 block discarded – undo
22 22
  */
23 23
 class Modeles extends AbstractCollecteur {
24 24
 
25
-	protected static string $markPrefix = 'MODELE';
26
-
27
-	/**
28
-	 * La preg pour découper et collecter les modèles
29
-	 * @var string
30
-	 */
31
-	protected string $preg_modele;
32
-
33
-	public function __construct(?string $preg = null) {
34
-
35
-		$this->preg_modele = ($preg ?:
36
-			'@<([a-z_-]{3,})' # <modele
37
-			. '\s*([0-9]*)\s*' # id
38
-			. '([|](?:<[^<>]*>|[^>])*?)?' # |arguments (y compris des tags <...>)
39
-			. '\s*/?' . '>@isS' # fin du modele >
40
-		);
41
-	}
42
-
43
-	/**
44
-	 * Sanitizer une collection d'occurences de modèle : on ne fait rien
45
-	 *
46
-	 * @param array $collection
47
-	 * @param string $sanitize_callback
48
-	 * @return array
49
-	 */
50
-	protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
51
-
52
-		return $collection;
53
-	}
54
-
55
-	/**
56
-	 * @param string $texte
57
-	 * @param array $options
58
-	 *   bool $collecter_liens
59
-	 * @return array
60
-	 */
61
-	public function collecter(string $texte, array $options = []): array {
62
-		if (!$texte) {
63
-			return [];
64
-		}
65
-
66
-		// collecter les matchs de la preg
67
-		$modeles = $this->collecteur($texte, '', '<', $this->preg_modele);
68
-
69
-		$pos_prev = 0;
70
-		foreach ($modeles as $k => &$modele) {
71
-			$pos = $modele['pos'];
72
-			$modele['type'] = $modele['match'][1];
73
-			$modele['id'] = $modele['match'][2] ?? '';
74
-			$modele['params'] = $modele['match'][3] ?? '';
75
-
76
-			$longueur = $modele['length'];
77
-			$end = $pos + $longueur;
78
-
79
-			// il faut avoir un id ou des params commençant par un | sinon c'est une simple balise html
80
-			if (empty($modele['id']) and empty($modele['params'])) {
81
-				unset($modeles[$k]);
82
-				continue;
83
-			}
84
-
85
-			// si on veut seulement detecter la présence, on peut retourner tel quel
86
-			if (!empty($options['detecter_presence'])) {
87
-				break;
88
-			}
89
-
90
-			$modele['lien'] = false;
91
-			if (!empty($options['collecter_liens'])
92
-				and $pos_fermeture_lien = stripos($texte, '</a>', $end)
93
-				and !strlen(trim(substr($texte, $end, $pos_fermeture_lien - $end)))) {
94
-
95
-				$pos_lien_ouvrant = stripos($texte, '<a', $pos_prev);
96
-				if ($pos_lien_ouvrant !== false
97
-					and $pos_lien_ouvrant < $pos
98
-					and preg_match('/<a\s[^<>]*>\s*$/i', substr($texte, $pos_prev, $pos - $pos_prev), $r)
99
-				) {
100
-					$modele['lien'] = [
101
-						'href' => extraire_attribut($r[0], 'href'),
102
-						'class' => extraire_attribut($r[0], 'class'),
103
-						'mime' => extraire_attribut($r[0], 'type'),
104
-						'title' => extraire_attribut($r[0], 'title'),
105
-						'hreflang' => extraire_attribut($r[0], 'hreflang')
106
-					];
107
-					$n = strlen($r[0]);
108
-					$pos -= $n;
109
-					$longueur = $pos_fermeture_lien - $pos + 4;
110
-					$end = $pos + $longueur;
111
-				}
112
-			}
113
-
114
-
115
-			$modele['pos'] = $pos;
116
-			$modele['length'] = $longueur;
117
-			$pos_prev = $end;
118
-		}
119
-
120
-		return $modeles;
121
-	}
122
-
123
-	/**
124
-	 * Traiter les modeles d'un texte
125
-	 * @param string $texte
126
-	 * @param array $options
127
-	 *   bool|array $doublons
128
-	 *   string $echap
129
-	 *   ?Spip\Texte\CollecteurLiens $collecteurLiens
130
-	 *   ?array $env
131
-	 *   ?string $connect
132
-	 * @return string
133
-	 */
134
-	public function traiter(string $texte, array $options) {
135
-		if ($texte) {
136
-			$doublons = $options['doublons'] ?? false;
137
-			$echap = $options['echap'] ?? '';
138
-			$collecteurLiens = $options['collecteurLiens'] ?? null;
139
-			$env = $options['env'] ?? [];
140
-			$connect = $options['connect'] ?? '';
141
-
142
-			// preserver la compatibilite : true = recherche des documents
143
-			if ($doublons === true) {
144
-				$doublons = ['documents' => ['doc', 'emb', 'img']];
145
-			}
146
-
147
-			$modeles = $this->collecter($texte, ['collecter_liens' => true]);
148
-			if (!empty($modeles)) {
149
-				include_spip('public/assembler');
150
-				$wrap_embed_html = charger_fonction('wrap_embed_html', 'inc', true);
151
-
152
-				$offset_pos = 0;
153
-				foreach ($modeles as $m) {
154
-					// calculer le modele
155
-					# hack indexation
156
-					if ($doublons) {
157
-						$texte .= preg_replace(',[|][^|=]*,s', ' ', $m['params']);
158
-					} # version normale
159
-					else {
160
-						// si un tableau de liens a ete passe, reinjecter le contenu d'origine
161
-						// dans les parametres, plutot que les liens echappes
162
-						$params = $m['params'];
163
-						if (!is_null($collecteurLiens)) {
164
-							$params = $collecteurLiens->retablir($params);
165
-						}
166
-
167
-						$modele = inclure_modele($m['type'], $m['id'], $params, $m['lien'], $connect ?? '', $env);
168
-
169
-						// en cas d'echec,
170
-						// si l'objet demande a une url,
171
-						// creer un petit encadre vers elle
172
-						if ($modele === false) {
173
-							$modele = $m['raw'];
174
-
175
-							if (!is_null($collecteurLiens)) {
176
-								$modele = $collecteurLiens->retablir($modele);
177
-							}
178
-
179
-							$contexte = array_merge($env, ['id' => $m['id'], 'type' => $m['type'], 'modele' => $modele]);
180
-
181
-							if (!empty($m['lien'])) {
182
-								# un eventuel guillemet (") sera reechappe par #ENV
183
-								$contexte['lien'] = str_replace('&quot;', '"', $m['lien']['href']);
184
-								$contexte['lien_class'] = $m['lien']['class'];
185
-								$contexte['lien_mime'] = $m['lien']['mime'];
186
-								$contexte['lien_title'] = $m['lien']['title'];
187
-								$contexte['lien_hreflang'] = $m['lien']['hreflang'];
188
-							}
189
-
190
-							$modele = recuperer_fond('modeles/dist', $contexte, [], $connect ?? '');
191
-						}
192
-
193
-						// le remplacer dans le texte
194
-						if ($modele !== false) {
195
-							$modele = protege_js_modeles($modele);
196
-
197
-							if ($wrap_embed_html) {
198
-								$modele = $wrap_embed_html($m['raw'], $modele);
199
-							}
200
-
201
-							$rempl = code_echappement($modele, $echap);
202
-							$texte = substr_replace($texte, $rempl, $m['pos'] + $offset_pos, $m['length']);
203
-							$offset_pos += strlen($rempl) - $m['length'];
204
-						}
205
-					}
206
-
207
-					// hack pour tout l'espace prive
208
-					if ((test_espace_prive() or ($doublons)) and !empty($m['id'])) {
209
-						$type = strtolower($m['type']);
210
-						foreach ($doublons ?: ['documents' => ['doc', 'emb', 'img']] as $quoi => $type_modeles) {
211
-							if (in_array($type, $type_modeles)) {
212
-								$GLOBALS["doublons_{$quoi}_inclus"][] = $m['id'];
213
-							}
214
-						}
215
-					}
216
-				}
217
-			}
218
-		}
219
-
220
-		return $texte;
221
-	}
25
+    protected static string $markPrefix = 'MODELE';
26
+
27
+    /**
28
+     * La preg pour découper et collecter les modèles
29
+     * @var string
30
+     */
31
+    protected string $preg_modele;
32
+
33
+    public function __construct(?string $preg = null) {
34
+
35
+        $this->preg_modele = ($preg ?:
36
+            '@<([a-z_-]{3,})' # <modele
37
+            . '\s*([0-9]*)\s*' # id
38
+            . '([|](?:<[^<>]*>|[^>])*?)?' # |arguments (y compris des tags <...>)
39
+            . '\s*/?' . '>@isS' # fin du modele >
40
+        );
41
+    }
42
+
43
+    /**
44
+     * Sanitizer une collection d'occurences de modèle : on ne fait rien
45
+     *
46
+     * @param array $collection
47
+     * @param string $sanitize_callback
48
+     * @return array
49
+     */
50
+    protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
51
+
52
+        return $collection;
53
+    }
54
+
55
+    /**
56
+     * @param string $texte
57
+     * @param array $options
58
+     *   bool $collecter_liens
59
+     * @return array
60
+     */
61
+    public function collecter(string $texte, array $options = []): array {
62
+        if (!$texte) {
63
+            return [];
64
+        }
65
+
66
+        // collecter les matchs de la preg
67
+        $modeles = $this->collecteur($texte, '', '<', $this->preg_modele);
68
+
69
+        $pos_prev = 0;
70
+        foreach ($modeles as $k => &$modele) {
71
+            $pos = $modele['pos'];
72
+            $modele['type'] = $modele['match'][1];
73
+            $modele['id'] = $modele['match'][2] ?? '';
74
+            $modele['params'] = $modele['match'][3] ?? '';
75
+
76
+            $longueur = $modele['length'];
77
+            $end = $pos + $longueur;
78
+
79
+            // il faut avoir un id ou des params commençant par un | sinon c'est une simple balise html
80
+            if (empty($modele['id']) and empty($modele['params'])) {
81
+                unset($modeles[$k]);
82
+                continue;
83
+            }
84
+
85
+            // si on veut seulement detecter la présence, on peut retourner tel quel
86
+            if (!empty($options['detecter_presence'])) {
87
+                break;
88
+            }
89
+
90
+            $modele['lien'] = false;
91
+            if (!empty($options['collecter_liens'])
92
+                and $pos_fermeture_lien = stripos($texte, '</a>', $end)
93
+                and !strlen(trim(substr($texte, $end, $pos_fermeture_lien - $end)))) {
94
+
95
+                $pos_lien_ouvrant = stripos($texte, '<a', $pos_prev);
96
+                if ($pos_lien_ouvrant !== false
97
+                    and $pos_lien_ouvrant < $pos
98
+                    and preg_match('/<a\s[^<>]*>\s*$/i', substr($texte, $pos_prev, $pos - $pos_prev), $r)
99
+                ) {
100
+                    $modele['lien'] = [
101
+                        'href' => extraire_attribut($r[0], 'href'),
102
+                        'class' => extraire_attribut($r[0], 'class'),
103
+                        'mime' => extraire_attribut($r[0], 'type'),
104
+                        'title' => extraire_attribut($r[0], 'title'),
105
+                        'hreflang' => extraire_attribut($r[0], 'hreflang')
106
+                    ];
107
+                    $n = strlen($r[0]);
108
+                    $pos -= $n;
109
+                    $longueur = $pos_fermeture_lien - $pos + 4;
110
+                    $end = $pos + $longueur;
111
+                }
112
+            }
113
+
114
+
115
+            $modele['pos'] = $pos;
116
+            $modele['length'] = $longueur;
117
+            $pos_prev = $end;
118
+        }
119
+
120
+        return $modeles;
121
+    }
122
+
123
+    /**
124
+     * Traiter les modeles d'un texte
125
+     * @param string $texte
126
+     * @param array $options
127
+     *   bool|array $doublons
128
+     *   string $echap
129
+     *   ?Spip\Texte\CollecteurLiens $collecteurLiens
130
+     *   ?array $env
131
+     *   ?string $connect
132
+     * @return string
133
+     */
134
+    public function traiter(string $texte, array $options) {
135
+        if ($texte) {
136
+            $doublons = $options['doublons'] ?? false;
137
+            $echap = $options['echap'] ?? '';
138
+            $collecteurLiens = $options['collecteurLiens'] ?? null;
139
+            $env = $options['env'] ?? [];
140
+            $connect = $options['connect'] ?? '';
141
+
142
+            // preserver la compatibilite : true = recherche des documents
143
+            if ($doublons === true) {
144
+                $doublons = ['documents' => ['doc', 'emb', 'img']];
145
+            }
146
+
147
+            $modeles = $this->collecter($texte, ['collecter_liens' => true]);
148
+            if (!empty($modeles)) {
149
+                include_spip('public/assembler');
150
+                $wrap_embed_html = charger_fonction('wrap_embed_html', 'inc', true);
151
+
152
+                $offset_pos = 0;
153
+                foreach ($modeles as $m) {
154
+                    // calculer le modele
155
+                    # hack indexation
156
+                    if ($doublons) {
157
+                        $texte .= preg_replace(',[|][^|=]*,s', ' ', $m['params']);
158
+                    } # version normale
159
+                    else {
160
+                        // si un tableau de liens a ete passe, reinjecter le contenu d'origine
161
+                        // dans les parametres, plutot que les liens echappes
162
+                        $params = $m['params'];
163
+                        if (!is_null($collecteurLiens)) {
164
+                            $params = $collecteurLiens->retablir($params);
165
+                        }
166
+
167
+                        $modele = inclure_modele($m['type'], $m['id'], $params, $m['lien'], $connect ?? '', $env);
168
+
169
+                        // en cas d'echec,
170
+                        // si l'objet demande a une url,
171
+                        // creer un petit encadre vers elle
172
+                        if ($modele === false) {
173
+                            $modele = $m['raw'];
174
+
175
+                            if (!is_null($collecteurLiens)) {
176
+                                $modele = $collecteurLiens->retablir($modele);
177
+                            }
178
+
179
+                            $contexte = array_merge($env, ['id' => $m['id'], 'type' => $m['type'], 'modele' => $modele]);
180
+
181
+                            if (!empty($m['lien'])) {
182
+                                # un eventuel guillemet (") sera reechappe par #ENV
183
+                                $contexte['lien'] = str_replace('&quot;', '"', $m['lien']['href']);
184
+                                $contexte['lien_class'] = $m['lien']['class'];
185
+                                $contexte['lien_mime'] = $m['lien']['mime'];
186
+                                $contexte['lien_title'] = $m['lien']['title'];
187
+                                $contexte['lien_hreflang'] = $m['lien']['hreflang'];
188
+                            }
189
+
190
+                            $modele = recuperer_fond('modeles/dist', $contexte, [], $connect ?? '');
191
+                        }
192
+
193
+                        // le remplacer dans le texte
194
+                        if ($modele !== false) {
195
+                            $modele = protege_js_modeles($modele);
196
+
197
+                            if ($wrap_embed_html) {
198
+                                $modele = $wrap_embed_html($m['raw'], $modele);
199
+                            }
200
+
201
+                            $rempl = code_echappement($modele, $echap);
202
+                            $texte = substr_replace($texte, $rempl, $m['pos'] + $offset_pos, $m['length']);
203
+                            $offset_pos += strlen($rempl) - $m['length'];
204
+                        }
205
+                    }
206
+
207
+                    // hack pour tout l'espace prive
208
+                    if ((test_espace_prive() or ($doublons)) and !empty($m['id'])) {
209
+                        $type = strtolower($m['type']);
210
+                        foreach ($doublons ?: ['documents' => ['doc', 'emb', 'img']] as $quoi => $type_modeles) {
211
+                            if (in_array($type, $type_modeles)) {
212
+                                $GLOBALS["doublons_{$quoi}_inclus"][] = $m['id'];
213
+                            }
214
+                        }
215
+                    }
216
+                }
217
+            }
218
+        }
219
+
220
+        return $texte;
221
+    }
222 222
 
223 223
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -3 removed lines patch added patch discarded remove patch
@@ -32,11 +32,10 @@
 block discarded – undo
32 32
 
33 33
 	public function __construct(?string $preg = null) {
34 34
 
35
-		$this->preg_modele = ($preg ?:
36
-			'@<([a-z_-]{3,})' # <modele
35
+		$this->preg_modele = ($preg ?: '@<([a-z_-]{3,})' # <modele
37 36
 			. '\s*([0-9]*)\s*' # id
38 37
 			. '([|](?:<[^<>]*>|[^>])*?)?' # |arguments (y compris des tags <...>)
39
-			. '\s*/?' . '>@isS' # fin du modele >
38
+			. '\s*/?'.'>@isS' # fin du modele >
40 39
 		);
41 40
 	}
42 41
 
Please login to merge, or discard this patch.
ecrire/src/Texte/Collecteur/Liens.php 1 patch
Indentation   +98 added lines, -98 removed lines patch added patch discarded remove patch
@@ -17,103 +17,103 @@
 block discarded – undo
17 17
  */
18 18
 class Liens extends AbstractCollecteur {
19 19
 
20
-	protected static string $markPrefix = 'LIEN';
21
-
22
-	/**
23
-	 * La preg pour découper et collecter les modèles
24
-	 * @var string
25
-	 */
26
-	protected string $preg_lien;
27
-
28
-	public function __construct(?string $preg = null) {
29
-
30
-		// Regexp des raccourcis, aussi utilisee pour la fusion de sauvegarde Spip
31
-		// Laisser passer des paires de crochets pour la balise multi
32
-		// mais refuser plus d'imbrications ou de mauvaises imbrications
33
-		// sinon les crochets ne peuvent plus servir qu'a ce type de raccourci
34
-		$this->preg_lien = ($preg ?: '/\[([^][]*?([[][^]>-]*[]][^][]*)*)->(>?)([^]]*)\]/msS');
35
-	}
36
-
37
-
38
-	/**
39
-	 * Sanitizer une collection d'occurences de liens : il faut sanitizer le href et le texte uniquement
40
-	 *
41
-	 * @param array $collection
42
-	 * @param string $sanitize_callback
43
-	 * @return array
44
-	 */
45
-	protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
46
-		foreach ($collection as &$lien) {
47
-			$t = $sanitize_callback($lien['texte']);
48
-			if ($t !== $lien['texte']) {
49
-				$lien['raw'] = str_replace($lien['texte'], $t, $lien['raw']);
50
-				$lien['texte'] = $t;
51
-			}
52
-			$href = $sanitize_callback($lien['href']);
53
-			if ($href !== $lien['href']) {
54
-				$lien['raw'] = str_replace($lien['href'], $href, $lien['raw']);
55
-				$lien['href'] = $href;
56
-			}
57
-		}
58
-
59
-		return $collection;
60
-	}
61
-
62
-	/**
63
-	 * @param string $texte
64
-	 * @param array $options
65
-	 *   bool $collecter_liens
66
-	 * @return array
67
-	 */
68
-	public function collecter(string $texte, array $options = []): array {
69
-		if (!$texte) {
70
-			return [];
71
-		}
72
-
73
-		$liens = [];
74
-		if (strpos($texte, '->') !== false) {
75
-
76
-			$desechappe_crochets = false;
77
-			// si il y a un crochet ouvrant échappé ou un crochet fermant échappé, les substituer pour les ignorer
78
-			if (strpos($texte, '\[') !== false or strpos($texte, '\]') !== false) {
79
-				$texte = str_replace(['\[', '\]'], ["\x1\x5", "\x1\x6"], $texte);
80
-				$desechappe_crochets = true;
81
-			}
82
-
83
-			// collecter les matchs de la preg
84
-			$liens = $this->collecteur($texte, '->', '[', $this->preg_lien, empty($options['detecter_presence']) ? 0 : 1);
85
-
86
-			// si on veut seulement detecter la présence, on peut retourner tel quel
87
-			if (empty($options['detecter_presence'])) {
88
-
89
-				foreach ($liens as $k => &$lien) {
90
-
91
-					$lien['href'] = end($lien['match']);
92
-					$lien['texte'] = $lien['match'][1];
93
-					$lien['ouvrant'] = $lien['match'][3] ?? '';
94
-
95
-					// la mise en lien automatique est passee par la a tort !
96
-					// corrigeons pour eviter d'avoir un <a...> dans un href...
97
-					if (strncmp($lien['href'], '<a', 2) == 0) {
98
-						$href = extraire_attribut($lien['href'], 'href');
99
-						// remplacons dans la source qui peut etre reinjectee dans les arguments
100
-						// d'un modele
101
-						$lien['raw'] = str_replace($lien['href'], $href, $lien['raw']);
102
-						// et prenons le href comme la vraie url a linker
103
-						$lien['href'] = $href;
104
-					}
105
-
106
-					if ($desechappe_crochets and strpos($lien['raw'], "\x1") !== false) {
107
-						$lien['raw'] = str_replace(["\x1\x5", "\x1\x6"], ['[', ']'], $lien['raw']);
108
-						$lien['texte'] = str_replace(["\x1\x5", "\x1\x6"], ['[', ']'], $lien['texte']);
109
-						$lien['href'] = str_replace(["\x1\x5", "\x1\x6"], ['[', ']'], $lien['href']);
110
-					}
111
-
112
-				}
113
-			}
114
-		}
115
-
116
-		return $liens;
117
-	}
20
+    protected static string $markPrefix = 'LIEN';
21
+
22
+    /**
23
+     * La preg pour découper et collecter les modèles
24
+     * @var string
25
+     */
26
+    protected string $preg_lien;
27
+
28
+    public function __construct(?string $preg = null) {
29
+
30
+        // Regexp des raccourcis, aussi utilisee pour la fusion de sauvegarde Spip
31
+        // Laisser passer des paires de crochets pour la balise multi
32
+        // mais refuser plus d'imbrications ou de mauvaises imbrications
33
+        // sinon les crochets ne peuvent plus servir qu'a ce type de raccourci
34
+        $this->preg_lien = ($preg ?: '/\[([^][]*?([[][^]>-]*[]][^][]*)*)->(>?)([^]]*)\]/msS');
35
+    }
36
+
37
+
38
+    /**
39
+     * Sanitizer une collection d'occurences de liens : il faut sanitizer le href et le texte uniquement
40
+     *
41
+     * @param array $collection
42
+     * @param string $sanitize_callback
43
+     * @return array
44
+     */
45
+    protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
46
+        foreach ($collection as &$lien) {
47
+            $t = $sanitize_callback($lien['texte']);
48
+            if ($t !== $lien['texte']) {
49
+                $lien['raw'] = str_replace($lien['texte'], $t, $lien['raw']);
50
+                $lien['texte'] = $t;
51
+            }
52
+            $href = $sanitize_callback($lien['href']);
53
+            if ($href !== $lien['href']) {
54
+                $lien['raw'] = str_replace($lien['href'], $href, $lien['raw']);
55
+                $lien['href'] = $href;
56
+            }
57
+        }
58
+
59
+        return $collection;
60
+    }
61
+
62
+    /**
63
+     * @param string $texte
64
+     * @param array $options
65
+     *   bool $collecter_liens
66
+     * @return array
67
+     */
68
+    public function collecter(string $texte, array $options = []): array {
69
+        if (!$texte) {
70
+            return [];
71
+        }
72
+
73
+        $liens = [];
74
+        if (strpos($texte, '->') !== false) {
75
+
76
+            $desechappe_crochets = false;
77
+            // si il y a un crochet ouvrant échappé ou un crochet fermant échappé, les substituer pour les ignorer
78
+            if (strpos($texte, '\[') !== false or strpos($texte, '\]') !== false) {
79
+                $texte = str_replace(['\[', '\]'], ["\x1\x5", "\x1\x6"], $texte);
80
+                $desechappe_crochets = true;
81
+            }
82
+
83
+            // collecter les matchs de la preg
84
+            $liens = $this->collecteur($texte, '->', '[', $this->preg_lien, empty($options['detecter_presence']) ? 0 : 1);
85
+
86
+            // si on veut seulement detecter la présence, on peut retourner tel quel
87
+            if (empty($options['detecter_presence'])) {
88
+
89
+                foreach ($liens as $k => &$lien) {
90
+
91
+                    $lien['href'] = end($lien['match']);
92
+                    $lien['texte'] = $lien['match'][1];
93
+                    $lien['ouvrant'] = $lien['match'][3] ?? '';
94
+
95
+                    // la mise en lien automatique est passee par la a tort !
96
+                    // corrigeons pour eviter d'avoir un <a...> dans un href...
97
+                    if (strncmp($lien['href'], '<a', 2) == 0) {
98
+                        $href = extraire_attribut($lien['href'], 'href');
99
+                        // remplacons dans la source qui peut etre reinjectee dans les arguments
100
+                        // d'un modele
101
+                        $lien['raw'] = str_replace($lien['href'], $href, $lien['raw']);
102
+                        // et prenons le href comme la vraie url a linker
103
+                        $lien['href'] = $href;
104
+                    }
105
+
106
+                    if ($desechappe_crochets and strpos($lien['raw'], "\x1") !== false) {
107
+                        $lien['raw'] = str_replace(["\x1\x5", "\x1\x6"], ['[', ']'], $lien['raw']);
108
+                        $lien['texte'] = str_replace(["\x1\x5", "\x1\x6"], ['[', ']'], $lien['texte']);
109
+                        $lien['href'] = str_replace(["\x1\x5", "\x1\x6"], ['[', ']'], $lien['href']);
110
+                    }
111
+
112
+                }
113
+            }
114
+        }
115
+
116
+        return $liens;
117
+    }
118 118
 
119 119
 }
Please login to merge, or discard this patch.
ecrire/src/Texte/Collecteur/Multis.php 2 patches
Indentation   +204 added lines, -204 removed lines patch added patch discarded remove patch
@@ -29,209 +29,209 @@
 block discarded – undo
29 29
  */
30 30
 class Multis extends AbstractCollecteur {
31 31
 
32
-	protected static string $markPrefix = 'MULTI';
33
-
34
-	/**
35
-	 * La preg pour découper et collecter les modèles
36
-	 * @var string
37
-	 */
38
-	protected string $preg_multi;
39
-
40
-	public function __construct(?string $preg = null) {
41
-
42
-		$this->preg_multi = ($preg ?: '@<multi>(.*?)</multi>@sS');
43
-	}
44
-
45
-	/**
46
-	 * Sanitizer une collection d'occurences de multi : on sanitize chaque texte de langue séparemment
47
-	 *
48
-	 * @param array $collection
49
-	 * @param string $sanitize_callback
50
-	 * @return array
51
-	 */
52
-	protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
53
-
54
-		foreach ($collection as &$multi) {
55
-			$changed = false;
56
-			foreach ($multi['trads'] as $lang => $trad) {
57
-				$t = $sanitize_callback($trad);
58
-				if ($t !== $trad) {
59
-					$changed = true;
60
-					$multi['trads'][$lang] = $t;
61
-				}
62
-			}
63
-			if ($changed) {
64
-				$texte = $this->agglomerer_trads($multi['trads']);
65
-				$multi['raw'] = str_replace($multi['texte'], $texte, $multi['raw']);
66
-				$multi['texte'] = $texte;
67
-			}
68
-		}
69
-		return $collection;
70
-	}
71
-
72
-
73
-	/**
74
-	 * Convertit le contenu d'une balise `<multi>` en un tableau
75
-	 *
76
-	 * Exemple de blocs.
77
-	 * - `texte par défaut [fr] en français [en] en anglais`
78
-	 * - `[fr] en français [en] en anglais`
79
-	 *
80
-	 * @param string $bloc
81
-	 *     Le contenu intérieur d'un bloc multi
82
-	 * @return array [code de langue => texte]
83
-	 *     Peut retourner un code de langue vide, lorsqu'un texte par défaut est indiqué.
84
-	 **/
85
-	protected function extraire_trads($bloc) {
86
-		$trads = [];
87
-
88
-		$langs = $this->collecteur($bloc, ']', '[', '@[\[]([a-z]{2,3}(_[a-z]{2,3})?(_[a-z]{2,3})?)[\]]@siS');
89
-		$lang = '';
90
-		$pos_prev = 0;
91
-		foreach ($langs as $l) {
92
-			$pos = $l['pos'];
93
-			if ($lang or $pos > $pos_prev) {
94
-				$trads[$lang] = substr($bloc, $pos_prev, $pos - $pos_prev);
95
-			}
96
-			$lang = $l['match'][1];
97
-			$pos_prev = $pos + $l['length'];
98
-		}
99
-		$trads[$lang] = substr($bloc, $pos_prev);
100
-
101
-		return $trads;
102
-	}
103
-
104
-	/**
105
-	 * Recoller ensemble les trads pour reconstituer le texte dans la balise <multi>...</multi>
106
-	 * @param $trads
107
-	 * @return string
108
-	 */
109
-	protected function agglomerer_trads($trads) {
110
-		$texte = '';
111
-		foreach ($trads as $lang => $trad) {
112
-			if ($texte or $lang) {
113
-				$texte .= "[$lang]";
114
-			}
115
-			$texte .= $trad;
116
-		}
117
-		return $texte;
118
-	}
119
-
120
-	/**
121
-	 * @param string $texte
122
-	 * @param array $options
123
-	 *   bool $collecter_liens
124
-	 * @return array
125
-	 */
126
-	public function collecter(string $texte, array $options = []): array {
127
-		if (!$texte) {
128
-			return [];
129
-		}
130
-
131
-		// collecter les matchs de la preg
132
-		$multis = $this->collecteur($texte, '', '<multi', $this->preg_multi, empty($options['detecter_presence']) ? 0 : 1);
133
-
134
-		// si on veut seulement detecter la présence, on peut retourner tel quel
135
-		if (empty($options['detecter_presence'])) {
136
-
137
-			$pos_prev = 0;
138
-			foreach ($multis as $k => &$multi) {
139
-
140
-				$multi['texte'] = $multi['match'][1];
141
-				// extraire les trads du texte
142
-				$trads = $this->extraire_trads($multi['match'][1]);
143
-				$multi['trads'] = $trads;
144
-			}
145
-		}
146
-
147
-		return $multis;
148
-	}
149
-
150
-	/**
151
-	 * Traiter les multis d'un texte
152
-	 *
153
-	 * @uses approcher_langue()
154
-	 * @uses lang_typo()
155
-	 * @uses code_echappement()
156
-	 * @uses echappe_retour()
157
-	 *
158
-	 * @param string $texte
159
-	 * @param array $options
160
-	 *   ?string $lang
161
-	 *   ?string $lang_defaut
162
-	 *   ?bool echappe_span
163
-	 *   ?bool appliquer_typo
164
-	 * @return string
165
-	 */
166
-	public function traiter(string $texte, array $options) {
167
-		if ($texte) {
168
-
169
-			$multis = $this->collecter($texte);
170
-			if (!empty($multis)) {
171
-				$lang = $options['lang'] ?? $GLOBALS['spip_lang'];
172
-				$lang_defaut = $options['lang_defaut'] ?? _LANGUE_PAR_DEFAUT;
173
-				$echappe_span = $options['echappe_span'] ?? false;
174
-				$appliquer_typo = $options['appliquer_typo'] ?? true;
175
-
176
-				if (!function_exists('approcher_langue')) {
177
-					include_spip('inc/lang');
178
-				}
179
-				if (!function_exists('code_echappement')) {
180
-					include_spip('inc/texte_mini');
181
-				}
182
-
183
-				$offset_pos = 0;
184
-				foreach ($multis as $m) {
185
-
186
-					// chercher la version de la langue courante
187
-					$trads = $m['trads'];
188
-					if ($l = approcher_langue($trads, $lang)) {
189
-						$trad = $trads[$l];
190
-					} else {
191
-						if ($lang_defaut == 'aucune') {
192
-							$trad = '';
193
-						} else {
194
-							// langue absente, prendre le fr ou une langue précisée (meme comportement que inc/traduire.php)
195
-							// ou la premiere dispo
196
-							if (!$l = approcher_langue($trads, $options['lang_defaut'])) {
197
-								$l = array_values($trads);
198
-								$l = reset($l);
199
-							}
200
-
201
-							// mais typographier le texte selon les regles de celle-ci
202
-							// Attention aux blocs multi sur plusieurs lignes
203
-							if ($appliquer_typo) {
204
-								$trad = $trads[$l];
205
-								$typographie = charger_fonction(lang_typo($l), 'typographie');
206
-								$trad = $typographie($trad);
207
-
208
-								// Tester si on echappe en span ou en div
209
-								// il ne faut pas echapper en div si propre produit un seul paragraphe
210
-								include_spip('inc/texte');
211
-								$trad_propre = preg_replace(',(^<p[^>]*>|</p>$),Uims', '', propre($trad));
212
-								$mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $trad_propre) ? 'div' : 'span';
213
-								if ($mode === 'div') {
214
-									$trad = rtrim($trad) . "\n\n";
215
-								}
216
-								$trad = code_echappement($trad, 'multi', false, $mode);
217
-								$trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
218
-								if (lang_dir($l) !== lang_dir($lang)) {
219
-									$trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
220
-								}
221
-								if (!$echappe_span) {
222
-									$trad = echappe_retour($trad, 'multi');
223
-								}
224
-							}
225
-						}
226
-					}
227
-
228
-					$texte = substr_replace($texte, $trad, $m['pos'] + $offset_pos, $m['length']);
229
-					$offset_pos += strlen($trad) - $m['length'];
230
-				}
231
-			}
232
-		}
233
-
234
-		return $texte;
235
-	}
32
+    protected static string $markPrefix = 'MULTI';
33
+
34
+    /**
35
+     * La preg pour découper et collecter les modèles
36
+     * @var string
37
+     */
38
+    protected string $preg_multi;
39
+
40
+    public function __construct(?string $preg = null) {
41
+
42
+        $this->preg_multi = ($preg ?: '@<multi>(.*?)</multi>@sS');
43
+    }
44
+
45
+    /**
46
+     * Sanitizer une collection d'occurences de multi : on sanitize chaque texte de langue séparemment
47
+     *
48
+     * @param array $collection
49
+     * @param string $sanitize_callback
50
+     * @return array
51
+     */
52
+    protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
53
+
54
+        foreach ($collection as &$multi) {
55
+            $changed = false;
56
+            foreach ($multi['trads'] as $lang => $trad) {
57
+                $t = $sanitize_callback($trad);
58
+                if ($t !== $trad) {
59
+                    $changed = true;
60
+                    $multi['trads'][$lang] = $t;
61
+                }
62
+            }
63
+            if ($changed) {
64
+                $texte = $this->agglomerer_trads($multi['trads']);
65
+                $multi['raw'] = str_replace($multi['texte'], $texte, $multi['raw']);
66
+                $multi['texte'] = $texte;
67
+            }
68
+        }
69
+        return $collection;
70
+    }
71
+
72
+
73
+    /**
74
+     * Convertit le contenu d'une balise `<multi>` en un tableau
75
+     *
76
+     * Exemple de blocs.
77
+     * - `texte par défaut [fr] en français [en] en anglais`
78
+     * - `[fr] en français [en] en anglais`
79
+     *
80
+     * @param string $bloc
81
+     *     Le contenu intérieur d'un bloc multi
82
+     * @return array [code de langue => texte]
83
+     *     Peut retourner un code de langue vide, lorsqu'un texte par défaut est indiqué.
84
+     **/
85
+    protected function extraire_trads($bloc) {
86
+        $trads = [];
87
+
88
+        $langs = $this->collecteur($bloc, ']', '[', '@[\[]([a-z]{2,3}(_[a-z]{2,3})?(_[a-z]{2,3})?)[\]]@siS');
89
+        $lang = '';
90
+        $pos_prev = 0;
91
+        foreach ($langs as $l) {
92
+            $pos = $l['pos'];
93
+            if ($lang or $pos > $pos_prev) {
94
+                $trads[$lang] = substr($bloc, $pos_prev, $pos - $pos_prev);
95
+            }
96
+            $lang = $l['match'][1];
97
+            $pos_prev = $pos + $l['length'];
98
+        }
99
+        $trads[$lang] = substr($bloc, $pos_prev);
100
+
101
+        return $trads;
102
+    }
103
+
104
+    /**
105
+     * Recoller ensemble les trads pour reconstituer le texte dans la balise <multi>...</multi>
106
+     * @param $trads
107
+     * @return string
108
+     */
109
+    protected function agglomerer_trads($trads) {
110
+        $texte = '';
111
+        foreach ($trads as $lang => $trad) {
112
+            if ($texte or $lang) {
113
+                $texte .= "[$lang]";
114
+            }
115
+            $texte .= $trad;
116
+        }
117
+        return $texte;
118
+    }
119
+
120
+    /**
121
+     * @param string $texte
122
+     * @param array $options
123
+     *   bool $collecter_liens
124
+     * @return array
125
+     */
126
+    public function collecter(string $texte, array $options = []): array {
127
+        if (!$texte) {
128
+            return [];
129
+        }
130
+
131
+        // collecter les matchs de la preg
132
+        $multis = $this->collecteur($texte, '', '<multi', $this->preg_multi, empty($options['detecter_presence']) ? 0 : 1);
133
+
134
+        // si on veut seulement detecter la présence, on peut retourner tel quel
135
+        if (empty($options['detecter_presence'])) {
136
+
137
+            $pos_prev = 0;
138
+            foreach ($multis as $k => &$multi) {
139
+
140
+                $multi['texte'] = $multi['match'][1];
141
+                // extraire les trads du texte
142
+                $trads = $this->extraire_trads($multi['match'][1]);
143
+                $multi['trads'] = $trads;
144
+            }
145
+        }
146
+
147
+        return $multis;
148
+    }
149
+
150
+    /**
151
+     * Traiter les multis d'un texte
152
+     *
153
+     * @uses approcher_langue()
154
+     * @uses lang_typo()
155
+     * @uses code_echappement()
156
+     * @uses echappe_retour()
157
+     *
158
+     * @param string $texte
159
+     * @param array $options
160
+     *   ?string $lang
161
+     *   ?string $lang_defaut
162
+     *   ?bool echappe_span
163
+     *   ?bool appliquer_typo
164
+     * @return string
165
+     */
166
+    public function traiter(string $texte, array $options) {
167
+        if ($texte) {
168
+
169
+            $multis = $this->collecter($texte);
170
+            if (!empty($multis)) {
171
+                $lang = $options['lang'] ?? $GLOBALS['spip_lang'];
172
+                $lang_defaut = $options['lang_defaut'] ?? _LANGUE_PAR_DEFAUT;
173
+                $echappe_span = $options['echappe_span'] ?? false;
174
+                $appliquer_typo = $options['appliquer_typo'] ?? true;
175
+
176
+                if (!function_exists('approcher_langue')) {
177
+                    include_spip('inc/lang');
178
+                }
179
+                if (!function_exists('code_echappement')) {
180
+                    include_spip('inc/texte_mini');
181
+                }
182
+
183
+                $offset_pos = 0;
184
+                foreach ($multis as $m) {
185
+
186
+                    // chercher la version de la langue courante
187
+                    $trads = $m['trads'];
188
+                    if ($l = approcher_langue($trads, $lang)) {
189
+                        $trad = $trads[$l];
190
+                    } else {
191
+                        if ($lang_defaut == 'aucune') {
192
+                            $trad = '';
193
+                        } else {
194
+                            // langue absente, prendre le fr ou une langue précisée (meme comportement que inc/traduire.php)
195
+                            // ou la premiere dispo
196
+                            if (!$l = approcher_langue($trads, $options['lang_defaut'])) {
197
+                                $l = array_values($trads);
198
+                                $l = reset($l);
199
+                            }
200
+
201
+                            // mais typographier le texte selon les regles de celle-ci
202
+                            // Attention aux blocs multi sur plusieurs lignes
203
+                            if ($appliquer_typo) {
204
+                                $trad = $trads[$l];
205
+                                $typographie = charger_fonction(lang_typo($l), 'typographie');
206
+                                $trad = $typographie($trad);
207
+
208
+                                // Tester si on echappe en span ou en div
209
+                                // il ne faut pas echapper en div si propre produit un seul paragraphe
210
+                                include_spip('inc/texte');
211
+                                $trad_propre = preg_replace(',(^<p[^>]*>|</p>$),Uims', '', propre($trad));
212
+                                $mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $trad_propre) ? 'div' : 'span';
213
+                                if ($mode === 'div') {
214
+                                    $trad = rtrim($trad) . "\n\n";
215
+                                }
216
+                                $trad = code_echappement($trad, 'multi', false, $mode);
217
+                                $trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
218
+                                if (lang_dir($l) !== lang_dir($lang)) {
219
+                                    $trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
220
+                                }
221
+                                if (!$echappe_span) {
222
+                                    $trad = echappe_retour($trad, 'multi');
223
+                                }
224
+                            }
225
+                        }
226
+                    }
227
+
228
+                    $texte = substr_replace($texte, $trad, $m['pos'] + $offset_pos, $m['length']);
229
+                    $offset_pos += strlen($trad) - $m['length'];
230
+                }
231
+            }
232
+        }
233
+
234
+        return $texte;
235
+    }
236 236
 
237 237
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -209,9 +209,9 @@
 block discarded – undo
209 209
 								// il ne faut pas echapper en div si propre produit un seul paragraphe
210 210
 								include_spip('inc/texte');
211 211
 								$trad_propre = preg_replace(',(^<p[^>]*>|</p>$),Uims', '', propre($trad));
212
-								$mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $trad_propre) ? 'div' : 'span';
212
+								$mode = preg_match(',</?('._BALISES_BLOCS.')[>[:space:]],iS', $trad_propre) ? 'div' : 'span';
213 213
 								if ($mode === 'div') {
214
-									$trad = rtrim($trad) . "\n\n";
214
+									$trad = rtrim($trad)."\n\n";
215 215
 								}
216 216
 								$trad = code_echappement($trad, 'multi', false, $mode);
217 217
 								$trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
Please login to merge, or discard this patch.
ecrire/inc/modeles.php 1 patch
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -11,7 +11,7 @@  discard block
 block discarded – undo
11 11
 \***************************************************************************/
12 12
 
13 13
 if (!defined('_ECRIRE_INC_VERSION')) {
14
-	return;
14
+    return;
15 15
 }
16 16
 
17 17
 /**
@@ -26,16 +26,16 @@  discard block
 block discarded – undo
26 26
  */
27 27
 function traiter_modeles($texte, $doublons = false, $echap = '', string $connect = '', ?Spip\Texte\Collecteur\Liens $collecteurLiens = null, $env = []) {
28 28
 
29
-	include_spip("src/Texte/Collecteur/AbstractCollecteur");
30
-	include_spip("src/Texte/Collecteur/Modeles");
31
-	$collecteurModeles = new Spip\Texte\Collecteur\Modeles();
29
+    include_spip("src/Texte/Collecteur/AbstractCollecteur");
30
+    include_spip("src/Texte/Collecteur/Modeles");
31
+    $collecteurModeles = new Spip\Texte\Collecteur\Modeles();
32 32
 
33
-	$options = [
34
-		'doublons' => $doublons,
35
-		'echap' => $echap,
36
-		'connect' => $connect,
37
-		'collecteurLiens' => $collecteurLiens,
38
-		'env' => $env
39
-	];
40
-	return $collecteurModeles->traiter($texte ?? '', $options);
33
+    $options = [
34
+        'doublons' => $doublons,
35
+        'echap' => $echap,
36
+        'connect' => $connect,
37
+        'collecteurLiens' => $collecteurLiens,
38
+        'env' => $env
39
+    ];
40
+    return $collecteurModeles->traiter($texte ?? '', $options);
41 41
 }
Please login to merge, or discard this patch.
ecrire/inc/liens.php 1 patch
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -11,5 +11,5 @@
 block discarded – undo
11 11
 \***************************************************************************/
12 12
 
13 13
 if (!defined('_ECRIRE_INC_VERSION')) {
14
-	return;
14
+    return;
15 15
 }
Please login to merge, or discard this patch.
ecrire/inc/texte_mini.php 3 patches
Indentation   +519 added lines, -519 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  **/
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 include_spip('inc/filtres');
23 23
 include_spip('inc/lang');
@@ -39,21 +39,21 @@  discard block
 block discarded – undo
39 39
  **/
40 40
 function definir_puce() {
41 41
 
42
-	// Attention au sens, qui n'est pas defini de la meme facon dans
43
-	// l'espace prive (spip_lang est la langue de l'interface, lang_dir
44
-	// celle du texte) et public (spip_lang est la langue du texte)
45
-	$dir = _DIR_RESTREINT ? lang_dir() : lang_dir($GLOBALS['spip_lang']);
42
+    // Attention au sens, qui n'est pas defini de la meme facon dans
43
+    // l'espace prive (spip_lang est la langue de l'interface, lang_dir
44
+    // celle du texte) et public (spip_lang est la langue du texte)
45
+    $dir = _DIR_RESTREINT ? lang_dir() : lang_dir($GLOBALS['spip_lang']);
46 46
 
47
-	$p = 'puce' . (test_espace_prive() ? '_prive' : '');
48
-	if ($dir == 'rtl') {
49
-		$p .= '_rtl';
50
-	}
47
+    $p = 'puce' . (test_espace_prive() ? '_prive' : '');
48
+    if ($dir == 'rtl') {
49
+        $p .= '_rtl';
50
+    }
51 51
 
52
-	if (!isset($GLOBALS[$p])) {
53
-		$GLOBALS[$p] = '<span class="spip-puce ' . $dir . '"><b>–</b></span>';
54
-	}
52
+    if (!isset($GLOBALS[$p])) {
53
+        $GLOBALS[$p] = '<span class="spip-puce ' . $dir . '"><b>–</b></span>';
54
+    }
55 55
 
56
-	return $GLOBALS[$p];
56
+    return $GLOBALS[$p];
57 57
 }
58 58
 
59 59
 /**
@@ -67,30 +67,30 @@  discard block
 block discarded – undo
67 67
  */
68 68
 function spip_balisage_code(string $corps, bool $bloc = false, string $attributs = '', string $langage = '') {
69 69
 
70
-	$echap = spip_htmlspecialchars($corps); // il ne faut pas passer dans entites_html, ne pas transformer les &#xxx; du code !
71
-	$class = "spip_code " . ($bloc ? 'spip_code_block' : 'spip_code_inline');
72
-	if ($langage) {
73
-		$class .= " language-$langage";
74
-	}
75
-	if ($attributs) {
76
-		$attributs = " " . trim($attributs);
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
-	}
87
-	else {
88
-		$echap = str_replace("\t", "&nbsp; &nbsp; &nbsp; &nbsp; ", $echap);
89
-		$echap = str_replace("  ", " &nbsp;", $echap);
90
-		$html = "<code class=\"$class\" dir=\"ltr\"$attributs>" . $echap . '</code>';
91
-	}
92
-
93
-	return $html;
70
+    $echap = spip_htmlspecialchars($corps); // il ne faut pas passer dans entites_html, ne pas transformer les &#xxx; du code !
71
+    $class = "spip_code " . ($bloc ? 'spip_code_block' : 'spip_code_inline');
72
+    if ($langage) {
73
+        $class .= " language-$langage";
74
+    }
75
+    if ($attributs) {
76
+        $attributs = " " . trim($attributs);
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
+    }
87
+    else {
88
+        $echap = str_replace("\t", "&nbsp; &nbsp; &nbsp; &nbsp; ", $echap);
89
+        $echap = str_replace("  ", " &nbsp;", $echap);
90
+        $html = "<code class=\"$class\" dir=\"ltr\"$attributs>" . $echap . '</code>';
91
+    }
92
+
93
+    return $html;
94 94
 }
95 95
 
96 96
 
@@ -98,14 +98,14 @@  discard block
 block discarded – undo
98 98
 // dont on souhaite qu'ils provoquent un saut de paragraphe
99 99
 
100 100
 if (!defined('_BALISES_BLOCS')) {
101
-	define(
102
-		'_BALISES_BLOCS',
103
-		'address|applet|article|aside|blockquote|button|center|d[ltd]|div|fieldset|fig(ure|caption)|footer|form|h[1-6r]|hgroup|head|header|iframe|li|map|marquee|nav|noscript|object|ol|pre|section|t(able|[rdh]|body|foot|extarea)|ul|script|style'
104
-	);
101
+    define(
102
+        '_BALISES_BLOCS',
103
+        'address|applet|article|aside|blockquote|button|center|d[ltd]|div|fieldset|fig(ure|caption)|footer|form|h[1-6r]|hgroup|head|header|iframe|li|map|marquee|nav|noscript|object|ol|pre|section|t(able|[rdh]|body|foot|extarea)|ul|script|style'
104
+    );
105 105
 }
106 106
 
107 107
 if (!defined('_BALISES_BLOCS_REGEXP')) {
108
-	define('_BALISES_BLOCS_REGEXP', ',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS');
108
+    define('_BALISES_BLOCS_REGEXP', ',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS');
109 109
 }
110 110
 
111 111
 //
@@ -116,100 +116,100 @@  discard block
 block discarded – undo
116 116
 // une $source differente ; le script detecte automagiquement si ce qu'on
117 117
 // echappe est un div ou un span
118 118
 function code_echappement($rempl, $source = '', $no_transform = false, $mode = null) {
119
-	if (!strlen($rempl)) {
120
-		return '';
121
-	}
122
-
123
-	// Tester si on echappe en span ou en div
124
-	if (is_null($mode) or !in_array($mode, ['div', 'span'])) {
125
-		$mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $rempl) ? 'div' : 'span';
126
-	}
127
-
128
-	// Decouper en morceaux, base64 a des probleme selon la taille de la pile
129
-	$taille = 30000;
130
-	$return = '';
131
-	for ($i = 0; $i < strlen($rempl); $i += $taille) {
132
-		// Convertir en base64 et cacher dans un attribut
133
-		// utiliser les " pour eviter le re-encodage de ' et &#8217
134
-		$base64 = base64_encode(substr($rempl, $i, $taille));
135
-		$return .= "<$mode class=\"base64$source\" title=\"$base64\"></$mode>";
136
-	}
137
-
138
-	return $return;
119
+    if (!strlen($rempl)) {
120
+        return '';
121
+    }
122
+
123
+    // Tester si on echappe en span ou en div
124
+    if (is_null($mode) or !in_array($mode, ['div', 'span'])) {
125
+        $mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $rempl) ? 'div' : 'span';
126
+    }
127
+
128
+    // Decouper en morceaux, base64 a des probleme selon la taille de la pile
129
+    $taille = 30000;
130
+    $return = '';
131
+    for ($i = 0; $i < strlen($rempl); $i += $taille) {
132
+        // Convertir en base64 et cacher dans un attribut
133
+        // utiliser les " pour eviter le re-encodage de ' et &#8217
134
+        $base64 = base64_encode(substr($rempl, $i, $taille));
135
+        $return .= "<$mode class=\"base64$source\" title=\"$base64\"></$mode>";
136
+    }
137
+
138
+    return $return;
139 139
 }
140 140
 
141 141
 
142 142
 // Echapper les <html>...</ html>
143 143
 function traiter_echap_html_dist($regs, $options = []) {
144
-	return $regs[3];
144
+    return $regs[3];
145 145
 }
146 146
 
147 147
 // Echapper les <pre>...</ pre>
148 148
 function traiter_echap_pre_dist($regs, $options = []) {
149
-	// echapper les <code> dans <pre>
150
-	$pre = $regs[3];
151
-
152
-	// echapper les < dans <code>
153
-	// on utilise _PROTEGE_BLOCS pour simplifier le code et la maintenance, mais on est interesse que par <code>
154
-	if (
155
-		strpos($pre, '<') !== false
156
-		and preg_match_all(_PROTEGE_BLOCS, $pre, $matches, PREG_SET_ORDER)
157
-	) {
158
-		foreach ($matches as $m) {
159
-			if ($m[1] === 'code') {
160
-				$code = '<code' . $m[2] . '>' . spip_htmlspecialchars($m[3]) . '</code>';
161
-				$pre = str_replace($m[0], $code, $pre);
162
-			}
163
-		}
164
-	}
165
-	return "<pre>$pre</pre>";
149
+    // echapper les <code> dans <pre>
150
+    $pre = $regs[3];
151
+
152
+    // echapper les < dans <code>
153
+    // on utilise _PROTEGE_BLOCS pour simplifier le code et la maintenance, mais on est interesse que par <code>
154
+    if (
155
+        strpos($pre, '<') !== false
156
+        and preg_match_all(_PROTEGE_BLOCS, $pre, $matches, PREG_SET_ORDER)
157
+    ) {
158
+        foreach ($matches as $m) {
159
+            if ($m[1] === 'code') {
160
+                $code = '<code' . $m[2] . '>' . spip_htmlspecialchars($m[3]) . '</code>';
161
+                $pre = str_replace($m[0], $code, $pre);
162
+            }
163
+        }
164
+    }
165
+    return "<pre>$pre</pre>";
166 166
 }
167 167
 
168 168
 // Echapper les <code>...</ code>
169 169
 function traiter_echap_code_dist($regs, $options = []) {
170
-	[, , $att, $corps] = $regs;
170
+    [, , $att, $corps] = $regs;
171 171
 
172
-	// ne pas mettre le <div...> s'il n'y a qu'une ligne
173
-	if (strpos($corps, "\n") !== false) {
174
-		// supprimer les sauts de ligne debut/fin
175
-		// (mais pas les espaces => ascii art).
176
-		$corps = preg_replace("/^[\n\r]+|[\n\r]+$/s", '', $corps);
172
+    // ne pas mettre le <div...> s'il n'y a qu'une ligne
173
+    if (strpos($corps, "\n") !== false) {
174
+        // supprimer les sauts de ligne debut/fin
175
+        // (mais pas les espaces => ascii art).
176
+        $corps = preg_replace("/^[\n\r]+|[\n\r]+$/s", '', $corps);
177 177
 
178
-		$echap = spip_balisage_code($corps, true, $att);
179
-	} else {
180
-		$echap = spip_balisage_code($corps, false, $att);
181
-	}
178
+        $echap = spip_balisage_code($corps, true, $att);
179
+    } else {
180
+        $echap = spip_balisage_code($corps, false, $att);
181
+    }
182 182
 
183
-	return $echap;
183
+    return $echap;
184 184
 }
185 185
 
186 186
 // Echapper les <cadre>...</ cadre> aka <frame>...</ frame>
187 187
 function traiter_echap_cadre_dist($regs, $options = []) {
188
-	$echap = trim(entites_html($regs[3]));
189
-	// compter les lignes un peu plus finement qu'avec les \n
190
-	$lignes = explode("\n", trim($echap));
191
-	$n = 0;
192
-	foreach ($lignes as $l) {
193
-		$n += floor(strlen($l) / 60) + 1;
194
-	}
195
-	$n = max($n, 2);
196
-	$echap = "\n<textarea readonly='readonly' cols='40' rows='$n' class='spip_cadre spip_cadre_block' dir='ltr'>$echap</textarea>";
197
-
198
-	return $echap;
188
+    $echap = trim(entites_html($regs[3]));
189
+    // compter les lignes un peu plus finement qu'avec les \n
190
+    $lignes = explode("\n", trim($echap));
191
+    $n = 0;
192
+    foreach ($lignes as $l) {
193
+        $n += floor(strlen($l) / 60) + 1;
194
+    }
195
+    $n = max($n, 2);
196
+    $echap = "\n<textarea readonly='readonly' cols='40' rows='$n' class='spip_cadre spip_cadre_block' dir='ltr'>$echap</textarea>";
197
+
198
+    return $echap;
199 199
 }
200 200
 
201 201
 function traiter_echap_frame_dist($regs, $options = []) {
202
-	return traiter_echap_cadre_dist($regs);
202
+    return traiter_echap_cadre_dist($regs);
203 203
 }
204 204
 
205 205
 function traiter_echap_script_dist($regs, $options = []) {
206
-	// rendre joli (et inactif) si c'est un script language=php
207
-	if (preg_match(',<script\b[^>]+php,ims', $regs[0])) {
208
-		return highlight_string($regs[0], true);
209
-	}
206
+    // rendre joli (et inactif) si c'est un script language=php
207
+    if (preg_match(',<script\b[^>]+php,ims', $regs[0])) {
208
+        return highlight_string($regs[0], true);
209
+    }
210 210
 
211
-	// Cas normal : le script passe tel quel
212
-	return $regs[0];
211
+    // Cas normal : le script passe tel quel
212
+    return $regs[0];
213 213
 }
214 214
 
215 215
 define('_PROTEGE_BLOCS', ',<(html|pre|code|cadre|frame|script|style)(\b[^>]*)?>(.*)</\1>,UimsS');
@@ -228,73 +228,73 @@  discard block
 block discarded – undo
228 228
  * @return string|string[]
229 229
  */
230 230
 function echappe_html(
231
-	$letexte,
232
-	$source = '',
233
-	$no_transform = false,
234
-	$preg = '',
235
-	$callback_prefix = '',
236
-	$callback_options = []
231
+    $letexte,
232
+    $source = '',
233
+    $no_transform = false,
234
+    $preg = '',
235
+    $callback_prefix = '',
236
+    $callback_options = []
237 237
 ) {
238
-	if (!is_string($letexte) or !strlen($letexte)) {
239
-		return $letexte;
240
-	}
241
-
242
-	if (
243
-		($preg or strpos($letexte, '<') !== false)
244
-		and preg_match_all($preg ?: _PROTEGE_BLOCS, $letexte, $matches, PREG_SET_ORDER)
245
-	) {
246
-		foreach ($matches as $regs) {
247
-			// echappements tels quels ?
248
-			if ($no_transform) {
249
-				$echap = $regs[0];
250
-			} // sinon les traiter selon le cas
251
-			else {
252
-				$callback_secure_prefix = ($callback_options['secure_prefix'] ?? '');
253
-				if (
254
-					function_exists($f = $callback_prefix . $callback_secure_prefix . 'traiter_echap_' . strtolower($regs[1]))
255
-					or function_exists($f = $f . '_dist')
256
-					or ($callback_secure_prefix and (
257
-						function_exists($f = $callback_prefix . 'traiter_echap_' . strtolower($regs[1]))
258
-						or function_exists($f = $f . '_dist')
259
-					))
260
-				) {
261
-					$echap = $f($regs, $callback_options);
262
-				}
263
-			}
264
-
265
-			$p = strpos($letexte, (string) $regs[0]);
266
-			$letexte = substr_replace($letexte, code_echappement($echap, $source, $no_transform), $p, strlen($regs[0]));
267
-		}
268
-	}
269
-
270
-	if ($no_transform) {
271
-		return $letexte;
272
-	}
273
-
274
-	// Echapper le php pour faire joli (ici, c'est pas pour la securite)
275
-	// seulement si on a echappe les <script>
276
-	// (derogatoire car on ne peut pas faire passer < ? ... ? >
277
-	// dans une callback autonommee
278
-	if (strpos($preg ?: _PROTEGE_BLOCS, 'script') !== false) {
279
-		if (
280
-			strpos($letexte, '<' . '?') !== false and preg_match_all(
281
-				',<[?].*($|[?]>),UisS',
282
-				$letexte,
283
-				$matches,
284
-				PREG_SET_ORDER
285
-			)
286
-		) {
287
-			foreach ($matches as $regs) {
288
-				$letexte = str_replace(
289
-					$regs[0],
290
-					code_echappement(highlight_string($regs[0], true), $source),
291
-					$letexte
292
-				);
293
-			}
294
-		}
295
-	}
296
-
297
-	return $letexte;
238
+    if (!is_string($letexte) or !strlen($letexte)) {
239
+        return $letexte;
240
+    }
241
+
242
+    if (
243
+        ($preg or strpos($letexte, '<') !== false)
244
+        and preg_match_all($preg ?: _PROTEGE_BLOCS, $letexte, $matches, PREG_SET_ORDER)
245
+    ) {
246
+        foreach ($matches as $regs) {
247
+            // echappements tels quels ?
248
+            if ($no_transform) {
249
+                $echap = $regs[0];
250
+            } // sinon les traiter selon le cas
251
+            else {
252
+                $callback_secure_prefix = ($callback_options['secure_prefix'] ?? '');
253
+                if (
254
+                    function_exists($f = $callback_prefix . $callback_secure_prefix . 'traiter_echap_' . strtolower($regs[1]))
255
+                    or function_exists($f = $f . '_dist')
256
+                    or ($callback_secure_prefix and (
257
+                        function_exists($f = $callback_prefix . 'traiter_echap_' . strtolower($regs[1]))
258
+                        or function_exists($f = $f . '_dist')
259
+                    ))
260
+                ) {
261
+                    $echap = $f($regs, $callback_options);
262
+                }
263
+            }
264
+
265
+            $p = strpos($letexte, (string) $regs[0]);
266
+            $letexte = substr_replace($letexte, code_echappement($echap, $source, $no_transform), $p, strlen($regs[0]));
267
+        }
268
+    }
269
+
270
+    if ($no_transform) {
271
+        return $letexte;
272
+    }
273
+
274
+    // Echapper le php pour faire joli (ici, c'est pas pour la securite)
275
+    // seulement si on a echappe les <script>
276
+    // (derogatoire car on ne peut pas faire passer < ? ... ? >
277
+    // dans une callback autonommee
278
+    if (strpos($preg ?: _PROTEGE_BLOCS, 'script') !== false) {
279
+        if (
280
+            strpos($letexte, '<' . '?') !== false and preg_match_all(
281
+                ',<[?].*($|[?]>),UisS',
282
+                $letexte,
283
+                $matches,
284
+                PREG_SET_ORDER
285
+            )
286
+        ) {
287
+            foreach ($matches as $regs) {
288
+                $letexte = str_replace(
289
+                    $regs[0],
290
+                    code_echappement(highlight_string($regs[0], true), $source),
291
+                    $letexte
292
+                );
293
+            }
294
+        }
295
+    }
296
+
297
+    return $letexte;
298 298
 }
299 299
 
300 300
 //
@@ -302,57 +302,57 @@  discard block
 block discarded – undo
302 302
 // Rq: $source sert a faire des echappements "a soi" qui ne sont pas nettoyes
303 303
 // par propre() : exemple dans multi et dans typo()
304 304
 function echappe_retour($letexte, $source = '', $filtre = '') {
305
-	if (strpos($letexte, (string) "base64$source")) {
306
-		# spip_log(spip_htmlspecialchars($letexte));  ## pour les curieux
307
-		$max_prof = 5;
308
-		while (
309
-			strpos($letexte, '<') !== false
310
-			and
311
-			preg_match_all(
312
-				',<(span|div)\sclass=[\'"]base64' . $source . '[\'"]\s(.*)>\s*</\1>,UmsS',
313
-				$letexte,
314
-				$regs,
315
-				PREG_SET_ORDER
316
-			)
317
-			and $max_prof--
318
-		) {
319
-			foreach ($regs as $reg) {
320
-				$rempl = base64_decode(extraire_attribut($reg[0], 'title'));
321
-				// recherche d'attributs supplementaires
322
-				$at = [];
323
-				foreach (['lang', 'dir'] as $attr) {
324
-					if ($a = extraire_attribut($reg[0], $attr)) {
325
-						$at[$attr] = $a;
326
-					}
327
-				}
328
-				if ($at) {
329
-					$rempl = '<' . $reg[1] . '>' . $rempl . '</' . $reg[1] . '>';
330
-					foreach ($at as $attr => $a) {
331
-						$rempl = inserer_attribut($rempl, $attr, $a);
332
-					}
333
-				}
334
-				if ($filtre) {
335
-					$rempl = $filtre($rempl);
336
-				}
337
-				$letexte = str_replace($reg[0], $rempl, $letexte);
338
-			}
339
-		}
340
-	}
341
-
342
-	return $letexte;
305
+    if (strpos($letexte, (string) "base64$source")) {
306
+        # spip_log(spip_htmlspecialchars($letexte));  ## pour les curieux
307
+        $max_prof = 5;
308
+        while (
309
+            strpos($letexte, '<') !== false
310
+            and
311
+            preg_match_all(
312
+                ',<(span|div)\sclass=[\'"]base64' . $source . '[\'"]\s(.*)>\s*</\1>,UmsS',
313
+                $letexte,
314
+                $regs,
315
+                PREG_SET_ORDER
316
+            )
317
+            and $max_prof--
318
+        ) {
319
+            foreach ($regs as $reg) {
320
+                $rempl = base64_decode(extraire_attribut($reg[0], 'title'));
321
+                // recherche d'attributs supplementaires
322
+                $at = [];
323
+                foreach (['lang', 'dir'] as $attr) {
324
+                    if ($a = extraire_attribut($reg[0], $attr)) {
325
+                        $at[$attr] = $a;
326
+                    }
327
+                }
328
+                if ($at) {
329
+                    $rempl = '<' . $reg[1] . '>' . $rempl . '</' . $reg[1] . '>';
330
+                    foreach ($at as $attr => $a) {
331
+                        $rempl = inserer_attribut($rempl, $attr, $a);
332
+                    }
333
+                }
334
+                if ($filtre) {
335
+                    $rempl = $filtre($rempl);
336
+                }
337
+                $letexte = str_replace($reg[0], $rempl, $letexte);
338
+            }
339
+        }
340
+    }
341
+
342
+    return $letexte;
343 343
 }
344 344
 
345 345
 // Reinserer le javascript de confiance (venant des modeles)
346 346
 
347 347
 function echappe_retour_modeles($letexte, $interdire_scripts = false) {
348
-	$letexte = echappe_retour($letexte);
348
+    $letexte = echappe_retour($letexte);
349 349
 
350
-	// Dans les appels directs hors squelette, securiser aussi ici
351
-	if ($interdire_scripts) {
352
-		$letexte = interdire_scripts($letexte);
353
-	}
350
+    // Dans les appels directs hors squelette, securiser aussi ici
351
+    if ($interdire_scripts) {
352
+        $letexte = interdire_scripts($letexte);
353
+    }
354 354
 
355
-	return trim($letexte);
355
+    return trim($letexte);
356 356
 }
357 357
 
358 358
 
@@ -380,131 +380,131 @@  discard block
 block discarded – undo
380 380
  *     Texte coupé
381 381
  **/
382 382
 function couper($texte, $taille = 50, $suite = null) {
383
-	if (!($length = strlen($texte)) or $taille <= 0) {
384
-		return '';
385
-	}
386
-	$offset = 400 + 2 * $taille;
387
-	while (
388
-		$offset < $length
389
-		and strlen(preg_replace(',<(!--|\w|/)[^>]+>,Uims', '', substr($texte, 0, $offset))) < $taille
390
-	) {
391
-		$offset = 2 * $offset;
392
-	}
393
-	if (
394
-		$offset < $length
395
-		&& ($p_tag_ouvrant = strpos($texte, '<', $offset)) !== null
396
-	) {
397
-		$p_tag_fermant = strpos($texte, '>', $offset);
398
-		if ($p_tag_fermant && ($p_tag_fermant < $p_tag_ouvrant)) {
399
-			$offset = $p_tag_fermant + 1;
400
-		} // prolonger la coupe jusqu'au tag fermant suivant eventuel
401
-	}
402
-	$texte = substr($texte, 0, $offset); /* eviter de travailler sur 10ko pour extraire 150 caracteres */
403
-
404
-	if (!function_exists('nettoyer_raccourcis_typo')) {
405
-		include_spip('inc/lien');
406
-	}
407
-	$texte = nettoyer_raccourcis_typo($texte);
408
-
409
-	// balises de sauts de ligne et paragraphe
410
-	$texte = preg_replace('/<p( [^>]*)?' . '>/', "\r", $texte);
411
-	$texte = preg_replace('/<br( [^>]*)?' . '>/', "\n", $texte);
412
-
413
-	// on repasse les doubles \n en \r que nettoyer_raccourcis_typo() a pu modifier
414
-	$texte = str_replace("\n\n", "\r", $texte);
415
-
416
-	// supprimer les tags
417
-	$texte = supprimer_tags($texte);
418
-	$texte = trim(str_replace("\n", ' ', $texte));
419
-	$texte .= "\n";  // marquer la fin
420
-
421
-	// corriger la longueur de coupe
422
-	// en fonction de la presence de caracteres utf
423
-	if ($GLOBALS['meta']['charset'] == 'utf-8') {
424
-		$long = charset2unicode($texte);
425
-		$long = spip_substr($long, 0, max($taille, 1));
426
-		$nbcharutf = preg_match_all('/(&#[0-9]{3,6};)/S', $long, $matches);
427
-		$taille += $nbcharutf;
428
-	}
429
-
430
-
431
-	// couper au mot precedent
432
-	$long = spip_substr($texte, 0, max($taille - 4, 1));
433
-	$u = $GLOBALS['meta']['pcre_u'];
434
-	$court = preg_replace("/([^\s][\s]+)[^\s]*\n?$/" . $u, "\\1", $long);
435
-	if (is_null($suite)) {
436
-		$suite = (defined('_COUPER_SUITE') ? _COUPER_SUITE : '&nbsp;(...)');
437
-	}
438
-	$points = $suite;
439
-
440
-	// trop court ? ne pas faire de (...)
441
-	if (spip_strlen($court) < max(0.75 * $taille, 2)) {
442
-		$points = '';
443
-		$long = spip_substr($texte, 0, $taille);
444
-		$texte = preg_replace("/([^\s][\s]+)[^\s]*\n?$/" . $u, "\\1", $long);
445
-		// encore trop court ? couper au caractere
446
-		if (spip_strlen($texte) < 0.75 * $taille) {
447
-			$texte = $long;
448
-		}
449
-	} else {
450
-		$texte = $court;
451
-	}
452
-
453
-	if (strpos($texte, "\n")) {  // la fin est encore la : c'est qu'on n'a pas de texte de suite
454
-	$points = '';
455
-	}
456
-
457
-	// remettre les paragraphes
458
-	$texte = preg_replace("/\r+/", "\n\n", $texte);
459
-
460
-	// supprimer l'eventuelle entite finale mal coupee
461
-	$texte = preg_replace('/&#?[a-z0-9]*$/S', '', $texte);
462
-
463
-	return quote_amp(trim($texte)) . $points;
383
+    if (!($length = strlen($texte)) or $taille <= 0) {
384
+        return '';
385
+    }
386
+    $offset = 400 + 2 * $taille;
387
+    while (
388
+        $offset < $length
389
+        and strlen(preg_replace(',<(!--|\w|/)[^>]+>,Uims', '', substr($texte, 0, $offset))) < $taille
390
+    ) {
391
+        $offset = 2 * $offset;
392
+    }
393
+    if (
394
+        $offset < $length
395
+        && ($p_tag_ouvrant = strpos($texte, '<', $offset)) !== null
396
+    ) {
397
+        $p_tag_fermant = strpos($texte, '>', $offset);
398
+        if ($p_tag_fermant && ($p_tag_fermant < $p_tag_ouvrant)) {
399
+            $offset = $p_tag_fermant + 1;
400
+        } // prolonger la coupe jusqu'au tag fermant suivant eventuel
401
+    }
402
+    $texte = substr($texte, 0, $offset); /* eviter de travailler sur 10ko pour extraire 150 caracteres */
403
+
404
+    if (!function_exists('nettoyer_raccourcis_typo')) {
405
+        include_spip('inc/lien');
406
+    }
407
+    $texte = nettoyer_raccourcis_typo($texte);
408
+
409
+    // balises de sauts de ligne et paragraphe
410
+    $texte = preg_replace('/<p( [^>]*)?' . '>/', "\r", $texte);
411
+    $texte = preg_replace('/<br( [^>]*)?' . '>/', "\n", $texte);
412
+
413
+    // on repasse les doubles \n en \r que nettoyer_raccourcis_typo() a pu modifier
414
+    $texte = str_replace("\n\n", "\r", $texte);
415
+
416
+    // supprimer les tags
417
+    $texte = supprimer_tags($texte);
418
+    $texte = trim(str_replace("\n", ' ', $texte));
419
+    $texte .= "\n";  // marquer la fin
420
+
421
+    // corriger la longueur de coupe
422
+    // en fonction de la presence de caracteres utf
423
+    if ($GLOBALS['meta']['charset'] == 'utf-8') {
424
+        $long = charset2unicode($texte);
425
+        $long = spip_substr($long, 0, max($taille, 1));
426
+        $nbcharutf = preg_match_all('/(&#[0-9]{3,6};)/S', $long, $matches);
427
+        $taille += $nbcharutf;
428
+    }
429
+
430
+
431
+    // couper au mot precedent
432
+    $long = spip_substr($texte, 0, max($taille - 4, 1));
433
+    $u = $GLOBALS['meta']['pcre_u'];
434
+    $court = preg_replace("/([^\s][\s]+)[^\s]*\n?$/" . $u, "\\1", $long);
435
+    if (is_null($suite)) {
436
+        $suite = (defined('_COUPER_SUITE') ? _COUPER_SUITE : '&nbsp;(...)');
437
+    }
438
+    $points = $suite;
439
+
440
+    // trop court ? ne pas faire de (...)
441
+    if (spip_strlen($court) < max(0.75 * $taille, 2)) {
442
+        $points = '';
443
+        $long = spip_substr($texte, 0, $taille);
444
+        $texte = preg_replace("/([^\s][\s]+)[^\s]*\n?$/" . $u, "\\1", $long);
445
+        // encore trop court ? couper au caractere
446
+        if (spip_strlen($texte) < 0.75 * $taille) {
447
+            $texte = $long;
448
+        }
449
+    } else {
450
+        $texte = $court;
451
+    }
452
+
453
+    if (strpos($texte, "\n")) {  // la fin est encore la : c'est qu'on n'a pas de texte de suite
454
+    $points = '';
455
+    }
456
+
457
+    // remettre les paragraphes
458
+    $texte = preg_replace("/\r+/", "\n\n", $texte);
459
+
460
+    // supprimer l'eventuelle entite finale mal coupee
461
+    $texte = preg_replace('/&#?[a-z0-9]*$/S', '', $texte);
462
+
463
+    return quote_amp(trim($texte)) . $points;
464 464
 }
465 465
 
466 466
 
467 467
 function protege_js_modeles($t) {
468
-	if (isset($GLOBALS['visiteur_session'])) {
469
-		if (preg_match_all(',<script.*?($|</script.),isS', $t, $r, PREG_SET_ORDER)) {
470
-			if (!defined('_PROTEGE_JS_MODELES')) {
471
-				include_spip('inc/acces');
472
-				define('_PROTEGE_JS_MODELES', creer_uniqid());
473
-			}
474
-			foreach ($r as $regs) {
475
-				$t = str_replace($regs[0], code_echappement($regs[0], 'javascript' . _PROTEGE_JS_MODELES), $t);
476
-			}
477
-		}
478
-		if (preg_match_all(',<\?php.*?($|\?' . '>),isS', $t, $r, PREG_SET_ORDER)) {
479
-			if (!defined('_PROTEGE_PHP_MODELES')) {
480
-				include_spip('inc/acces');
481
-				define('_PROTEGE_PHP_MODELES', creer_uniqid());
482
-			}
483
-			foreach ($r as $regs) {
484
-				$t = str_replace($regs[0], code_echappement($regs[0], 'php' . _PROTEGE_PHP_MODELES), $t);
485
-			}
486
-		}
487
-	}
488
-
489
-	return $t;
468
+    if (isset($GLOBALS['visiteur_session'])) {
469
+        if (preg_match_all(',<script.*?($|</script.),isS', $t, $r, PREG_SET_ORDER)) {
470
+            if (!defined('_PROTEGE_JS_MODELES')) {
471
+                include_spip('inc/acces');
472
+                define('_PROTEGE_JS_MODELES', creer_uniqid());
473
+            }
474
+            foreach ($r as $regs) {
475
+                $t = str_replace($regs[0], code_echappement($regs[0], 'javascript' . _PROTEGE_JS_MODELES), $t);
476
+            }
477
+        }
478
+        if (preg_match_all(',<\?php.*?($|\?' . '>),isS', $t, $r, PREG_SET_ORDER)) {
479
+            if (!defined('_PROTEGE_PHP_MODELES')) {
480
+                include_spip('inc/acces');
481
+                define('_PROTEGE_PHP_MODELES', creer_uniqid());
482
+            }
483
+            foreach ($r as $regs) {
484
+                $t = str_replace($regs[0], code_echappement($regs[0], 'php' . _PROTEGE_PHP_MODELES), $t);
485
+            }
486
+        }
487
+    }
488
+
489
+    return $t;
490 490
 }
491 491
 
492 492
 
493 493
 function echapper_faux_tags($letexte) {
494
-	if (strpos($letexte, '<') === false) {
495
-		return $letexte;
496
-	}
497
-	$textMatches = preg_split(',(</?[a-z!][^<>]*>),', $letexte, -1, PREG_SPLIT_DELIM_CAPTURE);
498
-
499
-	$letexte = '';
500
-	while (is_countable($textMatches) ? count($textMatches) : 0) {
501
-		// un texte a echapper
502
-		$letexte .= str_replace('<', '&lt;', array_shift($textMatches));
503
-		// un tag html qui a servit a faite le split
504
-		$letexte .= array_shift($textMatches);
505
-	}
506
-
507
-	return $letexte;
494
+    if (strpos($letexte, '<') === false) {
495
+        return $letexte;
496
+    }
497
+    $textMatches = preg_split(',(</?[a-z!][^<>]*>),', $letexte, -1, PREG_SPLIT_DELIM_CAPTURE);
498
+
499
+    $letexte = '';
500
+    while (is_countable($textMatches) ? count($textMatches) : 0) {
501
+        // un texte a echapper
502
+        $letexte .= str_replace('<', '&lt;', array_shift($textMatches));
503
+        // un tag html qui a servit a faite le split
504
+        $letexte .= array_shift($textMatches);
505
+    }
506
+
507
+    return $letexte;
508 508
 }
509 509
 
510 510
 /**
@@ -524,115 +524,115 @@  discard block
 block discarded – undo
524 524
  * @return string
525 525
  */
526 526
 function echapper_html_suspect($texte, $options = [], $connect = null, $env = []) {
527
-	static $echapper_html_suspect;
528
-	if (!$texte or !is_string($texte)) {
529
-		return $texte;
530
-	}
531
-
532
-	if (!isset($echapper_html_suspect)) {
533
-		$echapper_html_suspect = charger_fonction('echapper_html_suspect', 'inc', true);
534
-	}
535
-	// si fonction personalisee, on delegue
536
-	if ($echapper_html_suspect) {
537
-		// on collecte le tableau d'arg minimal pour ne pas casser un appel a une fonction inc_echapper_html_suspect() selon l'ancienne signature
538
-		$args = [$texte, $options];
539
-		if ($connect or !empty($env)) {
540
-			$args[] = $connect;
541
-		}
542
-		if (!empty($env)) {
543
-			$args[] = $env;
544
-		}
545
-		return $echapper_html_suspect(...$args);
546
-	}
547
-
548
-	if (is_bool($options)) {
549
-		$options = ['strict' => $options];
550
-	}
551
-	$strict = $options['strict'] ?? true;
552
-
553
-	// pas de balise html ou pas d'attribut sur les balises ? c'est OK
554
-	if (
555
-		strpos($texte, '<') === false
556
-		or strpos($texte, '=') === false
557
-	) {
558
-		return $texte;
559
-	}
560
-
561
-	// dans le prive, on veut afficher tout echappé pour la moderation
562
-	if (!isset($env['espace_prive'])) {
563
-		// conserver le comportement historique en cas d'appel court sans env
564
-		$env['espace_prive'] = test_espace_prive();
565
-	}
566
-	if (!empty($env['espace_prive']) or !empty($env['wysiwyg'])) {
567
-
568
-		// quand c'est du texte qui passe par propre on est plus coulant tant qu'il y a pas d'attribut du type onxxx=
569
-		// car sinon on declenche sur les modeles ou ressources
570
-		if (
571
-			!$strict and
572
-			(strpos($texte, 'on') === false or !preg_match(",<\w+.*\bon\w+\s*=,UimsS", $texte))
573
-		) {
574
-			return $texte;
575
-		}
576
-
577
-		include_spip("src/Texte/Collecteur/AbstractCollecteur");
578
-		include_spip("src/Texte/Collecteur/Modeles");
579
-		$collecteurModeles = new Spip\Texte\Collecteur\Modeles();
580
-		$texte = $collecteurModeles->echapper($texte);
581
-		$texte = echappe_js($texte);
582
-
583
-		$texte_to_check = $texte;
584
-		// si les raccourcis liens vont etre interprétés, il faut les expanser avant de vérifier que le html est safe
585
-		// car un raccourci peut etre utilisé pour faire un lien malin
586
-		// et un raccourci est potentiellement modifié par safehtml, ce qui fait un faux positif dans is_html_safe
587
-		if (!empty($options['expanser_liens'])) {
588
-			$texte_to_check = expanser_liens($texte_to_check, $env['connect'] ?? '', $env['env'] ?? []);
589
-		}
590
-		if (!is_html_safe($texte_to_check)) {
591
-			$texte = $options['texte_source_affiche'] ?? $texte;
592
-			$texte = preg_replace(",<(/?\w+\b[^>]*>),", "<tt>&lt;\\1</tt>", $texte);
593
-			$texte = str_replace('<', '&lt;', $texte);
594
-			$texte = str_replace('&lt;tt>', '<tt>', $texte);
595
-			$texte = str_replace('&lt;/tt>', '</tt>', $texte);
596
-			if (!function_exists('attribut_html')) {
597
-				include_spip('inc/filtres');
598
-			}
599
-			if (!empty($options['wrap_suspect'])) {
600
-				$texte = wrap($texte, $options['wrap_suspect']);
601
-			}
602
-			$texte = "<mark class='danger-js' title='" . attribut_html(_T('erreur_contenu_suspect')) . "'>⚠️</mark> " . $texte;
603
-		}
604
-
605
-		$texte = $collecteurModeles->retablir($texte);
606
-	}
607
-
608
-	// si on est là dans le public c'est le mode parano
609
-	// on veut donc un rendu propre et secure, et virer silencieusement ce qui est dangereux
610
-	else {
611
-		$collecteurLiens = $collecteurModeles = null;
612
-		if (!empty($options['expanser_liens'])) {
613
-			$texte = expanser_liens($texte, $env['connect'] ?? '', $env['env'] ?? []);
614
-		}
615
-		else {
616
-			include_spip("src/Texte/Collecteur/AbstractCollecteur");
617
-			include_spip("src/Texte/Collecteur/Liens");
618
-			include_spip("src/Texte/Collecteur/Modeles");
619
-
620
-			$collecteurLiens = new Spip\Texte\Collecteur\Liens();
621
-			$texte = $collecteurLiens->echapper($texte, ['sanitize_callback' => 'safehtml']);
622
-
623
-			$collecteurModeles = new Spip\Texte\Collecteur\Modeles();
624
-			$texte = $collecteurModeles->echapper($texte);
625
-		}
626
-		$texte = safehtml($texte);
627
-		if ($collecteurModeles) {
628
-			$texte = $collecteurModeles->retablir($texte);
629
-		}
630
-		if ($collecteurLiens) {
631
-			$texte = $collecteurLiens->retablir($texte);
632
-		}
633
-	}
634
-
635
-	return $texte;
527
+    static $echapper_html_suspect;
528
+    if (!$texte or !is_string($texte)) {
529
+        return $texte;
530
+    }
531
+
532
+    if (!isset($echapper_html_suspect)) {
533
+        $echapper_html_suspect = charger_fonction('echapper_html_suspect', 'inc', true);
534
+    }
535
+    // si fonction personalisee, on delegue
536
+    if ($echapper_html_suspect) {
537
+        // on collecte le tableau d'arg minimal pour ne pas casser un appel a une fonction inc_echapper_html_suspect() selon l'ancienne signature
538
+        $args = [$texte, $options];
539
+        if ($connect or !empty($env)) {
540
+            $args[] = $connect;
541
+        }
542
+        if (!empty($env)) {
543
+            $args[] = $env;
544
+        }
545
+        return $echapper_html_suspect(...$args);
546
+    }
547
+
548
+    if (is_bool($options)) {
549
+        $options = ['strict' => $options];
550
+    }
551
+    $strict = $options['strict'] ?? true;
552
+
553
+    // pas de balise html ou pas d'attribut sur les balises ? c'est OK
554
+    if (
555
+        strpos($texte, '<') === false
556
+        or strpos($texte, '=') === false
557
+    ) {
558
+        return $texte;
559
+    }
560
+
561
+    // dans le prive, on veut afficher tout echappé pour la moderation
562
+    if (!isset($env['espace_prive'])) {
563
+        // conserver le comportement historique en cas d'appel court sans env
564
+        $env['espace_prive'] = test_espace_prive();
565
+    }
566
+    if (!empty($env['espace_prive']) or !empty($env['wysiwyg'])) {
567
+
568
+        // quand c'est du texte qui passe par propre on est plus coulant tant qu'il y a pas d'attribut du type onxxx=
569
+        // car sinon on declenche sur les modeles ou ressources
570
+        if (
571
+            !$strict and
572
+            (strpos($texte, 'on') === false or !preg_match(",<\w+.*\bon\w+\s*=,UimsS", $texte))
573
+        ) {
574
+            return $texte;
575
+        }
576
+
577
+        include_spip("src/Texte/Collecteur/AbstractCollecteur");
578
+        include_spip("src/Texte/Collecteur/Modeles");
579
+        $collecteurModeles = new Spip\Texte\Collecteur\Modeles();
580
+        $texte = $collecteurModeles->echapper($texte);
581
+        $texte = echappe_js($texte);
582
+
583
+        $texte_to_check = $texte;
584
+        // si les raccourcis liens vont etre interprétés, il faut les expanser avant de vérifier que le html est safe
585
+        // car un raccourci peut etre utilisé pour faire un lien malin
586
+        // et un raccourci est potentiellement modifié par safehtml, ce qui fait un faux positif dans is_html_safe
587
+        if (!empty($options['expanser_liens'])) {
588
+            $texte_to_check = expanser_liens($texte_to_check, $env['connect'] ?? '', $env['env'] ?? []);
589
+        }
590
+        if (!is_html_safe($texte_to_check)) {
591
+            $texte = $options['texte_source_affiche'] ?? $texte;
592
+            $texte = preg_replace(",<(/?\w+\b[^>]*>),", "<tt>&lt;\\1</tt>", $texte);
593
+            $texte = str_replace('<', '&lt;', $texte);
594
+            $texte = str_replace('&lt;tt>', '<tt>', $texte);
595
+            $texte = str_replace('&lt;/tt>', '</tt>', $texte);
596
+            if (!function_exists('attribut_html')) {
597
+                include_spip('inc/filtres');
598
+            }
599
+            if (!empty($options['wrap_suspect'])) {
600
+                $texte = wrap($texte, $options['wrap_suspect']);
601
+            }
602
+            $texte = "<mark class='danger-js' title='" . attribut_html(_T('erreur_contenu_suspect')) . "'>⚠️</mark> " . $texte;
603
+        }
604
+
605
+        $texte = $collecteurModeles->retablir($texte);
606
+    }
607
+
608
+    // si on est là dans le public c'est le mode parano
609
+    // on veut donc un rendu propre et secure, et virer silencieusement ce qui est dangereux
610
+    else {
611
+        $collecteurLiens = $collecteurModeles = null;
612
+        if (!empty($options['expanser_liens'])) {
613
+            $texte = expanser_liens($texte, $env['connect'] ?? '', $env['env'] ?? []);
614
+        }
615
+        else {
616
+            include_spip("src/Texte/Collecteur/AbstractCollecteur");
617
+            include_spip("src/Texte/Collecteur/Liens");
618
+            include_spip("src/Texte/Collecteur/Modeles");
619
+
620
+            $collecteurLiens = new Spip\Texte\Collecteur\Liens();
621
+            $texte = $collecteurLiens->echapper($texte, ['sanitize_callback' => 'safehtml']);
622
+
623
+            $collecteurModeles = new Spip\Texte\Collecteur\Modeles();
624
+            $texte = $collecteurModeles->echapper($texte);
625
+        }
626
+        $texte = safehtml($texte);
627
+        if ($collecteurModeles) {
628
+            $texte = $collecteurModeles->retablir($texte);
629
+        }
630
+        if ($collecteurLiens) {
631
+            $texte = $collecteurLiens->retablir($texte);
632
+        }
633
+    }
634
+
635
+    return $texte;
636 636
 }
637 637
 
638 638
 
@@ -653,52 +653,52 @@  discard block
 block discarded – undo
653 653
  *      Texte sécurisé
654 654
  **/
655 655
 function safehtml($t) {
656
-	static $safehtml;
657
-
658
-	if (!$t or !is_string($t)) {
659
-		return $t;
660
-	}
661
-	# attention safehtml nettoie deux ou trois caracteres de plus. A voir
662
-	if (strpos($t, '<') === false) {
663
-		return str_replace("\x00", '', $t);
664
-	}
665
-
666
-	$collecteurIdiomes = null;
667
-	if (stripos($t, '<:') !== false) {
668
-		include_spip("src/Texte/Collecteur/AbstractCollecteur");
669
-		include_spip("src/Texte/Collecteur/Idiomes");
670
-		$collecteurIdiomes = new Spip\Texte\Collecteur\Idiomes();
671
-		$t = $collecteurIdiomes->echapper($t);
672
-	}
673
-	$collecteurMultis = null;
674
-	if (stripos($t, '<multi') !== false) {
675
-		include_spip("src/Texte/Collecteur/AbstractCollecteur");
676
-		include_spip("src/Texte/Collecteur/Multis");
677
-		$collecteurMultis = new Spip\Texte\Collecteur\Multis();
678
-		$t = $collecteurMultis->echapper($t, ['sanitize_callback' => 'safehtml']);
679
-	}
680
-
681
-	if (!function_exists('interdire_scripts')) {
682
-		include_spip('inc/texte');
683
-	}
684
-	$t = interdire_scripts($t); // jolifier le php
685
-	$t = echappe_js($t);
686
-
687
-	if (!isset($safehtml)) {
688
-		$safehtml = charger_fonction('safehtml', 'inc', true);
689
-	}
690
-	if ($safehtml) {
691
-		$t = $safehtml($t);
692
-	}
693
-
694
-	if ($collecteurMultis) {
695
-		$t = $collecteurMultis->retablir($t);
696
-	}
697
-	if ($collecteurIdiomes) {
698
-		$t = $collecteurIdiomes->retablir($t);
699
-	}
700
-
701
-	return interdire_scripts($t); // interdire le php (2 precautions)
656
+    static $safehtml;
657
+
658
+    if (!$t or !is_string($t)) {
659
+        return $t;
660
+    }
661
+    # attention safehtml nettoie deux ou trois caracteres de plus. A voir
662
+    if (strpos($t, '<') === false) {
663
+        return str_replace("\x00", '', $t);
664
+    }
665
+
666
+    $collecteurIdiomes = null;
667
+    if (stripos($t, '<:') !== false) {
668
+        include_spip("src/Texte/Collecteur/AbstractCollecteur");
669
+        include_spip("src/Texte/Collecteur/Idiomes");
670
+        $collecteurIdiomes = new Spip\Texte\Collecteur\Idiomes();
671
+        $t = $collecteurIdiomes->echapper($t);
672
+    }
673
+    $collecteurMultis = null;
674
+    if (stripos($t, '<multi') !== false) {
675
+        include_spip("src/Texte/Collecteur/AbstractCollecteur");
676
+        include_spip("src/Texte/Collecteur/Multis");
677
+        $collecteurMultis = new Spip\Texte\Collecteur\Multis();
678
+        $t = $collecteurMultis->echapper($t, ['sanitize_callback' => 'safehtml']);
679
+    }
680
+
681
+    if (!function_exists('interdire_scripts')) {
682
+        include_spip('inc/texte');
683
+    }
684
+    $t = interdire_scripts($t); // jolifier le php
685
+    $t = echappe_js($t);
686
+
687
+    if (!isset($safehtml)) {
688
+        $safehtml = charger_fonction('safehtml', 'inc', true);
689
+    }
690
+    if ($safehtml) {
691
+        $t = $safehtml($t);
692
+    }
693
+
694
+    if ($collecteurMultis) {
695
+        $t = $collecteurMultis->retablir($t);
696
+    }
697
+    if ($collecteurIdiomes) {
698
+        $t = $collecteurIdiomes->retablir($t);
699
+    }
700
+
701
+    return interdire_scripts($t); // interdire le php (2 precautions)
702 702
 }
703 703
 
704 704
 
@@ -706,25 +706,25 @@  discard block
 block discarded – undo
706 706
  * Detecter si un texte est "safe" ie non modifie significativement par safehtml()
707 707
  */
708 708
 function is_html_safe(string $texte): bool {
709
-	if ($is_html_safe = charger_fonction('is_html_safe', 'inc', true)) {
710
-		return $is_html_safe($texte);
711
-	}
712
-
713
-	// simplifier les retour ligne pour etre certain de ce que l'on compare
714
-	$texte = str_replace("\r\n", "\n", $texte);
715
-	// safehtml reduit aussi potentiellement les &nbsp;
716
-	$texte = str_replace("&nbsp;", " ", $texte);
717
-	// safehtml remplace les entités numériques
718
-	if (strpos($texte, '&#') !== false) {
719
-		$texte = unicode2charset($texte);
720
-	}
721
-
722
-	$texte_safe = safehtml($texte);
723
-
724
-	// on teste sur strlen car safehtml supprime le contenu dangereux
725
-	// mais il peut aussi changer des ' en " sur les attributs html,
726
-	// donc un test d'egalite est trop strict
727
-	return strlen($texte_safe) === strlen($texte);
709
+    if ($is_html_safe = charger_fonction('is_html_safe', 'inc', true)) {
710
+        return $is_html_safe($texte);
711
+    }
712
+
713
+    // simplifier les retour ligne pour etre certain de ce que l'on compare
714
+    $texte = str_replace("\r\n", "\n", $texte);
715
+    // safehtml reduit aussi potentiellement les &nbsp;
716
+    $texte = str_replace("&nbsp;", " ", $texte);
717
+    // safehtml remplace les entités numériques
718
+    if (strpos($texte, '&#') !== false) {
719
+        $texte = unicode2charset($texte);
720
+    }
721
+
722
+    $texte_safe = safehtml($texte);
723
+
724
+    // on teste sur strlen car safehtml supprime le contenu dangereux
725
+    // mais il peut aussi changer des ' en " sur les attributs html,
726
+    // donc un test d'egalite est trop strict
727
+    return strlen($texte_safe) === strlen($texte);
728 728
 }
729 729
 
730 730
 /**
@@ -745,13 +745,13 @@  discard block
 block discarded – undo
745 745
  *     Texte sans les modèles d'image
746 746
  **/
747 747
 function supprime_img($letexte, $message = null) {
748
-	if ($message === null) {
749
-		$message = '(' . _T('img_indisponible') . ')';
750
-	}
751
-
752
-	return preg_replace(
753
-		',<(img|doc|emb)([0-9]+)(\|([^>]*))?' . '\s*/?' . '>,i',
754
-		$message,
755
-		$letexte
756
-	);
748
+    if ($message === null) {
749
+        $message = '(' . _T('img_indisponible') . ')';
750
+    }
751
+
752
+    return preg_replace(
753
+        ',<(img|doc|emb)([0-9]+)(\|([^>]*))?' . '\s*/?' . '>,i',
754
+        $message,
755
+        $letexte
756
+    );
757 757
 }
Please login to merge, or discard this patch.
Spacing   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -44,13 +44,13 @@  discard block
 block discarded – undo
44 44
 	// celle du texte) et public (spip_lang est la langue du texte)
45 45
 	$dir = _DIR_RESTREINT ? lang_dir() : lang_dir($GLOBALS['spip_lang']);
46 46
 
47
-	$p = 'puce' . (test_espace_prive() ? '_prive' : '');
47
+	$p = 'puce'.(test_espace_prive() ? '_prive' : '');
48 48
 	if ($dir == 'rtl') {
49 49
 		$p .= '_rtl';
50 50
 	}
51 51
 
52 52
 	if (!isset($GLOBALS[$p])) {
53
-		$GLOBALS[$p] = '<span class="spip-puce ' . $dir . '"><b>–</b></span>';
53
+		$GLOBALS[$p] = '<span class="spip-puce '.$dir.'"><b>–</b></span>';
54 54
 	}
55 55
 
56 56
 	return $GLOBALS[$p];
@@ -68,12 +68,12 @@  discard block
 block discarded – undo
68 68
 function spip_balisage_code(string $corps, bool $bloc = false, string $attributs = '', string $langage = '') {
69 69
 
70 70
 	$echap = spip_htmlspecialchars($corps); // il ne faut pas passer dans entites_html, ne pas transformer les &#xxx; du code !
71
-	$class = "spip_code " . ($bloc ? 'spip_code_block' : 'spip_code_inline');
71
+	$class = "spip_code ".($bloc ? 'spip_code_block' : 'spip_code_inline');
72 72
 	if ($langage) {
73 73
 		$class .= " language-$langage";
74 74
 	}
75 75
 	if ($attributs) {
76
-		$attributs = " " . trim($attributs);
76
+		$attributs = " ".trim($attributs);
77 77
 	}
78 78
 	if ($bloc) {
79 79
 		$html = "<div class=\"precode\">"
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
 	else {
88 88
 		$echap = str_replace("\t", "&nbsp; &nbsp; &nbsp; &nbsp; ", $echap);
89 89
 		$echap = str_replace("  ", " &nbsp;", $echap);
90
-		$html = "<code class=\"$class\" dir=\"ltr\"$attributs>" . $echap . '</code>';
90
+		$html = "<code class=\"$class\" dir=\"ltr\"$attributs>".$echap.'</code>';
91 91
 	}
92 92
 
93 93
 	return $html;
@@ -105,7 +105,7 @@  discard block
 block discarded – undo
105 105
 }
106 106
 
107 107
 if (!defined('_BALISES_BLOCS_REGEXP')) {
108
-	define('_BALISES_BLOCS_REGEXP', ',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS');
108
+	define('_BALISES_BLOCS_REGEXP', ',</?('._BALISES_BLOCS.')[>[:space:]],iS');
109 109
 }
110 110
 
111 111
 //
@@ -122,7 +122,7 @@  discard block
 block discarded – undo
122 122
 
123 123
 	// Tester si on echappe en span ou en div
124 124
 	if (is_null($mode) or !in_array($mode, ['div', 'span'])) {
125
-		$mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $rempl) ? 'div' : 'span';
125
+		$mode = preg_match(',</?('._BALISES_BLOCS.')[>[:space:]],iS', $rempl) ? 'div' : 'span';
126 126
 	}
127 127
 
128 128
 	// Decouper en morceaux, base64 a des probleme selon la taille de la pile
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
 	) {
158 158
 		foreach ($matches as $m) {
159 159
 			if ($m[1] === 'code') {
160
-				$code = '<code' . $m[2] . '>' . spip_htmlspecialchars($m[3]) . '</code>';
160
+				$code = '<code'.$m[2].'>'.spip_htmlspecialchars($m[3]).'</code>';
161 161
 				$pre = str_replace($m[0], $code, $pre);
162 162
 			}
163 163
 		}
@@ -167,7 +167,7 @@  discard block
 block discarded – undo
167 167
 
168 168
 // Echapper les <code>...</ code>
169 169
 function traiter_echap_code_dist($regs, $options = []) {
170
-	[, , $att, $corps] = $regs;
170
+	[,, $att, $corps] = $regs;
171 171
 
172 172
 	// ne pas mettre le <div...> s'il n'y a qu'une ligne
173 173
 	if (strpos($corps, "\n") !== false) {
@@ -251,11 +251,11 @@  discard block
 block discarded – undo
251 251
 			else {
252 252
 				$callback_secure_prefix = ($callback_options['secure_prefix'] ?? '');
253 253
 				if (
254
-					function_exists($f = $callback_prefix . $callback_secure_prefix . 'traiter_echap_' . strtolower($regs[1]))
255
-					or function_exists($f = $f . '_dist')
254
+					function_exists($f = $callback_prefix.$callback_secure_prefix.'traiter_echap_'.strtolower($regs[1]))
255
+					or function_exists($f = $f.'_dist')
256 256
 					or ($callback_secure_prefix and (
257
-						function_exists($f = $callback_prefix . 'traiter_echap_' . strtolower($regs[1]))
258
-						or function_exists($f = $f . '_dist')
257
+						function_exists($f = $callback_prefix.'traiter_echap_'.strtolower($regs[1]))
258
+						or function_exists($f = $f.'_dist')
259 259
 					))
260 260
 				) {
261 261
 					$echap = $f($regs, $callback_options);
@@ -277,7 +277,7 @@  discard block
 block discarded – undo
277 277
 	// dans une callback autonommee
278 278
 	if (strpos($preg ?: _PROTEGE_BLOCS, 'script') !== false) {
279 279
 		if (
280
-			strpos($letexte, '<' . '?') !== false and preg_match_all(
280
+			strpos($letexte, '<'.'?') !== false and preg_match_all(
281 281
 				',<[?].*($|[?]>),UisS',
282 282
 				$letexte,
283 283
 				$matches,
@@ -309,7 +309,7 @@  discard block
 block discarded – undo
309 309
 			strpos($letexte, '<') !== false
310 310
 			and
311 311
 			preg_match_all(
312
-				',<(span|div)\sclass=[\'"]base64' . $source . '[\'"]\s(.*)>\s*</\1>,UmsS',
312
+				',<(span|div)\sclass=[\'"]base64'.$source.'[\'"]\s(.*)>\s*</\1>,UmsS',
313 313
 				$letexte,
314 314
 				$regs,
315 315
 				PREG_SET_ORDER
@@ -326,7 +326,7 @@  discard block
 block discarded – undo
326 326
 					}
327 327
 				}
328 328
 				if ($at) {
329
-					$rempl = '<' . $reg[1] . '>' . $rempl . '</' . $reg[1] . '>';
329
+					$rempl = '<'.$reg[1].'>'.$rempl.'</'.$reg[1].'>';
330 330
 					foreach ($at as $attr => $a) {
331 331
 						$rempl = inserer_attribut($rempl, $attr, $a);
332 332
 					}
@@ -407,8 +407,8 @@  discard block
 block discarded – undo
407 407
 	$texte = nettoyer_raccourcis_typo($texte);
408 408
 
409 409
 	// balises de sauts de ligne et paragraphe
410
-	$texte = preg_replace('/<p( [^>]*)?' . '>/', "\r", $texte);
411
-	$texte = preg_replace('/<br( [^>]*)?' . '>/', "\n", $texte);
410
+	$texte = preg_replace('/<p( [^>]*)?'.'>/', "\r", $texte);
411
+	$texte = preg_replace('/<br( [^>]*)?'.'>/', "\n", $texte);
412 412
 
413 413
 	// on repasse les doubles \n en \r que nettoyer_raccourcis_typo() a pu modifier
414 414
 	$texte = str_replace("\n\n", "\r", $texte);
@@ -416,7 +416,7 @@  discard block
 block discarded – undo
416 416
 	// supprimer les tags
417 417
 	$texte = supprimer_tags($texte);
418 418
 	$texte = trim(str_replace("\n", ' ', $texte));
419
-	$texte .= "\n";  // marquer la fin
419
+	$texte .= "\n"; // marquer la fin
420 420
 
421 421
 	// corriger la longueur de coupe
422 422
 	// en fonction de la presence de caracteres utf
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
 	// couper au mot precedent
432 432
 	$long = spip_substr($texte, 0, max($taille - 4, 1));
433 433
 	$u = $GLOBALS['meta']['pcre_u'];
434
-	$court = preg_replace("/([^\s][\s]+)[^\s]*\n?$/" . $u, "\\1", $long);
434
+	$court = preg_replace("/([^\s][\s]+)[^\s]*\n?$/".$u, "\\1", $long);
435 435
 	if (is_null($suite)) {
436 436
 		$suite = (defined('_COUPER_SUITE') ? _COUPER_SUITE : '&nbsp;(...)');
437 437
 	}
@@ -441,7 +441,7 @@  discard block
 block discarded – undo
441 441
 	if (spip_strlen($court) < max(0.75 * $taille, 2)) {
442 442
 		$points = '';
443 443
 		$long = spip_substr($texte, 0, $taille);
444
-		$texte = preg_replace("/([^\s][\s]+)[^\s]*\n?$/" . $u, "\\1", $long);
444
+		$texte = preg_replace("/([^\s][\s]+)[^\s]*\n?$/".$u, "\\1", $long);
445 445
 		// encore trop court ? couper au caractere
446 446
 		if (spip_strlen($texte) < 0.75 * $taille) {
447 447
 			$texte = $long;
@@ -460,7 +460,7 @@  discard block
 block discarded – undo
460 460
 	// supprimer l'eventuelle entite finale mal coupee
461 461
 	$texte = preg_replace('/&#?[a-z0-9]*$/S', '', $texte);
462 462
 
463
-	return quote_amp(trim($texte)) . $points;
463
+	return quote_amp(trim($texte)).$points;
464 464
 }
465 465
 
466 466
 
@@ -472,16 +472,16 @@  discard block
 block discarded – undo
472 472
 				define('_PROTEGE_JS_MODELES', creer_uniqid());
473 473
 			}
474 474
 			foreach ($r as $regs) {
475
-				$t = str_replace($regs[0], code_echappement($regs[0], 'javascript' . _PROTEGE_JS_MODELES), $t);
475
+				$t = str_replace($regs[0], code_echappement($regs[0], 'javascript'._PROTEGE_JS_MODELES), $t);
476 476
 			}
477 477
 		}
478
-		if (preg_match_all(',<\?php.*?($|\?' . '>),isS', $t, $r, PREG_SET_ORDER)) {
478
+		if (preg_match_all(',<\?php.*?($|\?'.'>),isS', $t, $r, PREG_SET_ORDER)) {
479 479
 			if (!defined('_PROTEGE_PHP_MODELES')) {
480 480
 				include_spip('inc/acces');
481 481
 				define('_PROTEGE_PHP_MODELES', creer_uniqid());
482 482
 			}
483 483
 			foreach ($r as $regs) {
484
-				$t = str_replace($regs[0], code_echappement($regs[0], 'php' . _PROTEGE_PHP_MODELES), $t);
484
+				$t = str_replace($regs[0], code_echappement($regs[0], 'php'._PROTEGE_PHP_MODELES), $t);
485 485
 			}
486 486
 		}
487 487
 	}
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
 			if (!empty($options['wrap_suspect'])) {
600 600
 				$texte = wrap($texte, $options['wrap_suspect']);
601 601
 			}
602
-			$texte = "<mark class='danger-js' title='" . attribut_html(_T('erreur_contenu_suspect')) . "'>⚠️</mark> " . $texte;
602
+			$texte = "<mark class='danger-js' title='".attribut_html(_T('erreur_contenu_suspect'))."'>⚠️</mark> ".$texte;
603 603
 		}
604 604
 
605 605
 		$texte = $collecteurModeles->retablir($texte);
@@ -746,11 +746,11 @@  discard block
 block discarded – undo
746 746
  **/
747 747
 function supprime_img($letexte, $message = null) {
748 748
 	if ($message === null) {
749
-		$message = '(' . _T('img_indisponible') . ')';
749
+		$message = '('._T('img_indisponible').')';
750 750
 	}
751 751
 
752 752
 	return preg_replace(
753
-		',<(img|doc|emb)([0-9]+)(\|([^>]*))?' . '\s*/?' . '>,i',
753
+		',<(img|doc|emb)([0-9]+)(\|([^>]*))?'.'\s*/?'.'>,i',
754 754
 		$message,
755 755
 		$letexte
756 756
 	);
Please login to merge, or discard this patch.
Braces   +2 added lines, -4 removed lines patch added patch discarded remove patch
@@ -83,8 +83,7 @@  discard block
 block discarded – undo
83 83
 		  . '</code>'
84 84
 		  . '</pre>'
85 85
 		  . '</div>';
86
-	}
87
-	else {
86
+	} else {
88 87
 		$echap = str_replace("\t", "&nbsp; &nbsp; &nbsp; &nbsp; ", $echap);
89 88
 		$echap = str_replace("  ", " &nbsp;", $echap);
90 89
 		$html = "<code class=\"$class\" dir=\"ltr\"$attributs>" . $echap . '</code>';
@@ -611,8 +610,7 @@  discard block
 block discarded – undo
611 610
 		$collecteurLiens = $collecteurModeles = null;
612 611
 		if (!empty($options['expanser_liens'])) {
613 612
 			$texte = expanser_liens($texte, $env['connect'] ?? '', $env['env'] ?? []);
614
-		}
615
-		else {
613
+		} else {
616 614
 			include_spip("src/Texte/Collecteur/AbstractCollecteur");
617 615
 			include_spip("src/Texte/Collecteur/Liens");
618 616
 			include_spip("src/Texte/Collecteur/Modeles");
Please login to merge, or discard this patch.