Completed
Push — master ( 0528ed...3f7b24 )
by cam
01:54
created
ecrire/typographie/fr.php 1 patch
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -10,73 +10,73 @@
 block discarded – undo
10 10
 \***************************************************************************/
11 11
 
12 12
 if (!defined('_ECRIRE_INC_VERSION')) {
13
-	return;
13
+    return;
14 14
 }
15 15
 
16 16
 // Correction typographique francaise
17 17
 
18 18
 function typographie_fr_dist($letexte) {
19 19
 
20
-	static $trans;
20
+    static $trans;
21 21
 
22
-	// Nettoyer 160 = nbsp ; 187 = raquo ; 171 = laquo ; 176 = deg ;
23
-	// 147 = ldquo; 148 = rdquo; ' = zouli apostrophe
24
-	if (!$trans) {
25
-		$trans = [
26
-			"'" => '’',
27
-			' ' => '~',
28
-			'»' => '»',
29
-			'«' => '«',
30
-			'”' => '”',
31
-			'“' => '“',
32
-			'°' => '°'
33
-		];
34
-		$chars = [160 => '~', 187 => '»', 171 => '«', 148 => '”', 147 => '“', 176 => '°'];
35
-		$chars_trans = array_keys($chars);
36
-		$chars = array_values($chars);
37
-		$chars_trans = implode(' ', array_map('chr', $chars_trans));
38
-		$chars_trans = unicode2charset(charset2unicode($chars_trans, 'iso-8859-1'));
39
-		$chars_trans = explode(' ', (string) $chars_trans);
40
-		foreach ($chars as $k => $r) {
41
-			$trans[$chars_trans[$k]] = $r;
42
-		}
43
-	}
22
+    // Nettoyer 160 = nbsp ; 187 = raquo ; 171 = laquo ; 176 = deg ;
23
+    // 147 = ldquo; 148 = rdquo; ' = zouli apostrophe
24
+    if (!$trans) {
25
+        $trans = [
26
+            "'" => '’',
27
+            ' ' => '~',
28
+            '»' => '»',
29
+            '«' => '«',
30
+            '”' => '”',
31
+            '“' => '“',
32
+            '°' => '°'
33
+        ];
34
+        $chars = [160 => '~', 187 => '»', 171 => '«', 148 => '”', 147 => '“', 176 => '°'];
35
+        $chars_trans = array_keys($chars);
36
+        $chars = array_values($chars);
37
+        $chars_trans = implode(' ', array_map('chr', $chars_trans));
38
+        $chars_trans = unicode2charset(charset2unicode($chars_trans, 'iso-8859-1'));
39
+        $chars_trans = explode(' ', (string) $chars_trans);
40
+        foreach ($chars as $k => $r) {
41
+            $trans[$chars_trans[$k]] = $r;
42
+        }
43
+    }
44 44
 
45
-	$letexte = strtr($letexte, $trans);
45
+    $letexte = strtr($letexte, $trans);
46 46
 
47
-	$cherche1 = [
48
-		/* 1 */
49
-		'/((?:^|[^\#0-9a-zA-Z\&])[\#0-9a-zA-Z]*)\;/S',
50
-		/* 2 */
51
-		'/»| --?,|(?::(?!:)| %)(?:\W|$)/S',
52
-		/* 3 */
53
-		'/([^[<(!?.])([!?][!?\.]*)/iS',
54
-		/* 4 */
55
-		'/&#171;|(?:M(?:M?\.|mes?|r\.?)|[MnN]&#176;) /S'
56
-	];
57
-	$remplace1 = [
58
-		/* 1 */
59
-		'\1~;',
60
-		/* 2 */
61
-		'~\0',
62
-		/* 3 */
63
-		'\1~\2',
64
-		/* 4 */
65
-		'\0~'
66
-	];
67
-	$letexte = preg_replace($cherche1, $remplace1, $letexte);
68
-	$letexte = preg_replace('/ *~+ */S', '~', $letexte);
47
+    $cherche1 = [
48
+        /* 1 */
49
+        '/((?:^|[^\#0-9a-zA-Z\&])[\#0-9a-zA-Z]*)\;/S',
50
+        /* 2 */
51
+        '/&#187;| --?,|(?::(?!:)| %)(?:\W|$)/S',
52
+        /* 3 */
53
+        '/([^[<(!?.])([!?][!?\.]*)/iS',
54
+        /* 4 */
55
+        '/&#171;|(?:M(?:M?\.|mes?|r\.?)|[MnN]&#176;) /S'
56
+    ];
57
+    $remplace1 = [
58
+        /* 1 */
59
+        '\1~;',
60
+        /* 2 */
61
+        '~\0',
62
+        /* 3 */
63
+        '\1~\2',
64
+        /* 4 */
65
+        '\0~'
66
+    ];
67
+    $letexte = preg_replace($cherche1, $remplace1, $letexte);
68
+    $letexte = preg_replace('/ *~+ */S', '~', $letexte);
69 69
 
70
-	$cherche2 = [
71
-		'/([^-\n]|^)--([^-]|$)/S',
72
-		',(' . _PROTOCOLES_STD . ')~((://[^"\'\s\[\]\}\)<>]+)~([?]))?,S',
73
-		'/~/'
74
-	];
75
-	$remplace2 = [
76
-		'\1&mdash;\2',
77
-		'\1\3\4',
78
-		'&nbsp;'
79
-	];
70
+    $cherche2 = [
71
+        '/([^-\n]|^)--([^-]|$)/S',
72
+        ',(' . _PROTOCOLES_STD . ')~((://[^"\'\s\[\]\}\)<>]+)~([?]))?,S',
73
+        '/~/'
74
+    ];
75
+    $remplace2 = [
76
+        '\1&mdash;\2',
77
+        '\1\3\4',
78
+        '&nbsp;'
79
+    ];
80 80
 
81
-	return preg_replace($cherche2, $remplace2, $letexte);
81
+    return preg_replace($cherche2, $remplace2, $letexte);
82 82
 }
Please login to merge, or discard this patch.
ecrire/src/Afficher/Minipage/AbstractPage.php 1 patch
Indentation   +236 added lines, -236 removed lines patch added patch discarded remove patch
@@ -15,265 +15,265 @@
 block discarded – undo
15 15
  * Présentation des pages simplifiées
16 16
  **/
17 17
 abstract class AbstractPage {
18
-	public const TYPE = '';
18
+    public const TYPE = '';
19 19
 
20
-	public function __construct() {
21
-		include_fichiers_fonctions();
22
-		include_spip('inc/headers');
23
-		include_spip('inc/texte'); //inclue inc/lang et inc/filtres
24
-		include_spip('inc/filtres_images_mini');
25
-	}
20
+    public function __construct() {
21
+        include_fichiers_fonctions();
22
+        include_spip('inc/headers');
23
+        include_spip('inc/texte'); //inclue inc/lang et inc/filtres
24
+        include_spip('inc/filtres_images_mini');
25
+    }
26 26
 
27
-	/**
28
-	 * Retourne le début d'une page HTML minimale
29
-	 *
30
-	 * Le contenu de CSS minimales (reset.css, clear.css, minipage.css) est inséré
31
-	 * dans une balise script inline (compactée si possible)
32
-	 *
33
-	 * @param array $options
34
-	 *   string $lang : forcer la langue utilisateur
35
-	 *   string $page_title : titre éventuel de la page (nom du site par défaut)
36
-	 *   string $couleur_fond : pour la couleur dominante de la page (par défaut on reprend le réglage de la page de login)
37
-	 *   bool $all_inline : inliner les CSS pour envoyer toute la page en 1 hit
38
-	 *   string $doctype
39
-	 *   string $charset
40
-	 *   string $onload
41
-	 *   array $css_files : ajouter des fichiers css
42
-	 *   string $css : ajouter du CSS inline
43
-	 *   string $head : contenu à ajouter à la fin <head> (pour inclusion de JS ou JS inline...)
44
-	 * @return string
45
-	 *    Code HTML
46
-	 *
47
-	 * @uses html_lang_attributes()
48
-	 * @uses minifier() si le plugin compresseur est présent
49
-	 * @uses url_absolue_css()
50
-	 *
51
-	 * @uses utiliser_langue_visiteur()
52
-	 * @uses http_no_cache()
53
-	 */
54
-	protected function ouvreBody($options = []) {
55
-		$h = null;
56
-		$s = null;
57
-		$l = null;
58
-		if (empty($options['lang'])) {
59
-			// on se limite sur une langue de $GLOBALS['meta']['langues_multilingue'] car on est dans le public
60
-			utiliser_langue_visiteur($GLOBALS['meta']['langues_multilingue'] ?? null);
61
-		} else {
62
-			changer_langue($options['lang']);
63
-		}
64
-		http_no_cache();
27
+    /**
28
+     * Retourne le début d'une page HTML minimale
29
+     *
30
+     * Le contenu de CSS minimales (reset.css, clear.css, minipage.css) est inséré
31
+     * dans une balise script inline (compactée si possible)
32
+     *
33
+     * @param array $options
34
+     *   string $lang : forcer la langue utilisateur
35
+     *   string $page_title : titre éventuel de la page (nom du site par défaut)
36
+     *   string $couleur_fond : pour la couleur dominante de la page (par défaut on reprend le réglage de la page de login)
37
+     *   bool $all_inline : inliner les CSS pour envoyer toute la page en 1 hit
38
+     *   string $doctype
39
+     *   string $charset
40
+     *   string $onload
41
+     *   array $css_files : ajouter des fichiers css
42
+     *   string $css : ajouter du CSS inline
43
+     *   string $head : contenu à ajouter à la fin <head> (pour inclusion de JS ou JS inline...)
44
+     * @return string
45
+     *    Code HTML
46
+     *
47
+     * @uses html_lang_attributes()
48
+     * @uses minifier() si le plugin compresseur est présent
49
+     * @uses url_absolue_css()
50
+     *
51
+     * @uses utiliser_langue_visiteur()
52
+     * @uses http_no_cache()
53
+     */
54
+    protected function ouvreBody($options = []) {
55
+        $h = null;
56
+        $s = null;
57
+        $l = null;
58
+        if (empty($options['lang'])) {
59
+            // on se limite sur une langue de $GLOBALS['meta']['langues_multilingue'] car on est dans le public
60
+            utiliser_langue_visiteur($GLOBALS['meta']['langues_multilingue'] ?? null);
61
+        } else {
62
+            changer_langue($options['lang']);
63
+        }
64
+        http_no_cache();
65 65
 
66
-		$page_title = ($options['page_title'] ?? $GLOBALS['meta']['nom_site']);
67
-		$doctype = ($options['doctype'] ?? '<!DOCTYPE html>');
68
-		$doctype = trim((string) $doctype) . "\n";
69
-		$charset = ($options['charset'] ?? 'utf-8');
70
-		$all_inline = ($options['all_inline'] ?? true);
71
-		$onLoad = ($options['onLoad'] ?? '');
72
-		if ($onLoad) {
73
-			$onLoad = ' onload="' . attribut_html($onLoad) . '"';
74
-		}
66
+        $page_title = ($options['page_title'] ?? $GLOBALS['meta']['nom_site']);
67
+        $doctype = ($options['doctype'] ?? '<!DOCTYPE html>');
68
+        $doctype = trim((string) $doctype) . "\n";
69
+        $charset = ($options['charset'] ?? 'utf-8');
70
+        $all_inline = ($options['all_inline'] ?? true);
71
+        $onLoad = ($options['onLoad'] ?? '');
72
+        if ($onLoad) {
73
+            $onLoad = ' onload="' . attribut_html($onLoad) . '"';
74
+        }
75 75
 
76
-		# envoyer le charset
77
-		if (!headers_sent()) {
78
-			header('Content-Type: text/html; charset=' . $charset);
79
-		}
76
+        # envoyer le charset
77
+        if (!headers_sent()) {
78
+            header('Content-Type: text/html; charset=' . $charset);
79
+        }
80 80
 
81
-		$css = '';
81
+        $css = '';
82 82
 
83
-		if (function_exists('couleur_hex_to_hsl')) {
84
-			$couleur_fond = empty($options['couleur_fond'])
85
-				? lire_config('couleur_login', '#db1762')
86
-				: $options['couleur_fond'];
87
-			$h = couleur_hex_to_hsl($couleur_fond, 'h');
88
-			$s = couleur_hex_to_hsl($couleur_fond, 's');
89
-			$l = couleur_hex_to_hsl($couleur_fond, 'l');
90
-		}
83
+        if (function_exists('couleur_hex_to_hsl')) {
84
+            $couleur_fond = empty($options['couleur_fond'])
85
+                ? lire_config('couleur_login', '#db1762')
86
+                : $options['couleur_fond'];
87
+            $h = couleur_hex_to_hsl($couleur_fond, 'h');
88
+            $s = couleur_hex_to_hsl($couleur_fond, 's');
89
+            $l = couleur_hex_to_hsl($couleur_fond, 'l');
90
+        }
91 91
 
92
-		$inline = ':root {'
93
-			. "--minipage-color-theme--h: $h;"
94
-			. "--minipage-color-theme--s: $s;"
95
-			. "--minipage-color-theme--l: $l;}";
96
-		$vars = file_get_contents(find_in_theme('minipage.vars.css'));
97
-		$inline .= "\n" . trim($vars);
98
-		if (function_exists('minifier')) {
99
-			$inline = minifier($inline, 'css');
100
-		}
101
-		$files = [
102
-			find_in_theme('reset.css'),
103
-			find_in_theme('clear.css'),
104
-			find_in_theme('minipage.css'),
105
-		];
106
-		if (!empty($options['css_files'])) {
107
-			foreach ($options['css_files'] as $css_file) {
108
-				$files[] = $css_file;
109
-			}
110
-		}
111
-		if ($all_inline) {
112
-			// inliner les CSS (optimisation de la page minipage qui passe en un seul hit a la demande)
113
-			foreach ($files as $name) {
114
-				$file = direction_css($name);
115
-				if (function_exists('minifier')) {
116
-					$file = minifier($file);
117
-				} else {
118
-					$file = url_absolue_css($file); // precaution
119
-				}
120
-				$css .= file_get_contents($file);
121
-			}
122
-			$css = "$inline\n$css";
123
-			if (!empty($options['css'])) {
124
-				$css .= "\n" . $options['css'];
125
-			}
126
-			$css = "<style type='text/css'>$css</style>";
127
-		} else {
128
-			$css = "<style type='text/css'>$inline</style>";
129
-			foreach ($files as $name) {
130
-				$file = timestamp(direction_css($name));
131
-				$css .= "<link rel='stylesheet' href='" . attribut_html($file) . "' type='text/css' />\n";
132
-			}
133
-			if (!empty($options['css'])) {
134
-				$css .= "<style type='text/css'>" . $options['css'] . '</style>';
135
-			}
136
-		}
92
+        $inline = ':root {'
93
+            . "--minipage-color-theme--h: $h;"
94
+            . "--minipage-color-theme--s: $s;"
95
+            . "--minipage-color-theme--l: $l;}";
96
+        $vars = file_get_contents(find_in_theme('minipage.vars.css'));
97
+        $inline .= "\n" . trim($vars);
98
+        if (function_exists('minifier')) {
99
+            $inline = minifier($inline, 'css');
100
+        }
101
+        $files = [
102
+            find_in_theme('reset.css'),
103
+            find_in_theme('clear.css'),
104
+            find_in_theme('minipage.css'),
105
+        ];
106
+        if (!empty($options['css_files'])) {
107
+            foreach ($options['css_files'] as $css_file) {
108
+                $files[] = $css_file;
109
+            }
110
+        }
111
+        if ($all_inline) {
112
+            // inliner les CSS (optimisation de la page minipage qui passe en un seul hit a la demande)
113
+            foreach ($files as $name) {
114
+                $file = direction_css($name);
115
+                if (function_exists('minifier')) {
116
+                    $file = minifier($file);
117
+                } else {
118
+                    $file = url_absolue_css($file); // precaution
119
+                }
120
+                $css .= file_get_contents($file);
121
+            }
122
+            $css = "$inline\n$css";
123
+            if (!empty($options['css'])) {
124
+                $css .= "\n" . $options['css'];
125
+            }
126
+            $css = "<style type='text/css'>$css</style>";
127
+        } else {
128
+            $css = "<style type='text/css'>$inline</style>";
129
+            foreach ($files as $name) {
130
+                $file = timestamp(direction_css($name));
131
+                $css .= "<link rel='stylesheet' href='" . attribut_html($file) . "' type='text/css' />\n";
132
+            }
133
+            if (!empty($options['css'])) {
134
+                $css .= "<style type='text/css'>" . $options['css'] . '</style>';
135
+            }
136
+        }
137 137
 
138
-		return $doctype .
139
-			html_lang_attributes() .
140
-			"<head>\n" .
141
-			'<title>' .
142
-			textebrut($page_title) .
143
-			"</title>\n" .
144
-			"<meta name=\"viewport\" content=\"width=device-width\" />\n" .
145
-			$css .
146
-			(empty($options['head']) ? '' : $options['head']) .
147
-			"</head>\n" .
148
-			"<body{$onLoad} class=\"minipage" . ($this::TYPE ? ' minipage--' . $this::TYPE : '') . "\">\n" .
149
-			"\t<div class=\"minipage-bloc\">\n";
150
-	}
138
+        return $doctype .
139
+            html_lang_attributes() .
140
+            "<head>\n" .
141
+            '<title>' .
142
+            textebrut($page_title) .
143
+            "</title>\n" .
144
+            "<meta name=\"viewport\" content=\"width=device-width\" />\n" .
145
+            $css .
146
+            (empty($options['head']) ? '' : $options['head']) .
147
+            "</head>\n" .
148
+            "<body{$onLoad} class=\"minipage" . ($this::TYPE ? ' minipage--' . $this::TYPE : '') . "\">\n" .
149
+            "\t<div class=\"minipage-bloc\">\n";
150
+    }
151 151
 
152
-	/**
153
-	 * Ouvre le corps : affiche le header avec un éventuel titre + ouvre le div corps
154
-	 * @param array options
155
-	 * @return string
156
-	 */
157
-	protected function ouvreCorps($options = []) {
158
-		$url_site = url_de_base();
159
-		$header = "<header>\n" .
160
-			'<h1><a href="' . attribut_html($url_site) . '">' . interdire_scripts($GLOBALS['meta']['nom_site'] ?? '') . "</a></h1>\n";
152
+    /**
153
+     * Ouvre le corps : affiche le header avec un éventuel titre + ouvre le div corps
154
+     * @param array options
155
+     * @return string
156
+     */
157
+    protected function ouvreCorps($options = []) {
158
+        $url_site = url_de_base();
159
+        $header = "<header>\n" .
160
+            '<h1><a href="' . attribut_html($url_site) . '">' . interdire_scripts($GLOBALS['meta']['nom_site'] ?? '') . "</a></h1>\n";
161 161
 
162
-		$titre = ($options['titre'] ?? '');
163
-		if ($titre) {
164
-			$header .= '<h2>' . interdire_scripts($titre) . '</h2>';
165
-		}
166
-		$header .= '</header>';
162
+        $titre = ($options['titre'] ?? '');
163
+        if ($titre) {
164
+            $header .= '<h2>' . interdire_scripts($titre) . '</h2>';
165
+        }
166
+        $header .= '</header>';
167 167
 
168
-		return $header . "<div class='corps'>\n";
169
-	}
168
+        return $header . "<div class='corps'>\n";
169
+    }
170 170
 
171
-	/**
172
-	 * Ferme le corps : affiche le footer par défaut ou custom et ferme le div corps
173
-	 * @param array $options
174
-	 * @return string
175
-	 */
176
-	protected function fermeCorps($options = []) {
177
-		$url_site = url_de_base();
171
+    /**
172
+     * Ferme le corps : affiche le footer par défaut ou custom et ferme le div corps
173
+     * @param array $options
174
+     * @return string
175
+     */
176
+    protected function fermeCorps($options = []) {
177
+        $url_site = url_de_base();
178 178
 
179
-		if (isset($options['footer'])) {
180
-			$footer = $options['footer'];
181
-		} else {
182
-			$footer = '<a href="' . attribut_html($url_site) . '">' . _T('retour') . "</a>\n";
183
-		}
184
-		if (!empty($footer)) {
185
-			$footer = "<footer>\n{$footer}</footer>";
186
-		}
179
+        if (isset($options['footer'])) {
180
+            $footer = $options['footer'];
181
+        } else {
182
+            $footer = '<a href="' . attribut_html($url_site) . '">' . _T('retour') . "</a>\n";
183
+        }
184
+        if (!empty($footer)) {
185
+            $footer = "<footer>\n{$footer}</footer>";
186
+        }
187 187
 
188
-		return "</div>\n" . $footer;
189
-	}
188
+        return "</div>\n" . $footer;
189
+    }
190 190
 
191 191
 
192
-	/**
193
-	 * Retourne la fin d'une page HTML minimale
194
-	 *
195
-	 * @return string Code HTML
196
-	 */
197
-	protected function fermeBody() {
198
-		return "\n\t</div>\n</body>\n</html>";
199
-	}
192
+    /**
193
+     * Retourne la fin d'une page HTML minimale
194
+     *
195
+     * @return string Code HTML
196
+     */
197
+    protected function fermeBody() {
198
+        return "\n\t</div>\n</body>\n</html>";
199
+    }
200 200
 
201 201
 
202
-	/**
203
-	 * Retourne une page HTML contenant, dans une présentation minimale,
204
-	 * le contenu transmis dans `$corps`.
205
-	 *
206
-	 * Appelée pour afficher un message ou une demande de confirmation simple et rapide
207
-	 *
208
-	 * @param string $corps
209
-	 *   Corps de la page
210
-	 * @param array $options
211
-	 * @return string
212
-	 *   HTML de la page
213
-	 * @see  ouvreBody()
214
-	 * @see  ouvreCorps()
215
-	 *   string $titre : Titre à l'affichage (différent de $page_title)
216
-	 *   int $status : status de la page
217
-	 *   string $footer : pied de la box en remplacement du bouton retour par défaut
218
-	 * @uses ouvreBody()
219
-	 * @uses ouvreCorps()
220
-	 * @uses fermeCorps()
221
-	 * @uses fermeBody()
222
-	 *
223
-	 */
224
-	public function page($corps, $options = []) {
202
+    /**
203
+     * Retourne une page HTML contenant, dans une présentation minimale,
204
+     * le contenu transmis dans `$corps`.
205
+     *
206
+     * Appelée pour afficher un message ou une demande de confirmation simple et rapide
207
+     *
208
+     * @param string $corps
209
+     *   Corps de la page
210
+     * @param array $options
211
+     * @return string
212
+     *   HTML de la page
213
+     * @see  ouvreBody()
214
+     * @see  ouvreCorps()
215
+     *   string $titre : Titre à l'affichage (différent de $page_title)
216
+     *   int $status : status de la page
217
+     *   string $footer : pied de la box en remplacement du bouton retour par défaut
218
+     * @uses ouvreBody()
219
+     * @uses ouvreCorps()
220
+     * @uses fermeCorps()
221
+     * @uses fermeBody()
222
+     *
223
+     */
224
+    public function page($corps, $options = []) {
225 225
 
226
-		// par securite
227
-		if (!defined('_AJAX')) {
228
-			define('_AJAX', false);
229
-		}
226
+        // par securite
227
+        if (!defined('_AJAX')) {
228
+            define('_AJAX', false);
229
+        }
230 230
 
231
-		$status = ((int) ($options['status'] ?? 200)) ?: 200;
231
+        $status = ((int) ($options['status'] ?? 200)) ?: 200;
232 232
 
233
-		http_response_code($status);
233
+        http_response_code($status);
234 234
 
235
-		$html = $this->ouvreBody($options)
236
-			. $this->ouvreCorps($options)
237
-			. $corps
238
-			. $this->fermeCorps($options)
239
-			. $this->fermeBody();
235
+        $html = $this->ouvreBody($options)
236
+            . $this->ouvreCorps($options)
237
+            . $corps
238
+            . $this->fermeCorps($options)
239
+            . $this->fermeBody();
240 240
 
241
-		if (
242
-			$GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2)
243
-			&& empty($options['all_inline'])
244
-		) {
245
-			define('_SET_HTML_BASE', true);
246
-			include_spip('public/assembler');
247
-			$GLOBALS['html'] = true;
248
-			page_base_href($html);
249
-		}
250
-		return $html;
251
-	}
241
+        if (
242
+            $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2)
243
+            && empty($options['all_inline'])
244
+        ) {
245
+            define('_SET_HTML_BASE', true);
246
+            include_spip('public/assembler');
247
+            $GLOBALS['html'] = true;
248
+            page_base_href($html);
249
+        }
250
+        return $html;
251
+    }
252 252
 
253
-	/**
254
-	 * Fonction helper pour les erreurs
255
-	 * @param ?string $message_erreur
256
-	 * @param array $options
257
-	 * @see page()
258
-	 * @return string
259
-	 *
260
-	 */
261
-	public function pageErreur($message_erreur = null, $options = []) {
253
+    /**
254
+     * Fonction helper pour les erreurs
255
+     * @param ?string $message_erreur
256
+     * @param array $options
257
+     * @see page()
258
+     * @return string
259
+     *
260
+     */
261
+    public function pageErreur($message_erreur = null, $options = []) {
262 262
 
263
-		if (empty($message_erreur)) {
264
-			if (empty($options['lang'])) {
265
-				utiliser_langue_visiteur();
266
-			} else {
267
-				changer_langue($options['lang']);
268
-			}
269
-			$message_erreur = _T('info_acces_interdit');
270
-		}
271
-		$corps = "<div class='msg-alert error'>"
272
-			. $message_erreur
273
-			. '</div>';
274
-		if (empty($options['status'])) {
275
-			$options['status'] = 403;
276
-		}
277
-		return $this->page($corps, $options);
278
-	}
263
+        if (empty($message_erreur)) {
264
+            if (empty($options['lang'])) {
265
+                utiliser_langue_visiteur();
266
+            } else {
267
+                changer_langue($options['lang']);
268
+            }
269
+            $message_erreur = _T('info_acces_interdit');
270
+        }
271
+        $corps = "<div class='msg-alert error'>"
272
+            . $message_erreur
273
+            . '</div>';
274
+        if (empty($options['status'])) {
275
+            $options['status'] = 403;
276
+        }
277
+        return $this->page($corps, $options);
278
+    }
279 279
 }
Please login to merge, or discard this patch.
ecrire/src/Texte/Collecteur/Idiomes.php 1 patch
Indentation   +105 added lines, -105 removed lines patch added patch discarded remove patch
@@ -21,109 +21,109 @@
 block discarded – undo
21 21
  * Ne pas mettre de span@lang=fr si on est déjà en fr.
22 22
  */
23 23
 class Idiomes extends AbstractCollecteur {
24
-	protected static string $markPrefix = 'IDIOME';
25
-
26
-	/**
27
-	 * La preg pour découper et collecter les modèles
28
-	 * @var string
29
-	 */
30
-	protected string $preg_idiome;
31
-
32
-	public function __construct(?string $preg = null) {
33
-
34
-		$this->preg_idiome = ($preg ?: '@<:(?:([a-z0-9_]+):)?([a-z0-9_]+):>@isS');
35
-	}
36
-
37
-	/**
38
-	 * Sanitizer une collection d'occurences d'idiomes : on ne fait rien
39
-	 *
40
-	 * @param array $collection
41
-	 * @param string $sanitize_callback
42
-	 * @return array
43
-	 */
44
-	protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
45
-
46
-		return $collection;
47
-	}
48
-
49
-
50
-	/**
51
-	 * @param string $texte
52
-	 * @param array $options
53
-	 *   bool $collecter_liens
54
-	 * @return array
55
-	 */
56
-	public function collecter(string $texte, array $options = []): array {
57
-		if (!$texte) {
58
-			return [];
59
-		}
60
-
61
-		// collecter les matchs de la preg
62
-		$idiomes = static::collecteur($texte, '', '<:', $this->preg_idiome, empty($options['detecter_presence']) ? 0 : 1);
63
-
64
-		// si on veut seulement detecter la présence, on peut retourner tel quel
65
-		if (empty($options['detecter_presence'])) {
66
-			$pos_prev = 0;
67
-			foreach ($idiomes as $k => &$idiome) {
68
-				$idiome['module'] = $idiome['match'][1];
69
-				$idiome['chaine'] = $idiome['match'][2];
70
-			}
71
-		}
72
-
73
-		return $idiomes;
74
-	}
75
-
76
-	/**
77
-	 * Traiter les idiomes d'un texte
78
-	 *
79
-	 * @uses inc_traduire_dist()
80
-	 * @uses code_echappement()
81
-	 * @uses echappe_retour()
82
-	 *
83
-	 * @param string $texte
84
-	 * @param array $options
85
-	 *   ?string $lang
86
-	 *   ?bool echappe_span
87
-	 * @return string
88
-	 */
89
-	public function traiter(string $texte, array $options) {
90
-		static $traduire;
91
-		if ($texte) {
92
-			$idiomes = $this->collecter($texte);
93
-			if ($idiomes !== []) {
94
-				$lang = $options['lang'] ?? $GLOBALS['spip_lang'];
95
-				$echappe_span = $options['echappe_span'] ?? false;
96
-
97
-				if (is_null($traduire)) {
98
-					$traduire = charger_fonction('traduire', 'inc');
99
-					include_spip('inc/lang');
100
-				}
101
-
102
-				$offset_pos = 0;
103
-				foreach ($idiomes as $idiome) {
104
-					$cle = ($idiome['module'] ? $idiome['module'] . ':' : '') . $idiome['chaine'];
105
-					$desc = $traduire($cle, $lang, true);
106
-					$l = $desc->langue;
107
-
108
-					// si pas de traduction, on laissera l'écriture de l'idiome entier dans le texte.
109
-					if (strlen($desc->texte ?? '')) {
110
-						$trad = self::echappementHtmlBase64($desc->texte, 'idiome');
111
-						if ($l !== $lang) {
112
-							$trad = str_replace("'", '"', (string) inserer_attribut($trad, 'lang', $l));
113
-						}
114
-						if (lang_dir($l) !== lang_dir($lang)) {
115
-							$trad = str_replace("'", '"', (string) inserer_attribut($trad, 'dir', lang_dir($l)));
116
-						}
117
-						if (!$echappe_span) {
118
-							$trad = self::retablir_depuisHtmlBase64($trad, 'idiome');
119
-						}
120
-						$texte = substr_replace($texte, (string) $trad, $idiome['pos'] + $offset_pos, $idiome['length']);
121
-						$offset_pos += strlen((string) $trad) - $idiome['length'];
122
-					}
123
-				}
124
-			}
125
-		}
126
-
127
-		return $texte;
128
-	}
24
+    protected static string $markPrefix = 'IDIOME';
25
+
26
+    /**
27
+     * La preg pour découper et collecter les modèles
28
+     * @var string
29
+     */
30
+    protected string $preg_idiome;
31
+
32
+    public function __construct(?string $preg = null) {
33
+
34
+        $this->preg_idiome = ($preg ?: '@<:(?:([a-z0-9_]+):)?([a-z0-9_]+):>@isS');
35
+    }
36
+
37
+    /**
38
+     * Sanitizer une collection d'occurences d'idiomes : on ne fait rien
39
+     *
40
+     * @param array $collection
41
+     * @param string $sanitize_callback
42
+     * @return array
43
+     */
44
+    protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
45
+
46
+        return $collection;
47
+    }
48
+
49
+
50
+    /**
51
+     * @param string $texte
52
+     * @param array $options
53
+     *   bool $collecter_liens
54
+     * @return array
55
+     */
56
+    public function collecter(string $texte, array $options = []): array {
57
+        if (!$texte) {
58
+            return [];
59
+        }
60
+
61
+        // collecter les matchs de la preg
62
+        $idiomes = static::collecteur($texte, '', '<:', $this->preg_idiome, empty($options['detecter_presence']) ? 0 : 1);
63
+
64
+        // si on veut seulement detecter la présence, on peut retourner tel quel
65
+        if (empty($options['detecter_presence'])) {
66
+            $pos_prev = 0;
67
+            foreach ($idiomes as $k => &$idiome) {
68
+                $idiome['module'] = $idiome['match'][1];
69
+                $idiome['chaine'] = $idiome['match'][2];
70
+            }
71
+        }
72
+
73
+        return $idiomes;
74
+    }
75
+
76
+    /**
77
+     * Traiter les idiomes d'un texte
78
+     *
79
+     * @uses inc_traduire_dist()
80
+     * @uses code_echappement()
81
+     * @uses echappe_retour()
82
+     *
83
+     * @param string $texte
84
+     * @param array $options
85
+     *   ?string $lang
86
+     *   ?bool echappe_span
87
+     * @return string
88
+     */
89
+    public function traiter(string $texte, array $options) {
90
+        static $traduire;
91
+        if ($texte) {
92
+            $idiomes = $this->collecter($texte);
93
+            if ($idiomes !== []) {
94
+                $lang = $options['lang'] ?? $GLOBALS['spip_lang'];
95
+                $echappe_span = $options['echappe_span'] ?? false;
96
+
97
+                if (is_null($traduire)) {
98
+                    $traduire = charger_fonction('traduire', 'inc');
99
+                    include_spip('inc/lang');
100
+                }
101
+
102
+                $offset_pos = 0;
103
+                foreach ($idiomes as $idiome) {
104
+                    $cle = ($idiome['module'] ? $idiome['module'] . ':' : '') . $idiome['chaine'];
105
+                    $desc = $traduire($cle, $lang, true);
106
+                    $l = $desc->langue;
107
+
108
+                    // si pas de traduction, on laissera l'écriture de l'idiome entier dans le texte.
109
+                    if (strlen($desc->texte ?? '')) {
110
+                        $trad = self::echappementHtmlBase64($desc->texte, 'idiome');
111
+                        if ($l !== $lang) {
112
+                            $trad = str_replace("'", '"', (string) inserer_attribut($trad, 'lang', $l));
113
+                        }
114
+                        if (lang_dir($l) !== lang_dir($lang)) {
115
+                            $trad = str_replace("'", '"', (string) inserer_attribut($trad, 'dir', lang_dir($l)));
116
+                        }
117
+                        if (!$echappe_span) {
118
+                            $trad = self::retablir_depuisHtmlBase64($trad, 'idiome');
119
+                        }
120
+                        $texte = substr_replace($texte, (string) $trad, $idiome['pos'] + $offset_pos, $idiome['length']);
121
+                        $offset_pos += strlen((string) $trad) - $idiome['length'];
122
+                    }
123
+                }
124
+            }
125
+        }
126
+
127
+        return $texte;
128
+    }
129 129
 }
Please login to merge, or discard this patch.
ecrire/src/Texte/Collecteur/HtmlTag.php 1 patch
Indentation   +206 added lines, -206 removed lines patch added patch discarded remove patch
@@ -17,210 +17,210 @@
 block discarded – undo
17 17
  * @see extraire_balises()
18 18
  */
19 19
 class HtmlTag extends AbstractCollecteur {
20
-	protected static string $markPrefix = 'HTMLTAG';
21
-
22
-	/**
23
-	 * La preg pour découper et collecter les modèles
24
-	 * @var string
25
-	 */
26
-	protected string $preg_openingtag;
27
-	protected string $preg_closingtag;
28
-	protected string $tag;
29
-
30
-	public static array $listeBalisesAProteger = ['html', 'pre', 'code', 'cadre', 'frame', 'script', 'style'];
31
-
32
-	public function __construct(string $tag, ?string $preg_openingtag = null, ?string $preg_closingtag = null) {
33
-
34
-		$tag = strtolower($tag);
35
-		$this->tag = $tag;
36
-		$this->preg_openingtag = ($preg_openingtag ?: "@<{$tag}\b([^>]*?)(/?)>@isS");
37
-		$this->preg_closingtag = ($preg_closingtag ?? "@</{$tag}\b[^>]*>@isS");
38
-	}
39
-
40
-	/**
41
-	 * @param string $texte
42
-	 * @param array $options
43
-	 *   bool $detecter_presence
44
-	 *   bool $nb_max
45
-	 *   int  $profondeur
46
-	 * @return array
47
-	 */
48
-	public function collecter(string $texte, array $options = []): array {
49
-		if (!$texte) {
50
-			return [];
51
-		}
52
-
53
-		$upperTag = strtoupper($this->tag);
54
-		$hasUpperCaseTags = ($upperTag !== $this->tag && (str_contains($texte, '<' . $upperTag) || str_contains($texte, '</' . $upperTag)));
55
-
56
-		// collecter les balises ouvrantes
57
-		$opening = static::collecteur($texte, '', $hasUpperCaseTags ? '<' : '<' . $this->tag, $this->preg_openingtag, empty($options['detecter_presence']) ? 0 : 1);
58
-		if (!$opening) {
59
-			return [];
60
-		}
61
-
62
-		// si c'est un tag autofermant ou vide qui se repère avec une seule regexp, on va plus vite
63
-		if (!$this->preg_closingtag) {
64
-			return $opening;
65
-		}
66
-
67
-		// collecter les balises fermantes
68
-		$closing = static::collecteur($texte, '', $hasUpperCaseTags ? '</' : '</' . $this->tag, $this->preg_closingtag);
69
-
70
-		$profondeur = ($options['profondeur'] ?? 1);
71
-		$tags = [];
72
-		while (!empty($opening)) {
73
-			$first_opening = array_shift($opening);
74
-			// self closing ?
75
-			if (str_contains($first_opening['raw'], '/>')) {
76
-				$tag = $first_opening;
77
-				$tag['opening'] = $tag['raw'];
78
-				$tag['closing'] = '';
79
-				$tag['innerHtml'] = '';
80
-				$tag['attributs'] = trim(substr($tag['opening'], strlen($this->tag) + 1, -2));
81
-				$tags[] = $tag;
82
-			}
83
-			else {
84
-				// enlever les closing qui sont avant le premier opening, car ils n'ont pas de sens
85
-				while (
86
-					!empty($closing)
87
-					&& ($first_closing = reset($closing))
88
-					&& $first_closing['pos'] < $first_opening['pos']
89
-				) {
90
-					array_shift($closing);
91
-				}
92
-
93
-				$need_closing = 0;
94
-				$next_closing = reset($closing);
95
-				$next_opening = reset($opening);
96
-				// certaines balises comme <code> neutralisent le contenant, donc tout ce qui est avant le prochain closing doit etre ignoré
97
-				if (in_array($this->tag, ['code'])) {
98
-					while ($next_opening && $next_closing && $next_opening['pos'] < $next_closing['pos']) {
99
-						array_shift($opening);
100
-						$next_opening = reset($opening);
101
-					}
102
-				}
103
-				else {
104
-					while ($next_opening && $next_closing && $next_opening['pos'] < $next_closing['pos']) {
105
-						while ($next_opening && $next_opening['pos'] < $next_closing['pos']) {
106
-							// si pas self closing, il faut un closing de plus
107
-							if (!str_contains($next_opening['raw'], '/>')) {
108
-								$need_closing++;
109
-							}
110
-							array_shift($opening);
111
-							$next_opening = reset($opening);
112
-						}
113
-						// il faut depiler les balises fermantes autant de fois que nécessaire et tant qu'on a pas une nouvelle balise ouvrante
114
-						while ($need_closing && $next_closing && (!$next_opening || $next_closing['pos'] < $next_opening['pos'])) {
115
-							array_shift($closing);
116
-							$need_closing--;
117
-							$next_closing = reset($closing);
118
-						}
119
-					}
120
-				}
121
-				// si pas de fermeture, c'est une autofermante mal fermée...
122
-				if (!$next_closing || $need_closing) {
123
-					$tag = $first_opening;
124
-					$tag['opening'] = $tag['raw'];
125
-					$tag['closing'] = '';
126
-					$tag['innerHtml'] = '';
127
-					$tag['attributs'] = trim(substr($tag['opening'], strlen($this->tag) + 1, -1));
128
-					$tags[] = $tag;
129
-				}
130
-				else {
131
-					$tag = $first_opening;
132
-					$next_closing = array_shift($closing);
133
-					$innerHtml = substr($texte, $tag['pos'] + $tag['length'], $next_closing['pos'] - $tag['pos'] - $tag['length']);
134
-					$tag['length'] = $next_closing['pos'] - $tag['pos'] + $next_closing['length'];
135
-					$tag['opening'] = $tag['raw'];
136
-					$tag['raw'] = substr($texte, $tag['pos'], $tag['length']);
137
-					$tag['innerHtml'] = $innerHtml;
138
-					$tag['closing'] = $next_closing['raw'];
139
-					$tag['attributs'] = trim(substr($tag['opening'], strlen($this->tag) + 1, -1));
140
-					$tags[] = $tag;
141
-				}
142
-			}
143
-			if ((!empty($options['detecter_presence']) && count($tags))) {
144
-				return $tags;
145
-			}
146
-			if (($profondeur == 1 && !empty($options['nb_max']) && count($tags) >= $options['nb_max'])) {
147
-				break;
148
-			}
149
-		}
150
-
151
-		while (--$profondeur > 0) {
152
-			$outerTags = $tags;
153
-			$tags = [];
154
-			$options['profondeur'] = 1;
155
-			foreach ($outerTags as $outerTag) {
156
-				if (!empty($outerTag['innerHtml'])) {
157
-					$offsetPos = $outerTag['pos'] + strlen($outerTag['opening']);
158
-					$innerTags = $this->collecter($outerTag['innerHtml'], $options);
159
-					if (!empty($innerTags)) {
160
-						foreach ($innerTags as $tag) {
161
-							$tag['pos'] += $offsetPos;
162
-							$tags[] = $tag;
163
-						}
164
-						if (($profondeur == 1 && !empty($options['nb_max']) && count($tags) >= $options['nb_max'])) {
165
-							return $tags;
166
-						}
167
-					}
168
-				}
169
-			}
170
-		}
171
-
172
-
173
-		return $tags;
174
-	}
175
-
176
-	/**
177
-	 * @param callable|null $callback_function
178
-	 */
179
-	public function echapper_enHtmlBase64(string $texte, string $source = '', $callback_function = null, array $callback_options = []): string {
180
-		if ($callback_function) {
181
-			$legacy_callback = $callback_function;
182
-			// si on est dans un cas evident de preg perso, ne pas essayer de mapper le match car on ne sait pas ce qu'il contient
183
-			// et on aura pas non plus de innerHtml si pas de preg_closingtag
184
-			if ($this->preg_closingtag) {
185
-				$tag = $this->tag;
186
-				$legacy_callback = function ($c, $options) use ($tag, $callback_function) {
187
-					// legacy : renseigner les infos correspondantes aux matchs de l'ancienne regexp
188
-					$regs = [
189
-						0 => $c['raw'],
190
-						1 => $tag,
191
-						2 => $c['match'][1] . $c['match'][2],
192
-						3 => $c['innerHtml'],
193
-						'tag' => $this->tag,
194
-					] + $c;
195
-					return $callback_function($regs, $options);
196
-				};
197
-			}
198
-		}
199
-		return parent::echapper_enHtmlBase64($texte, $source, $callback_function ? $legacy_callback : null, $callback_options);
200
-	}
201
-
202
-
203
-	/**
204
-	 * pour $source voir commentaire infra (echappe_retour)
205
-	 * pour $no_transform voir le filtre post_autobr dans inc/filtres
206
-	 */
207
-	public static function proteger_balisesHtml(string $texte, string $source = '', ?array $html_tags = null, array $callbacks_function = [], array $callback_options = []): string {
208
-		if ($texte === '') {
209
-			return '';
210
-		}
211
-
212
-		$html_tags = $html_tags ?: self::$listeBalisesAProteger;
213
-
214
-		$tags_todo = $html_tags;
215
-		while (
216
-			!empty($tags_todo)
217
-			&& ($tag = array_shift($tags_todo))
218
-			&& str_contains($texte, '<')
219
-		) {
220
-			$htmlTagCollecteur = new self($tag);
221
-			$texte = $htmlTagCollecteur->echapper_enHtmlBase64($texte, $source, $callbacks_function[$tag] ?? null, $callback_options);
222
-		}
223
-
224
-		return $texte;
225
-	}
20
+    protected static string $markPrefix = 'HTMLTAG';
21
+
22
+    /**
23
+     * La preg pour découper et collecter les modèles
24
+     * @var string
25
+     */
26
+    protected string $preg_openingtag;
27
+    protected string $preg_closingtag;
28
+    protected string $tag;
29
+
30
+    public static array $listeBalisesAProteger = ['html', 'pre', 'code', 'cadre', 'frame', 'script', 'style'];
31
+
32
+    public function __construct(string $tag, ?string $preg_openingtag = null, ?string $preg_closingtag = null) {
33
+
34
+        $tag = strtolower($tag);
35
+        $this->tag = $tag;
36
+        $this->preg_openingtag = ($preg_openingtag ?: "@<{$tag}\b([^>]*?)(/?)>@isS");
37
+        $this->preg_closingtag = ($preg_closingtag ?? "@</{$tag}\b[^>]*>@isS");
38
+    }
39
+
40
+    /**
41
+     * @param string $texte
42
+     * @param array $options
43
+     *   bool $detecter_presence
44
+     *   bool $nb_max
45
+     *   int  $profondeur
46
+     * @return array
47
+     */
48
+    public function collecter(string $texte, array $options = []): array {
49
+        if (!$texte) {
50
+            return [];
51
+        }
52
+
53
+        $upperTag = strtoupper($this->tag);
54
+        $hasUpperCaseTags = ($upperTag !== $this->tag && (str_contains($texte, '<' . $upperTag) || str_contains($texte, '</' . $upperTag)));
55
+
56
+        // collecter les balises ouvrantes
57
+        $opening = static::collecteur($texte, '', $hasUpperCaseTags ? '<' : '<' . $this->tag, $this->preg_openingtag, empty($options['detecter_presence']) ? 0 : 1);
58
+        if (!$opening) {
59
+            return [];
60
+        }
61
+
62
+        // si c'est un tag autofermant ou vide qui se repère avec une seule regexp, on va plus vite
63
+        if (!$this->preg_closingtag) {
64
+            return $opening;
65
+        }
66
+
67
+        // collecter les balises fermantes
68
+        $closing = static::collecteur($texte, '', $hasUpperCaseTags ? '</' : '</' . $this->tag, $this->preg_closingtag);
69
+
70
+        $profondeur = ($options['profondeur'] ?? 1);
71
+        $tags = [];
72
+        while (!empty($opening)) {
73
+            $first_opening = array_shift($opening);
74
+            // self closing ?
75
+            if (str_contains($first_opening['raw'], '/>')) {
76
+                $tag = $first_opening;
77
+                $tag['opening'] = $tag['raw'];
78
+                $tag['closing'] = '';
79
+                $tag['innerHtml'] = '';
80
+                $tag['attributs'] = trim(substr($tag['opening'], strlen($this->tag) + 1, -2));
81
+                $tags[] = $tag;
82
+            }
83
+            else {
84
+                // enlever les closing qui sont avant le premier opening, car ils n'ont pas de sens
85
+                while (
86
+                    !empty($closing)
87
+                    && ($first_closing = reset($closing))
88
+                    && $first_closing['pos'] < $first_opening['pos']
89
+                ) {
90
+                    array_shift($closing);
91
+                }
92
+
93
+                $need_closing = 0;
94
+                $next_closing = reset($closing);
95
+                $next_opening = reset($opening);
96
+                // certaines balises comme <code> neutralisent le contenant, donc tout ce qui est avant le prochain closing doit etre ignoré
97
+                if (in_array($this->tag, ['code'])) {
98
+                    while ($next_opening && $next_closing && $next_opening['pos'] < $next_closing['pos']) {
99
+                        array_shift($opening);
100
+                        $next_opening = reset($opening);
101
+                    }
102
+                }
103
+                else {
104
+                    while ($next_opening && $next_closing && $next_opening['pos'] < $next_closing['pos']) {
105
+                        while ($next_opening && $next_opening['pos'] < $next_closing['pos']) {
106
+                            // si pas self closing, il faut un closing de plus
107
+                            if (!str_contains($next_opening['raw'], '/>')) {
108
+                                $need_closing++;
109
+                            }
110
+                            array_shift($opening);
111
+                            $next_opening = reset($opening);
112
+                        }
113
+                        // il faut depiler les balises fermantes autant de fois que nécessaire et tant qu'on a pas une nouvelle balise ouvrante
114
+                        while ($need_closing && $next_closing && (!$next_opening || $next_closing['pos'] < $next_opening['pos'])) {
115
+                            array_shift($closing);
116
+                            $need_closing--;
117
+                            $next_closing = reset($closing);
118
+                        }
119
+                    }
120
+                }
121
+                // si pas de fermeture, c'est une autofermante mal fermée...
122
+                if (!$next_closing || $need_closing) {
123
+                    $tag = $first_opening;
124
+                    $tag['opening'] = $tag['raw'];
125
+                    $tag['closing'] = '';
126
+                    $tag['innerHtml'] = '';
127
+                    $tag['attributs'] = trim(substr($tag['opening'], strlen($this->tag) + 1, -1));
128
+                    $tags[] = $tag;
129
+                }
130
+                else {
131
+                    $tag = $first_opening;
132
+                    $next_closing = array_shift($closing);
133
+                    $innerHtml = substr($texte, $tag['pos'] + $tag['length'], $next_closing['pos'] - $tag['pos'] - $tag['length']);
134
+                    $tag['length'] = $next_closing['pos'] - $tag['pos'] + $next_closing['length'];
135
+                    $tag['opening'] = $tag['raw'];
136
+                    $tag['raw'] = substr($texte, $tag['pos'], $tag['length']);
137
+                    $tag['innerHtml'] = $innerHtml;
138
+                    $tag['closing'] = $next_closing['raw'];
139
+                    $tag['attributs'] = trim(substr($tag['opening'], strlen($this->tag) + 1, -1));
140
+                    $tags[] = $tag;
141
+                }
142
+            }
143
+            if ((!empty($options['detecter_presence']) && count($tags))) {
144
+                return $tags;
145
+            }
146
+            if (($profondeur == 1 && !empty($options['nb_max']) && count($tags) >= $options['nb_max'])) {
147
+                break;
148
+            }
149
+        }
150
+
151
+        while (--$profondeur > 0) {
152
+            $outerTags = $tags;
153
+            $tags = [];
154
+            $options['profondeur'] = 1;
155
+            foreach ($outerTags as $outerTag) {
156
+                if (!empty($outerTag['innerHtml'])) {
157
+                    $offsetPos = $outerTag['pos'] + strlen($outerTag['opening']);
158
+                    $innerTags = $this->collecter($outerTag['innerHtml'], $options);
159
+                    if (!empty($innerTags)) {
160
+                        foreach ($innerTags as $tag) {
161
+                            $tag['pos'] += $offsetPos;
162
+                            $tags[] = $tag;
163
+                        }
164
+                        if (($profondeur == 1 && !empty($options['nb_max']) && count($tags) >= $options['nb_max'])) {
165
+                            return $tags;
166
+                        }
167
+                    }
168
+                }
169
+            }
170
+        }
171
+
172
+
173
+        return $tags;
174
+    }
175
+
176
+    /**
177
+     * @param callable|null $callback_function
178
+     */
179
+    public function echapper_enHtmlBase64(string $texte, string $source = '', $callback_function = null, array $callback_options = []): string {
180
+        if ($callback_function) {
181
+            $legacy_callback = $callback_function;
182
+            // si on est dans un cas evident de preg perso, ne pas essayer de mapper le match car on ne sait pas ce qu'il contient
183
+            // et on aura pas non plus de innerHtml si pas de preg_closingtag
184
+            if ($this->preg_closingtag) {
185
+                $tag = $this->tag;
186
+                $legacy_callback = function ($c, $options) use ($tag, $callback_function) {
187
+                    // legacy : renseigner les infos correspondantes aux matchs de l'ancienne regexp
188
+                    $regs = [
189
+                        0 => $c['raw'],
190
+                        1 => $tag,
191
+                        2 => $c['match'][1] . $c['match'][2],
192
+                        3 => $c['innerHtml'],
193
+                        'tag' => $this->tag,
194
+                    ] + $c;
195
+                    return $callback_function($regs, $options);
196
+                };
197
+            }
198
+        }
199
+        return parent::echapper_enHtmlBase64($texte, $source, $callback_function ? $legacy_callback : null, $callback_options);
200
+    }
201
+
202
+
203
+    /**
204
+     * pour $source voir commentaire infra (echappe_retour)
205
+     * pour $no_transform voir le filtre post_autobr dans inc/filtres
206
+     */
207
+    public static function proteger_balisesHtml(string $texte, string $source = '', ?array $html_tags = null, array $callbacks_function = [], array $callback_options = []): string {
208
+        if ($texte === '') {
209
+            return '';
210
+        }
211
+
212
+        $html_tags = $html_tags ?: self::$listeBalisesAProteger;
213
+
214
+        $tags_todo = $html_tags;
215
+        while (
216
+            !empty($tags_todo)
217
+            && ($tag = array_shift($tags_todo))
218
+            && str_contains($texte, '<')
219
+        ) {
220
+            $htmlTagCollecteur = new self($tag);
221
+            $texte = $htmlTagCollecteur->echapper_enHtmlBase64($texte, $source, $callbacks_function[$tag] ?? null, $callback_options);
222
+        }
223
+
224
+        return $texte;
225
+    }
226 226
 }
Please login to merge, or discard this patch.
ecrire/src/Texte/Collecteur/Multis.php 1 patch
Indentation   +199 added lines, -199 removed lines patch added patch discarded remove patch
@@ -27,203 +27,203 @@
 block discarded – undo
27 27
  * Ne pas mettre de span@lang=fr si on est déjà en fr.
28 28
  */
29 29
 class Multis extends AbstractCollecteur {
30
-	protected static string $markPrefix = 'MULTI';
31
-
32
-	/**
33
-	 * La preg pour découper et collecter les modèles
34
-	 * @var string
35
-	 */
36
-	protected string $preg_multi;
37
-
38
-	public function __construct(?string $preg = null) {
39
-
40
-		$this->preg_multi = ($preg ?: '@<multi>(.*?)</multi>@sS');
41
-	}
42
-
43
-	/**
44
-	 * Sanitizer une collection d'occurences de multi : on sanitize chaque texte de langue séparemment
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
-		foreach ($collection as &$multi) {
53
-			$changed = false;
54
-			foreach ($multi['trads'] as $lang => $trad) {
55
-				$t = $sanitize_callback($trad);
56
-				if ($t !== $trad) {
57
-					$changed = true;
58
-					$multi['trads'][$lang] = $t;
59
-				}
60
-			}
61
-			if ($changed) {
62
-				$texte = $this->agglomerer_trads($multi['trads']);
63
-				$multi['raw'] = str_replace($multi['texte'], $texte, (string) $multi['raw']);
64
-				$multi['texte'] = $texte;
65
-			}
66
-		}
67
-		return $collection;
68
-	}
69
-
70
-
71
-	/**
72
-	 * Convertit le contenu d'une balise `<multi>` en un tableau
73
-	 *
74
-	 * Exemple de blocs.
75
-	 * - `texte par défaut [fr] en français [en] en anglais`
76
-	 * - `[fr] en français [en] en anglais`
77
-	 *
78
-	 * @param string $bloc
79
-	 *     Le contenu intérieur d'un bloc multi
80
-	 * @return array [code de langue => texte]
81
-	 *     Peut retourner un code de langue vide, lorsqu'un texte par défaut est indiqué.
82
-	 **/
83
-	protected function extraire_trads($bloc) {
84
-		$trads = [];
85
-
86
-		if (strlen($bloc)) {
87
-			$langs = static::collecteur($bloc, ']', '[', '@[\[]([a-z]{2,3}(_[a-z]{2,3})?(_[a-z]{2,3})?)[\]]@siS');
88
-			$lang = '';
89
-			$pos_prev = 0;
90
-			foreach ($langs as $l) {
91
-				$pos = $l['pos'];
92
-				if ($lang || $pos > $pos_prev) {
93
-					$trads[$lang] = substr($bloc, $pos_prev, $pos - $pos_prev);
94
-				}
95
-				$lang = $l['match'][1];
96
-				$pos_prev = $pos + $l['length'];
97
-			}
98
-			$trads[$lang] = substr($bloc, $pos_prev);
99
-		}
100
-
101
-		return $trads;
102
-	}
103
-
104
-	/**
105
-	 * Recoller ensemble les trads pour reconstituer le texte dans la balise <multi>...</multi>
106
-	 * @param array<string,string> $trads
107
-	 * @return string
108
-	 */
109
-	protected function agglomerer_trads($trads) {
110
-		$texte = '';
111
-		foreach ($trads as $lang => $trad) {
112
-			if ($texte || $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 = static::collecteur($texte, '', '<multi', $this->preg_multi, empty($options['detecter_presence']) ? 0 : 1);
133
-		// si on veut seulement detecter la présence, on peut retourner tel quel
134
-		if (empty($options['detecter_presence'])) {
135
-			foreach ($multis as $k => &$multi) {
136
-				$multi['texte'] = $multi['match'][1];
137
-				// extraire les trads du texte
138
-				$multi['trads'] = $this->extraire_trads($multi['texte']);
139
-			}
140
-		}
141
-
142
-		return $multis;
143
-	}
144
-
145
-	/**
146
-	 * Traiter les multis d'un texte
147
-	 *
148
-	 * @uses approcher_langue()
149
-	 * @uses lang_typo()
150
-	 * @uses code_echappement()
151
-	 * @uses echappe_retour()
152
-	 *
153
-	 * @param string $texte
154
-	 * @param array $options
155
-	 *   ?string $lang
156
-	 *   ?string $lang_defaut
157
-	 *   ?bool echappe_span
158
-	 *   ?bool appliquer_typo
159
-	 * @return string
160
-	 */
161
-	public function traiter(string $texte, array $options) {
162
-		if ($texte) {
163
-			$multis = $this->collecter($texte);
164
-			if ($multis !== []) {
165
-				$lang = $options['lang'] ?? $GLOBALS['spip_lang'];
166
-				$lang_defaut = $options['lang_defaut'] ?? _LANGUE_PAR_DEFAUT;
167
-				$echappe_span = $options['echappe_span'] ?? false;
168
-				$appliquer_typo = $options['appliquer_typo'] ?? true;
169
-
170
-				if (!function_exists('approcher_langue')) {
171
-					include_spip('inc/lang');
172
-				}
173
-
174
-				$offset_pos = 0;
175
-				foreach ($multis as $m) {
176
-					// chercher la version de la langue courante
177
-					$trads = $m['trads'];
178
-					if (empty($trads)) {
179
-						$trad = '';
180
-					}
181
-					elseif ($l = approcher_langue($trads, $lang)) {
182
-						$trad = $trads[$l];
183
-					} else {
184
-						if ($lang_defaut == 'aucune') {
185
-							$trad = '';
186
-						} else {
187
-							// langue absente, prendre le fr ou une langue précisée (meme comportement que inc/traduire.php)
188
-							// ou la premiere dispo
189
-							if (!$l = approcher_langue($trads, $lang_defaut)) {
190
-								$l = array_keys($trads);
191
-								$l = reset($l);
192
-							}
193
-							$trad = $trads[$l];
194
-
195
-							// mais typographier le texte selon les regles de celle-ci
196
-							// Attention aux blocs multi sur plusieurs lignes
197
-							if ($appliquer_typo) {
198
-								$typographie = charger_fonction(lang_typo($l), 'typographie');
199
-								$trad = $typographie($trad);
200
-
201
-								// Tester si on echappe en span ou en div
202
-								// il ne faut pas echapper en div si propre produit un seul paragraphe
203
-								include_spip('inc/texte');
204
-								$trad_propre = preg_replace(',(^<p[^>]*>|</p>$),Uims', '', (string) propre($trad));
205
-								$isBloc = self::echappementTexteContientBaliseBloc($trad_propre);
206
-								if ($isBloc) {
207
-									$trad = rtrim((string) $trad) . "\n\n";
208
-								}
209
-								$attributs = ['lang' => $l];
210
-								if (lang_dir($l) !== lang_dir($lang)) {
211
-									$attributs['dir'] = lang_dir($l);
212
-								}
213
-								$trad = self::echappementHtmlBase64($trad, 'multi', $isBloc, $attributs);
214
-								if (!$echappe_span) {
215
-									$trad = self::retablir_depuisHtmlBase64($trad, 'multi');
216
-								}
217
-							}
218
-						}
219
-					}
220
-
221
-					$texte = substr_replace($texte, (string) $trad, $m['pos'] + $offset_pos, $m['length']);
222
-					$offset_pos += strlen((string) $trad) - $m['length'];
223
-				}
224
-			}
225
-		}
226
-
227
-		return $texte;
228
-	}
30
+    protected static string $markPrefix = 'MULTI';
31
+
32
+    /**
33
+     * La preg pour découper et collecter les modèles
34
+     * @var string
35
+     */
36
+    protected string $preg_multi;
37
+
38
+    public function __construct(?string $preg = null) {
39
+
40
+        $this->preg_multi = ($preg ?: '@<multi>(.*?)</multi>@sS');
41
+    }
42
+
43
+    /**
44
+     * Sanitizer une collection d'occurences de multi : on sanitize chaque texte de langue séparemment
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
+        foreach ($collection as &$multi) {
53
+            $changed = false;
54
+            foreach ($multi['trads'] as $lang => $trad) {
55
+                $t = $sanitize_callback($trad);
56
+                if ($t !== $trad) {
57
+                    $changed = true;
58
+                    $multi['trads'][$lang] = $t;
59
+                }
60
+            }
61
+            if ($changed) {
62
+                $texte = $this->agglomerer_trads($multi['trads']);
63
+                $multi['raw'] = str_replace($multi['texte'], $texte, (string) $multi['raw']);
64
+                $multi['texte'] = $texte;
65
+            }
66
+        }
67
+        return $collection;
68
+    }
69
+
70
+
71
+    /**
72
+     * Convertit le contenu d'une balise `<multi>` en un tableau
73
+     *
74
+     * Exemple de blocs.
75
+     * - `texte par défaut [fr] en français [en] en anglais`
76
+     * - `[fr] en français [en] en anglais`
77
+     *
78
+     * @param string $bloc
79
+     *     Le contenu intérieur d'un bloc multi
80
+     * @return array [code de langue => texte]
81
+     *     Peut retourner un code de langue vide, lorsqu'un texte par défaut est indiqué.
82
+     **/
83
+    protected function extraire_trads($bloc) {
84
+        $trads = [];
85
+
86
+        if (strlen($bloc)) {
87
+            $langs = static::collecteur($bloc, ']', '[', '@[\[]([a-z]{2,3}(_[a-z]{2,3})?(_[a-z]{2,3})?)[\]]@siS');
88
+            $lang = '';
89
+            $pos_prev = 0;
90
+            foreach ($langs as $l) {
91
+                $pos = $l['pos'];
92
+                if ($lang || $pos > $pos_prev) {
93
+                    $trads[$lang] = substr($bloc, $pos_prev, $pos - $pos_prev);
94
+                }
95
+                $lang = $l['match'][1];
96
+                $pos_prev = $pos + $l['length'];
97
+            }
98
+            $trads[$lang] = substr($bloc, $pos_prev);
99
+        }
100
+
101
+        return $trads;
102
+    }
103
+
104
+    /**
105
+     * Recoller ensemble les trads pour reconstituer le texte dans la balise <multi>...</multi>
106
+     * @param array<string,string> $trads
107
+     * @return string
108
+     */
109
+    protected function agglomerer_trads($trads) {
110
+        $texte = '';
111
+        foreach ($trads as $lang => $trad) {
112
+            if ($texte || $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 = static::collecteur($texte, '', '<multi', $this->preg_multi, empty($options['detecter_presence']) ? 0 : 1);
133
+        // si on veut seulement detecter la présence, on peut retourner tel quel
134
+        if (empty($options['detecter_presence'])) {
135
+            foreach ($multis as $k => &$multi) {
136
+                $multi['texte'] = $multi['match'][1];
137
+                // extraire les trads du texte
138
+                $multi['trads'] = $this->extraire_trads($multi['texte']);
139
+            }
140
+        }
141
+
142
+        return $multis;
143
+    }
144
+
145
+    /**
146
+     * Traiter les multis d'un texte
147
+     *
148
+     * @uses approcher_langue()
149
+     * @uses lang_typo()
150
+     * @uses code_echappement()
151
+     * @uses echappe_retour()
152
+     *
153
+     * @param string $texte
154
+     * @param array $options
155
+     *   ?string $lang
156
+     *   ?string $lang_defaut
157
+     *   ?bool echappe_span
158
+     *   ?bool appliquer_typo
159
+     * @return string
160
+     */
161
+    public function traiter(string $texte, array $options) {
162
+        if ($texte) {
163
+            $multis = $this->collecter($texte);
164
+            if ($multis !== []) {
165
+                $lang = $options['lang'] ?? $GLOBALS['spip_lang'];
166
+                $lang_defaut = $options['lang_defaut'] ?? _LANGUE_PAR_DEFAUT;
167
+                $echappe_span = $options['echappe_span'] ?? false;
168
+                $appliquer_typo = $options['appliquer_typo'] ?? true;
169
+
170
+                if (!function_exists('approcher_langue')) {
171
+                    include_spip('inc/lang');
172
+                }
173
+
174
+                $offset_pos = 0;
175
+                foreach ($multis as $m) {
176
+                    // chercher la version de la langue courante
177
+                    $trads = $m['trads'];
178
+                    if (empty($trads)) {
179
+                        $trad = '';
180
+                    }
181
+                    elseif ($l = approcher_langue($trads, $lang)) {
182
+                        $trad = $trads[$l];
183
+                    } else {
184
+                        if ($lang_defaut == 'aucune') {
185
+                            $trad = '';
186
+                        } else {
187
+                            // langue absente, prendre le fr ou une langue précisée (meme comportement que inc/traduire.php)
188
+                            // ou la premiere dispo
189
+                            if (!$l = approcher_langue($trads, $lang_defaut)) {
190
+                                $l = array_keys($trads);
191
+                                $l = reset($l);
192
+                            }
193
+                            $trad = $trads[$l];
194
+
195
+                            // mais typographier le texte selon les regles de celle-ci
196
+                            // Attention aux blocs multi sur plusieurs lignes
197
+                            if ($appliquer_typo) {
198
+                                $typographie = charger_fonction(lang_typo($l), 'typographie');
199
+                                $trad = $typographie($trad);
200
+
201
+                                // Tester si on echappe en span ou en div
202
+                                // il ne faut pas echapper en div si propre produit un seul paragraphe
203
+                                include_spip('inc/texte');
204
+                                $trad_propre = preg_replace(',(^<p[^>]*>|</p>$),Uims', '', (string) propre($trad));
205
+                                $isBloc = self::echappementTexteContientBaliseBloc($trad_propre);
206
+                                if ($isBloc) {
207
+                                    $trad = rtrim((string) $trad) . "\n\n";
208
+                                }
209
+                                $attributs = ['lang' => $l];
210
+                                if (lang_dir($l) !== lang_dir($lang)) {
211
+                                    $attributs['dir'] = lang_dir($l);
212
+                                }
213
+                                $trad = self::echappementHtmlBase64($trad, 'multi', $isBloc, $attributs);
214
+                                if (!$echappe_span) {
215
+                                    $trad = self::retablir_depuisHtmlBase64($trad, 'multi');
216
+                                }
217
+                            }
218
+                        }
219
+                    }
220
+
221
+                    $texte = substr_replace($texte, (string) $trad, $m['pos'] + $offset_pos, $m['length']);
222
+                    $offset_pos += strlen((string) $trad) - $m['length'];
223
+                }
224
+            }
225
+        }
226
+
227
+        return $texte;
228
+    }
229 229
 }
Please login to merge, or discard this patch.
ecrire/src/Texte/Collecteur/Modeles.php 1 patch
Indentation   +199 added lines, -199 removed lines patch added patch discarded remove patch
@@ -20,203 +20,203 @@
 block discarded – undo
20 20
  *    mais on renvoie les params (pour l'indexation par le moteur de recherche)
21 21
  */
22 22
 class Modeles extends AbstractCollecteur {
23
-	protected static string $markPrefix = 'MODELE';
24
-
25
-	/**
26
-	 * La preg pour découper et collecter les modèles
27
-	 * @var string
28
-	 */
29
-	protected string $preg_modele;
30
-
31
-	public function __construct(?string $preg = null) {
32
-
33
-		$this->preg_modele = ($preg ?:
34
-			'@<([a-z_-]{3,})' # <modele
35
-			. '\s*([0-9]*)\s*' # id
36
-			. '([|](?:<[^<>]*>|[^>])*?)?' # |arguments (y compris des tags <...>)
37
-			. '\s*/?' . '>@isS' # fin du modele >
38
-		);
39
-	}
40
-
41
-	/**
42
-	 * Sanitizer une collection d'occurences de modèle : on ne fait rien
43
-	 *
44
-	 * @param array $collection
45
-	 * @param string $sanitize_callback
46
-	 * @return array
47
-	 */
48
-	protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
49
-
50
-		return $collection;
51
-	}
52
-
53
-	/**
54
-	 * @param string $texte
55
-	 * @param array $options
56
-	 *   bool $collecter_liens
57
-	 * @return array
58
-	 */
59
-	public function collecter(string $texte, array $options = []): array {
60
-		if (!$texte) {
61
-			return [];
62
-		}
63
-
64
-		// collecter les matchs de la preg
65
-		$modeles = static::collecteur($texte, '', '<', $this->preg_modele);
66
-
67
-		$pos_prev = 0;
68
-		foreach ($modeles as $k => &$modele) {
69
-			$pos = $modele['pos'];
70
-			$modele['type'] = $modele['match'][1];
71
-			$modele['id'] = $modele['match'][2] ?? '';
72
-			$modele['params'] = $modele['match'][3] ?? '';
73
-
74
-			$longueur = $modele['length'];
75
-			$end = $pos + $longueur;
76
-
77
-			// il faut avoir un id ou des params commençant par un | sinon c'est une simple balise html
78
-			if (empty($modele['id']) && empty($modele['params'])) {
79
-				unset($modeles[$k]);
80
-				continue;
81
-			}
82
-
83
-			// si on veut seulement detecter la présence, on peut retourner tel quel
84
-			if (!empty($options['detecter_presence'])) {
85
-				break;
86
-			}
87
-
88
-			$modele['lien'] = false;
89
-			if (
90
-				!empty($options['collecter_liens'])
91
-				&& ($pos_fermeture_lien = stripos($texte, '</a>', $end))
92
-				&& !strlen(trim(substr($texte, $end, $pos_fermeture_lien - $end)))
93
-			) {
94
-				$pos_lien_ouvrant = stripos($texte, '<a', $pos_prev);
95
-				if (
96
-					$pos_lien_ouvrant !== false
97
-					&& $pos_lien_ouvrant < $pos
98
-					&& 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 ($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', ' ', (string) $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;', '"', (string) $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 = self::echappementHtmlBase64($modele, $echap);
202
-							$texte = substr_replace($texte, (string) $rempl, $m['pos'] + $offset_pos, $m['length']);
203
-							$offset_pos += strlen((string) $rempl) - $m['length'];
204
-						}
205
-					}
206
-
207
-					// hack pour tout l'espace prive
208
-					if ((test_espace_prive() || $doublons) && !empty($m['id'])) {
209
-						$type = strtolower((string) $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
-	}
23
+    protected static string $markPrefix = 'MODELE';
24
+
25
+    /**
26
+     * La preg pour découper et collecter les modèles
27
+     * @var string
28
+     */
29
+    protected string $preg_modele;
30
+
31
+    public function __construct(?string $preg = null) {
32
+
33
+        $this->preg_modele = ($preg ?:
34
+            '@<([a-z_-]{3,})' # <modele
35
+            . '\s*([0-9]*)\s*' # id
36
+            . '([|](?:<[^<>]*>|[^>])*?)?' # |arguments (y compris des tags <...>)
37
+            . '\s*/?' . '>@isS' # fin du modele >
38
+        );
39
+    }
40
+
41
+    /**
42
+     * Sanitizer une collection d'occurences de modèle : on ne fait rien
43
+     *
44
+     * @param array $collection
45
+     * @param string $sanitize_callback
46
+     * @return array
47
+     */
48
+    protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
49
+
50
+        return $collection;
51
+    }
52
+
53
+    /**
54
+     * @param string $texte
55
+     * @param array $options
56
+     *   bool $collecter_liens
57
+     * @return array
58
+     */
59
+    public function collecter(string $texte, array $options = []): array {
60
+        if (!$texte) {
61
+            return [];
62
+        }
63
+
64
+        // collecter les matchs de la preg
65
+        $modeles = static::collecteur($texte, '', '<', $this->preg_modele);
66
+
67
+        $pos_prev = 0;
68
+        foreach ($modeles as $k => &$modele) {
69
+            $pos = $modele['pos'];
70
+            $modele['type'] = $modele['match'][1];
71
+            $modele['id'] = $modele['match'][2] ?? '';
72
+            $modele['params'] = $modele['match'][3] ?? '';
73
+
74
+            $longueur = $modele['length'];
75
+            $end = $pos + $longueur;
76
+
77
+            // il faut avoir un id ou des params commençant par un | sinon c'est une simple balise html
78
+            if (empty($modele['id']) && empty($modele['params'])) {
79
+                unset($modeles[$k]);
80
+                continue;
81
+            }
82
+
83
+            // si on veut seulement detecter la présence, on peut retourner tel quel
84
+            if (!empty($options['detecter_presence'])) {
85
+                break;
86
+            }
87
+
88
+            $modele['lien'] = false;
89
+            if (
90
+                !empty($options['collecter_liens'])
91
+                && ($pos_fermeture_lien = stripos($texte, '</a>', $end))
92
+                && !strlen(trim(substr($texte, $end, $pos_fermeture_lien - $end)))
93
+            ) {
94
+                $pos_lien_ouvrant = stripos($texte, '<a', $pos_prev);
95
+                if (
96
+                    $pos_lien_ouvrant !== false
97
+                    && $pos_lien_ouvrant < $pos
98
+                    && 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 ($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', ' ', (string) $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;', '"', (string) $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 = self::echappementHtmlBase64($modele, $echap);
202
+                            $texte = substr_replace($texte, (string) $rempl, $m['pos'] + $offset_pos, $m['length']);
203
+                            $offset_pos += strlen((string) $rempl) - $m['length'];
204
+                        }
205
+                    }
206
+
207
+                    // hack pour tout l'espace prive
208
+                    if ((test_espace_prive() || $doublons) && !empty($m['id'])) {
209
+                        $type = strtolower((string) $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
 }
Please login to merge, or discard this patch.
ecrire/src/Compilateur/Iterateur/Sql.php 1 patch
Indentation   +176 added lines, -176 removed lines patch added patch discarded remove patch
@@ -11,187 +11,187 @@
 block discarded – undo
11 11
  */
12 12
 class Sql extends AbstractIterateur implements Iterator
13 13
 {
14
-	/**
15
-	 * Ressource sql.
16
-	 *
17
-	 * @var bool|object
18
-	 */
19
-	protected $sqlresult = false;
14
+    /**
15
+     * Ressource sql.
16
+     *
17
+     * @var bool|object
18
+     */
19
+    protected $sqlresult = false;
20 20
 
21
-	/**
22
-	 * row sql courante.
23
-	 *
24
-	 * @var null|array
25
-	 */
26
-	protected $row;
21
+    /**
22
+     * row sql courante.
23
+     *
24
+     * @var null|array
25
+     */
26
+    protected $row;
27 27
 
28
-	protected bool $firstseek = false;
28
+    protected bool $firstseek = false;
29 29
 
30
-	protected int $pos = -1;
30
+    protected int $pos = -1;
31 31
 
32
-	/*
32
+    /*
33 33
 	 * array command: les commandes d'initialisation
34 34
 	 * array info: les infos sur le squelette
35 35
 	 */
36
-	public function __construct(array $command, array $info = []) {
37
-		$this->type = 'SQL';
38
-		parent::__construct($command, $info);
39
-
40
-		$this->select();
41
-	}
42
-
43
-	/**
44
-	 * Rembobiner.
45
-	 *
46
-	 * @return bool
47
-	 */
48
-	public function rewind(): void {
49
-		if ($this->pos > 0) {
50
-			$this->seek(0);
51
-		}
52
-	}
53
-
54
-	/**
55
-	 * Verifier l'etat de l'iterateur.
56
-	 */
57
-	public function valid(): bool {
58
-		if ($this->err) {
59
-			return false;
60
-		}
61
-		if (!$this->firstseek) {
62
-			$this->next();
63
-		}
64
-
65
-		return is_array($this->row);
66
-	}
67
-
68
-	/**
69
-	 * Valeurs sur la position courante.
70
-	 *
71
-	 * @return array
72
-	 */
73
-	public function current(): ?array {
74
-		return $this->row;
75
-	}
76
-
77
-	public function key(): int {
78
-		return $this->pos;
79
-	}
80
-
81
-	/**
82
-	 * Sauter a une position absolue.
83
-	 *
84
-	 * @param int         $n
85
-	 * @param null|string $continue
86
-	 */
87
-	public function seek($n = 0, $continue = null): bool {
88
-		if (!sql_seek($this->sqlresult, $n, $this->command['connect'], $continue)) {
89
-			// SQLite ne sait pas seek(), il faut relancer la query
90
-			// si la position courante est apres la position visee
91
-			// il faut relancer la requete
92
-			if ($this->pos > $n) {
93
-				$this->free();
94
-				$this->select();
95
-				$this->valid();
96
-			}
97
-			// et utiliser la methode par defaut pour se deplacer au bon endroit
98
-			// (sera fait en cas d'echec de cette fonction)
99
-			return false;
100
-		}
101
-		$this->row = sql_fetch($this->sqlresult, $this->command['connect']);
102
-		$this->pos = min($n, $this->count());
103
-
104
-		return true;
105
-	}
106
-
107
-	/**
108
-	 * Avancer d'un cran.
109
-	 */
110
-	public function next(): void {
111
-		$this->row = sql_fetch($this->sqlresult, $this->command['connect']);
112
-		++$this->pos;
113
-		$this->firstseek = true;
114
-	}
115
-
116
-	/**
117
-	 * Avancer et retourner les donnees pour le nouvel element.
118
-	 *
119
-	 * @return null|array|bool
120
-	 */
121
-	public function fetch() {
122
-		if ($this->valid()) {
123
-			$r = $this->current();
124
-			$this->next();
125
-		} else {
126
-			$r = false;
127
-		}
128
-
129
-		return $r;
130
-	}
131
-
132
-	/**
133
-	 * liberer les ressources.
134
-	 *
135
-	 * @return bool
136
-	 */
137
-	public function free() {
138
-		if (!$this->sqlresult) {
139
-			return true;
140
-		}
141
-		$a = sql_free($this->sqlresult, $this->command['connect']);
142
-		$this->sqlresult = null;
143
-
144
-		return $a;
145
-	}
146
-
147
-	/**
148
-	 * Compter le nombre de resultats.
149
-	 */
150
-	public function count(): int {
151
-		if (is_null($this->total)) {
152
-			if (!$this->sqlresult) {
153
-				$this->total = 0;
154
-			} else {
155
-				// cas count(*)
156
-				if (in_array('count(*)', $this->command['select'])) {
157
-					$this->valid();
158
-					$s = $this->current();
159
-					$this->total = (int) $s['count(*)'];
160
-				} else {
161
-					$this->total = (int) sql_count($this->sqlresult, $this->command['connect']);
162
-				}
163
-			}
164
-		}
165
-
166
-		return $this->total;
167
-	}
168
-
169
-	/**
170
-	 * selectionner les donnees, ie faire la requete SQL.
171
-	 */
172
-	protected function select() {
173
-		$this->row = null;
174
-		$v = &$this->command;
175
-		$this->sqlresult = calculer_select(
176
-			$v['select'],
177
-			$v['from'],
178
-			$v['type'],
179
-			$v['where'],
180
-			$v['join'],
181
-			$v['groupby'],
182
-			$v['orderby'],
183
-			$v['limit'],
184
-			$v['having'],
185
-			$v['table'],
186
-			$v['id'],
187
-			$v['connect'],
188
-			$this->info
189
-		);
190
-		$this->err = !$this->sqlresult;
191
-		$this->firstseek = false;
192
-		$this->pos = -1;
193
-
194
-		// pas d'init a priori, le calcul ne sera fait qu'en cas de besoin (provoque une double requete souvent inutile en sqlite)
195
-		//$this->total = $this->count();
196
-	}
36
+    public function __construct(array $command, array $info = []) {
37
+        $this->type = 'SQL';
38
+        parent::__construct($command, $info);
39
+
40
+        $this->select();
41
+    }
42
+
43
+    /**
44
+     * Rembobiner.
45
+     *
46
+     * @return bool
47
+     */
48
+    public function rewind(): void {
49
+        if ($this->pos > 0) {
50
+            $this->seek(0);
51
+        }
52
+    }
53
+
54
+    /**
55
+     * Verifier l'etat de l'iterateur.
56
+     */
57
+    public function valid(): bool {
58
+        if ($this->err) {
59
+            return false;
60
+        }
61
+        if (!$this->firstseek) {
62
+            $this->next();
63
+        }
64
+
65
+        return is_array($this->row);
66
+    }
67
+
68
+    /**
69
+     * Valeurs sur la position courante.
70
+     *
71
+     * @return array
72
+     */
73
+    public function current(): ?array {
74
+        return $this->row;
75
+    }
76
+
77
+    public function key(): int {
78
+        return $this->pos;
79
+    }
80
+
81
+    /**
82
+     * Sauter a une position absolue.
83
+     *
84
+     * @param int         $n
85
+     * @param null|string $continue
86
+     */
87
+    public function seek($n = 0, $continue = null): bool {
88
+        if (!sql_seek($this->sqlresult, $n, $this->command['connect'], $continue)) {
89
+            // SQLite ne sait pas seek(), il faut relancer la query
90
+            // si la position courante est apres la position visee
91
+            // il faut relancer la requete
92
+            if ($this->pos > $n) {
93
+                $this->free();
94
+                $this->select();
95
+                $this->valid();
96
+            }
97
+            // et utiliser la methode par defaut pour se deplacer au bon endroit
98
+            // (sera fait en cas d'echec de cette fonction)
99
+            return false;
100
+        }
101
+        $this->row = sql_fetch($this->sqlresult, $this->command['connect']);
102
+        $this->pos = min($n, $this->count());
103
+
104
+        return true;
105
+    }
106
+
107
+    /**
108
+     * Avancer d'un cran.
109
+     */
110
+    public function next(): void {
111
+        $this->row = sql_fetch($this->sqlresult, $this->command['connect']);
112
+        ++$this->pos;
113
+        $this->firstseek = true;
114
+    }
115
+
116
+    /**
117
+     * Avancer et retourner les donnees pour le nouvel element.
118
+     *
119
+     * @return null|array|bool
120
+     */
121
+    public function fetch() {
122
+        if ($this->valid()) {
123
+            $r = $this->current();
124
+            $this->next();
125
+        } else {
126
+            $r = false;
127
+        }
128
+
129
+        return $r;
130
+    }
131
+
132
+    /**
133
+     * liberer les ressources.
134
+     *
135
+     * @return bool
136
+     */
137
+    public function free() {
138
+        if (!$this->sqlresult) {
139
+            return true;
140
+        }
141
+        $a = sql_free($this->sqlresult, $this->command['connect']);
142
+        $this->sqlresult = null;
143
+
144
+        return $a;
145
+    }
146
+
147
+    /**
148
+     * Compter le nombre de resultats.
149
+     */
150
+    public function count(): int {
151
+        if (is_null($this->total)) {
152
+            if (!$this->sqlresult) {
153
+                $this->total = 0;
154
+            } else {
155
+                // cas count(*)
156
+                if (in_array('count(*)', $this->command['select'])) {
157
+                    $this->valid();
158
+                    $s = $this->current();
159
+                    $this->total = (int) $s['count(*)'];
160
+                } else {
161
+                    $this->total = (int) sql_count($this->sqlresult, $this->command['connect']);
162
+                }
163
+            }
164
+        }
165
+
166
+        return $this->total;
167
+    }
168
+
169
+    /**
170
+     * selectionner les donnees, ie faire la requete SQL.
171
+     */
172
+    protected function select() {
173
+        $this->row = null;
174
+        $v = &$this->command;
175
+        $this->sqlresult = calculer_select(
176
+            $v['select'],
177
+            $v['from'],
178
+            $v['type'],
179
+            $v['where'],
180
+            $v['join'],
181
+            $v['groupby'],
182
+            $v['orderby'],
183
+            $v['limit'],
184
+            $v['having'],
185
+            $v['table'],
186
+            $v['id'],
187
+            $v['connect'],
188
+            $this->info
189
+        );
190
+        $this->err = !$this->sqlresult;
191
+        $this->firstseek = false;
192
+        $this->pos = -1;
193
+
194
+        // pas d'init a priori, le calcul ne sera fait qu'en cas de besoin (provoque une double requete souvent inutile en sqlite)
195
+        //$this->total = $this->count();
196
+    }
197 197
 }
Please login to merge, or discard this patch.
ecrire/src/Compilateur/Noeud/Boucle.php 1 patch
Indentation   +364 added lines, -364 removed lines patch added patch discarded remove patch
@@ -7,368 +7,368 @@
 block discarded – undo
7 7
  */
8 8
 class Boucle
9 9
 {
10
-	/** Type de noeud */
11
-	public string $type = 'boucle';
12
-
13
-	/** Identifiant de la boucle */
14
-	public string $id_boucle;
15
-
16
-	/** Identifiant de la boucle parente */
17
-	public string $id_parent = '';
18
-
19
-	/** Un nom explicite qui peut être affecté manuellement à certaines boucles générées */
20
-	public string $nom = '';
21
-
22
-	/**
23
-	 * Partie avant toujours affichee
24
-	 *
25
-	 * @var string|array
26
-	 */
27
-	public $preaff = '';
28
-
29
-	/**
30
-	 * Partie optionnelle avant
31
-	 *
32
-	 * @var string|array
33
-	 */
34
-	public $avant = '';
35
-
36
-	/**
37
-	 * Pour chaque élément
38
-	 *
39
-	 * @var string|array
40
-	 */
41
-	public $milieu = '';
42
-
43
-	/**
44
-	 * Partie optionnelle après
45
-	 *
46
-	 * @var string|array
47
-	 */
48
-	public $apres = '';
49
-
50
-	/**
51
-	 * Partie alternative, si pas de résultat dans la boucle
52
-	 *
53
-	 * @var string|array
54
-	 */
55
-	public $altern = '';
56
-
57
-	/**
58
-	 * Partie apres toujours affichee
59
-	 *
60
-	 * @var string|array
61
-	 */
62
-	public $postaff = '';
63
-
64
-
65
-	/**
66
-	 * La boucle doit-elle sélectionner la langue ?
67
-	 *
68
-	 * Valeurs : '', 'oui', 'non'
69
-	 */
70
-	public string $lang_select = '';
71
-
72
-	/**
73
-	 * Alias de table d'application de la requête ou nom complet de la table SQL
74
-	 *
75
-	 * FIXME: un seul typage (string ?)
76
-	 *
77
-	 * @var string|false|null
78
-	 */
79
-	public $type_requete = null;
80
-
81
-	/**
82
-	 * La table est elle optionnelle ?
83
-	 *
84
-	 * Si oui, aucune erreur ne sera générée si la table demandée n'est pas présente
85
-	 */
86
-	public bool $table_optionnelle = false;
87
-	public string $type_table_optionnelle = '';
88
-
89
-	/**
90
-	 * Nom du fichier de connexion
91
-	 */
92
-	public string $sql_serveur = '';
93
-
94
-	/**
95
-	 * Paramètres de la boucle
96
-	 *
97
-	 * Description des paramètres passés à la boucle, qui servent ensuite
98
-	 * au calcul des critères
99
-	 *
100
-	 * FIXME: type unique.
101
-	 * @var false|array
102
-	 *     - false: erreur de syntaxe
103
-	 */
104
-	public $param = [];
105
-
106
-	/**
107
-	 * Critères de la boucle
108
-	 *
109
-	 * FIXME: type array unique.
110
-	 *
111
-	 * @var string|Critere[]
112
-	 * - string: phrasage (code brut). Il reste si erreur de critère
113
-	 * - array: analyse correcte des critères...
114
-	 */
115
-	public $criteres = [];
116
-
117
-	/**
118
-	 * Textes insérés entre 2 éléments de boucle (critère inter)
119
-	 *
120
-	 * @var string[]
121
-	 */
122
-	public array $separateur = [];
123
-
124
-	/**
125
-	 * Liste des jointures possibles avec cette table
126
-	 *
127
-	 * Les jointures par défaut de la table sont complétées en priorité
128
-	 * des jointures déclarées explicitement sur la boucle
129
-	 *
130
-	 * @see base_trouver_table_dist()
131
-	 */
132
-	public array $jointures = [];
133
-
134
-	/**
135
-	 * Jointures explicites avec cette table
136
-	 *
137
-	 * Ces jointures sont utilisées en priorité par rapport aux jointures
138
-	 * normales possibles pour retrouver les colonnes demandées extérieures
139
-	 * à la boucle.
140
-	 *
141
-	 * @var string|bool
142
-	 */
143
-	public $jointures_explicites = false;
144
-
145
-	/**
146
-	 * Nom de la variable PHP stockant le noms de doublons utilisés "$doublons_index"
147
-	 */
148
-	public string $doublons = '';
149
-
150
-	/**
151
-	 * Code PHP ajouté au début de chaque itération de boucle.
152
-	 *
153
-	 * Utilisé entre autre par les critères {pagination}, {n-a,b}, {a/b}...
154
-	 */
155
-	public string $partie = '';
156
-
157
-	/**
158
-	 * Nombre de divisions de la boucle, d'éléments à afficher,
159
-	 * ou de soustractions d'éléments à faire
160
-	 *
161
-	 * Dans les critères limitant le nombre d'éléments affichés
162
-	 * {a,b}, {a,n-b}, {a/b}, {pagination b}, b est affecté à total_parties.
163
-	 */
164
-	public string $total_parties = '';
165
-
166
-	/**
167
-	 * Code PHP ajouté avant l'itération de boucle.
168
-	 *
169
-	 * Utilisé entre autre par les critères {pagination}, {a,b}, {a/b}
170
-	 * pour initialiser les variables de début et de fin d'itération.
171
-	 */
172
-	public string $mode_partie = '';
173
-
174
-	/**
175
-	 * Identifiant d'une boucle qui appelle celle-ci de manière récursive
176
-	 *
177
-	 * Si une boucle est appelée de manière récursive quelque part par
178
-	 * une autre boucle comme <BOUCLE_rec(boucle_identifiant) />, cette
179
-	 * boucle (identifiant) reçoit dans cette propriété l'identifiant
180
-	 * de l'appelant (rec)
181
-	 */
182
-	public string $externe = '';
183
-
184
-	// champs pour la construction de la requete SQL
185
-
186
-	/**
187
-	 * Liste des champs à récupérer par la boucle
188
-	 *
189
-	 * Expression 'table.nom_champ' ou calculée 'nom_champ AS x'
190
-	 *
191
-	 * @var string[]
192
-	 */
193
-	public array $select = [];
194
-
195
-	/**
196
-	 * Liste des alias / tables SQL utilisées dans la boucle
197
-	 *
198
-	 * L'index est un identifiant (xx dans spip_xx assez souvent) qui servira
199
-	 * d'alias au nom de la table ; la valeur est le nom de la table SQL désirée.
200
-	 *
201
-	 * L'index 0 peut définir le type de sources de données de l'itérateur DATA
202
-	 *
203
-	 * @var string[]
204
-	 */
205
-	public array $from = [];
206
-
207
-	/**
208
-	 * Liste des alias / type de jointures utilisées dans la boucle
209
-	 *
210
-	 * L'index est le nom d'alias (comme pour la propriété $from), et la valeur
211
-	 * un type de jointure parmi 'INNER', 'LEFT', 'RIGHT', 'OUTER'.
212
-	 *
213
-	 * Lorsque le type n'est pas déclaré pour un alias, c'est 'INNER'
214
-	 * qui sera utilisé par défaut (créant donc un INNER JOIN).
215
-	 *
216
-	 * @var string[]
217
-	 */
218
-	public array $from_type = [];
219
-
220
-	/**
221
-	 * Liste des conditions WHERE de la boucle
222
-	 *
223
-	 * Permet de restreindre les éléments retournés par une boucle
224
-	 * en fonctions des conditions transmises dans ce tableau.
225
-	 *
226
-	 * Ce tableau peut avoir plusieurs niveaux de profondeur.
227
-	 *
228
-	 * Les éléments du premier niveau sont reliés par des AND, donc
229
-	 * chaque élément ajouté directement au where par
230
-	 * $boucle->where[] = array(...) ou $boucle->where[] = "'expression'"
231
-	 * est une condition AND en plus.
232
-	 *
233
-	 * Par contre, lorsqu'on indique un tableau, il peut décrire des relations
234
-	 * internes différentes. Soit $expr un tableau d'expressions quelconques de 3 valeurs :
235
-	 * $expr = array(operateur, val1, val2)
236
-	 *
237
-	 * Ces 3 valeurs sont des expressions PHP. L'index 0 désigne l'opérateur
238
-	 * à réaliser tel que :
239
-	 *
240
-	 * - "'='" , "'>='", "'<'", "'IN'", "'REGEXP'", "'LIKE'", ... :
241
-	 *    val1 et val2 sont des champs et valeurs à utiliser dans la comparaison
242
-	 *    suivant cet ordre : "val1 operateur val2".
243
-	 *    Exemple : $boucle->where[] = array("'='", "'articles.statut'", "'\"publie\"'");
244
-	 * - "'AND'", "'OR'", "'NOT'" :
245
-	 *    dans ce cas val1 et val2 sont également des expressions
246
-	 *    de comparaison complètes, et peuvent être eux-même des tableaux comme $expr
247
-	 *    Exemples :
248
-	 *    $boucle->where[] = array("'OR'", $expr1, $expr2);
249
-	 *    $boucle->where[] = array("'NOT'", $expr); // val2 n'existe pas avec NOT
250
-	 *
251
-	 * D'autres noms sont possibles pour l'opérateur (le nombre de valeurs diffère) :
252
-	 * - "'SELF'", "'SUBSELECT'" : indiquent des sous requêtes
253
-	 * - "'?'" : indique une condition à faire évaluer (val1 ? val2 : val3)
254
-	 */
255
-	public array $where = [];
256
-
257
-	public array $join = [];
258
-	public array $having = [];
259
-	public $limit = '';
260
-	public array $group = [];
261
-	public array $order = [];
262
-	public array $default_order = [];
263
-	public string $date = 'date';
264
-	public string $hash = '';
265
-	public $in = '';
266
-	public bool $sous_requete = false;
267
-
268
-	/**
269
-	 * Code PHP qui sera ajouté en tout début de la fonction de boucle
270
-	 *
271
-	 * Il sert à insérer le code calculant une hierarchie
272
-	 */
273
-	public string $hierarchie = '';
274
-
275
-	// champs pour la construction du corps PHP
276
-
277
-	/**
278
-	 * Description des sources de données de la boucle
279
-	 *
280
-	 * Description des données de la boucle issu de trouver_table
281
-	 * dans le cadre de l'itérateur SQL et contenant au moins l'index 'field'.
282
-	 *
283
-	 * @see base_trouver_table_dist()
284
-	 */
285
-	public array $show = [];
286
-
287
-	/**
288
-	 * Nom de la table SQL principale de la boucle, sans son préfixe
289
-	 */
290
-	public string $id_table = '';
291
-
292
-	/**
293
-	 * Nom de la clé primaire de la table SQL principale de la boucle
294
-	 */
295
-	public string $primary = '';
296
-
297
-	/**
298
-	 * Code PHP compilé de la boucle
299
-	 *
300
-	 * FIXME: un seul type (string ?)
301
-	 *
302
-	 * - false: boucle fautive ?
303
-	 *
304
-	 * @var string|false
305
-	 */
306
-	public $return = '';
307
-
308
-	public $numrows = false;
309
-	public $cptrows = false;
310
-
311
-	/**
312
-	 * Description du squelette
313
-	 *
314
-	 * Sert pour la gestion d'erreur et la production de code dependant du contexte
315
-	 *
316
-	 * Peut contenir les index :
317
-	 *
318
-	 * - nom : Nom du fichier de cache
319
-	 * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser)
320
-	 * - sourcefile : Chemin du squelette
321
-	 * - squelette : Code du squelette
322
-	 * - id_mere : Identifiant de la boucle parente
323
-	 * - documents : Pour embed et img dans les textes
324
-	 * - session : Pour un cache sessionné par auteur
325
-	 * - niv : Niveau de tabulation
326
-	 */
327
-	public array $descr = [];
328
-
329
-	/** Numéro de ligne dans le code source du squelette */
330
-	public int $ligne = 0;
331
-
332
-
333
-	/**
334
-	 * table pour stocker les modificateurs de boucle tels que tout, plat ...,
335
-	 * utilisable par les plugins egalement
336
-	 *
337
-	 * @var array<string, mixed>
338
-	 */
339
-	public array $modificateur = [];
340
-
341
-	/**
342
-	 * Type d'itérateur utilisé pour cette boucle
343
-	 *
344
-	 * - 'SQL' dans le cadre d'une boucle sur une table SQL
345
-	 * - 'DATA' pour l'itérateur DATA, ...
346
-	 *
347
-	 * @var string
348
-	 */
349
-	public string $iterateur = ''; // type d'iterateur
350
-
351
-	/**
352
-	 * @var array $debug Textes qui seront insérés dans l’entête de boucle du mode debug
353
-	 */
354
-	public array $debug = [];
355
-
356
-	/**
357
-	 * Index de la boucle dont le champ présent dans cette boucle est originaire,
358
-	 * notamment si le champ a été trouve dans une boucle parente
359
-	 *
360
-	 * Tableau nom du champ => index de boucle
361
-	*/
362
-	public array $index_champ = [];
363
-
364
-	/** Résultat de la compilation (?) (sert au débusqueur) */
365
-	public string $code = '';
366
-
367
-	/** Source des filtres (compatibilité) (?) */
368
-	public array $fonctions = [];
369
-
370
-	// obsoletes, conserves provisoirement pour compatibilite
371
-	public $tout = false;
372
-	public $plat = false;
373
-	public $lien = false;
10
+    /** Type de noeud */
11
+    public string $type = 'boucle';
12
+
13
+    /** Identifiant de la boucle */
14
+    public string $id_boucle;
15
+
16
+    /** Identifiant de la boucle parente */
17
+    public string $id_parent = '';
18
+
19
+    /** Un nom explicite qui peut être affecté manuellement à certaines boucles générées */
20
+    public string $nom = '';
21
+
22
+    /**
23
+     * Partie avant toujours affichee
24
+     *
25
+     * @var string|array
26
+     */
27
+    public $preaff = '';
28
+
29
+    /**
30
+     * Partie optionnelle avant
31
+     *
32
+     * @var string|array
33
+     */
34
+    public $avant = '';
35
+
36
+    /**
37
+     * Pour chaque élément
38
+     *
39
+     * @var string|array
40
+     */
41
+    public $milieu = '';
42
+
43
+    /**
44
+     * Partie optionnelle après
45
+     *
46
+     * @var string|array
47
+     */
48
+    public $apres = '';
49
+
50
+    /**
51
+     * Partie alternative, si pas de résultat dans la boucle
52
+     *
53
+     * @var string|array
54
+     */
55
+    public $altern = '';
56
+
57
+    /**
58
+     * Partie apres toujours affichee
59
+     *
60
+     * @var string|array
61
+     */
62
+    public $postaff = '';
63
+
64
+
65
+    /**
66
+     * La boucle doit-elle sélectionner la langue ?
67
+     *
68
+     * Valeurs : '', 'oui', 'non'
69
+     */
70
+    public string $lang_select = '';
71
+
72
+    /**
73
+     * Alias de table d'application de la requête ou nom complet de la table SQL
74
+     *
75
+     * FIXME: un seul typage (string ?)
76
+     *
77
+     * @var string|false|null
78
+     */
79
+    public $type_requete = null;
80
+
81
+    /**
82
+     * La table est elle optionnelle ?
83
+     *
84
+     * Si oui, aucune erreur ne sera générée si la table demandée n'est pas présente
85
+     */
86
+    public bool $table_optionnelle = false;
87
+    public string $type_table_optionnelle = '';
88
+
89
+    /**
90
+     * Nom du fichier de connexion
91
+     */
92
+    public string $sql_serveur = '';
93
+
94
+    /**
95
+     * Paramètres de la boucle
96
+     *
97
+     * Description des paramètres passés à la boucle, qui servent ensuite
98
+     * au calcul des critères
99
+     *
100
+     * FIXME: type unique.
101
+     * @var false|array
102
+     *     - false: erreur de syntaxe
103
+     */
104
+    public $param = [];
105
+
106
+    /**
107
+     * Critères de la boucle
108
+     *
109
+     * FIXME: type array unique.
110
+     *
111
+     * @var string|Critere[]
112
+     * - string: phrasage (code brut). Il reste si erreur de critère
113
+     * - array: analyse correcte des critères...
114
+     */
115
+    public $criteres = [];
116
+
117
+    /**
118
+     * Textes insérés entre 2 éléments de boucle (critère inter)
119
+     *
120
+     * @var string[]
121
+     */
122
+    public array $separateur = [];
123
+
124
+    /**
125
+     * Liste des jointures possibles avec cette table
126
+     *
127
+     * Les jointures par défaut de la table sont complétées en priorité
128
+     * des jointures déclarées explicitement sur la boucle
129
+     *
130
+     * @see base_trouver_table_dist()
131
+     */
132
+    public array $jointures = [];
133
+
134
+    /**
135
+     * Jointures explicites avec cette table
136
+     *
137
+     * Ces jointures sont utilisées en priorité par rapport aux jointures
138
+     * normales possibles pour retrouver les colonnes demandées extérieures
139
+     * à la boucle.
140
+     *
141
+     * @var string|bool
142
+     */
143
+    public $jointures_explicites = false;
144
+
145
+    /**
146
+     * Nom de la variable PHP stockant le noms de doublons utilisés "$doublons_index"
147
+     */
148
+    public string $doublons = '';
149
+
150
+    /**
151
+     * Code PHP ajouté au début de chaque itération de boucle.
152
+     *
153
+     * Utilisé entre autre par les critères {pagination}, {n-a,b}, {a/b}...
154
+     */
155
+    public string $partie = '';
156
+
157
+    /**
158
+     * Nombre de divisions de la boucle, d'éléments à afficher,
159
+     * ou de soustractions d'éléments à faire
160
+     *
161
+     * Dans les critères limitant le nombre d'éléments affichés
162
+     * {a,b}, {a,n-b}, {a/b}, {pagination b}, b est affecté à total_parties.
163
+     */
164
+    public string $total_parties = '';
165
+
166
+    /**
167
+     * Code PHP ajouté avant l'itération de boucle.
168
+     *
169
+     * Utilisé entre autre par les critères {pagination}, {a,b}, {a/b}
170
+     * pour initialiser les variables de début et de fin d'itération.
171
+     */
172
+    public string $mode_partie = '';
173
+
174
+    /**
175
+     * Identifiant d'une boucle qui appelle celle-ci de manière récursive
176
+     *
177
+     * Si une boucle est appelée de manière récursive quelque part par
178
+     * une autre boucle comme <BOUCLE_rec(boucle_identifiant) />, cette
179
+     * boucle (identifiant) reçoit dans cette propriété l'identifiant
180
+     * de l'appelant (rec)
181
+     */
182
+    public string $externe = '';
183
+
184
+    // champs pour la construction de la requete SQL
185
+
186
+    /**
187
+     * Liste des champs à récupérer par la boucle
188
+     *
189
+     * Expression 'table.nom_champ' ou calculée 'nom_champ AS x'
190
+     *
191
+     * @var string[]
192
+     */
193
+    public array $select = [];
194
+
195
+    /**
196
+     * Liste des alias / tables SQL utilisées dans la boucle
197
+     *
198
+     * L'index est un identifiant (xx dans spip_xx assez souvent) qui servira
199
+     * d'alias au nom de la table ; la valeur est le nom de la table SQL désirée.
200
+     *
201
+     * L'index 0 peut définir le type de sources de données de l'itérateur DATA
202
+     *
203
+     * @var string[]
204
+     */
205
+    public array $from = [];
206
+
207
+    /**
208
+     * Liste des alias / type de jointures utilisées dans la boucle
209
+     *
210
+     * L'index est le nom d'alias (comme pour la propriété $from), et la valeur
211
+     * un type de jointure parmi 'INNER', 'LEFT', 'RIGHT', 'OUTER'.
212
+     *
213
+     * Lorsque le type n'est pas déclaré pour un alias, c'est 'INNER'
214
+     * qui sera utilisé par défaut (créant donc un INNER JOIN).
215
+     *
216
+     * @var string[]
217
+     */
218
+    public array $from_type = [];
219
+
220
+    /**
221
+     * Liste des conditions WHERE de la boucle
222
+     *
223
+     * Permet de restreindre les éléments retournés par une boucle
224
+     * en fonctions des conditions transmises dans ce tableau.
225
+     *
226
+     * Ce tableau peut avoir plusieurs niveaux de profondeur.
227
+     *
228
+     * Les éléments du premier niveau sont reliés par des AND, donc
229
+     * chaque élément ajouté directement au where par
230
+     * $boucle->where[] = array(...) ou $boucle->where[] = "'expression'"
231
+     * est une condition AND en plus.
232
+     *
233
+     * Par contre, lorsqu'on indique un tableau, il peut décrire des relations
234
+     * internes différentes. Soit $expr un tableau d'expressions quelconques de 3 valeurs :
235
+     * $expr = array(operateur, val1, val2)
236
+     *
237
+     * Ces 3 valeurs sont des expressions PHP. L'index 0 désigne l'opérateur
238
+     * à réaliser tel que :
239
+     *
240
+     * - "'='" , "'>='", "'<'", "'IN'", "'REGEXP'", "'LIKE'", ... :
241
+     *    val1 et val2 sont des champs et valeurs à utiliser dans la comparaison
242
+     *    suivant cet ordre : "val1 operateur val2".
243
+     *    Exemple : $boucle->where[] = array("'='", "'articles.statut'", "'\"publie\"'");
244
+     * - "'AND'", "'OR'", "'NOT'" :
245
+     *    dans ce cas val1 et val2 sont également des expressions
246
+     *    de comparaison complètes, et peuvent être eux-même des tableaux comme $expr
247
+     *    Exemples :
248
+     *    $boucle->where[] = array("'OR'", $expr1, $expr2);
249
+     *    $boucle->where[] = array("'NOT'", $expr); // val2 n'existe pas avec NOT
250
+     *
251
+     * D'autres noms sont possibles pour l'opérateur (le nombre de valeurs diffère) :
252
+     * - "'SELF'", "'SUBSELECT'" : indiquent des sous requêtes
253
+     * - "'?'" : indique une condition à faire évaluer (val1 ? val2 : val3)
254
+     */
255
+    public array $where = [];
256
+
257
+    public array $join = [];
258
+    public array $having = [];
259
+    public $limit = '';
260
+    public array $group = [];
261
+    public array $order = [];
262
+    public array $default_order = [];
263
+    public string $date = 'date';
264
+    public string $hash = '';
265
+    public $in = '';
266
+    public bool $sous_requete = false;
267
+
268
+    /**
269
+     * Code PHP qui sera ajouté en tout début de la fonction de boucle
270
+     *
271
+     * Il sert à insérer le code calculant une hierarchie
272
+     */
273
+    public string $hierarchie = '';
274
+
275
+    // champs pour la construction du corps PHP
276
+
277
+    /**
278
+     * Description des sources de données de la boucle
279
+     *
280
+     * Description des données de la boucle issu de trouver_table
281
+     * dans le cadre de l'itérateur SQL et contenant au moins l'index 'field'.
282
+     *
283
+     * @see base_trouver_table_dist()
284
+     */
285
+    public array $show = [];
286
+
287
+    /**
288
+     * Nom de la table SQL principale de la boucle, sans son préfixe
289
+     */
290
+    public string $id_table = '';
291
+
292
+    /**
293
+     * Nom de la clé primaire de la table SQL principale de la boucle
294
+     */
295
+    public string $primary = '';
296
+
297
+    /**
298
+     * Code PHP compilé de la boucle
299
+     *
300
+     * FIXME: un seul type (string ?)
301
+     *
302
+     * - false: boucle fautive ?
303
+     *
304
+     * @var string|false
305
+     */
306
+    public $return = '';
307
+
308
+    public $numrows = false;
309
+    public $cptrows = false;
310
+
311
+    /**
312
+     * Description du squelette
313
+     *
314
+     * Sert pour la gestion d'erreur et la production de code dependant du contexte
315
+     *
316
+     * Peut contenir les index :
317
+     *
318
+     * - nom : Nom du fichier de cache
319
+     * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser)
320
+     * - sourcefile : Chemin du squelette
321
+     * - squelette : Code du squelette
322
+     * - id_mere : Identifiant de la boucle parente
323
+     * - documents : Pour embed et img dans les textes
324
+     * - session : Pour un cache sessionné par auteur
325
+     * - niv : Niveau de tabulation
326
+     */
327
+    public array $descr = [];
328
+
329
+    /** Numéro de ligne dans le code source du squelette */
330
+    public int $ligne = 0;
331
+
332
+
333
+    /**
334
+     * table pour stocker les modificateurs de boucle tels que tout, plat ...,
335
+     * utilisable par les plugins egalement
336
+     *
337
+     * @var array<string, mixed>
338
+     */
339
+    public array $modificateur = [];
340
+
341
+    /**
342
+     * Type d'itérateur utilisé pour cette boucle
343
+     *
344
+     * - 'SQL' dans le cadre d'une boucle sur une table SQL
345
+     * - 'DATA' pour l'itérateur DATA, ...
346
+     *
347
+     * @var string
348
+     */
349
+    public string $iterateur = ''; // type d'iterateur
350
+
351
+    /**
352
+     * @var array $debug Textes qui seront insérés dans l’entête de boucle du mode debug
353
+     */
354
+    public array $debug = [];
355
+
356
+    /**
357
+     * Index de la boucle dont le champ présent dans cette boucle est originaire,
358
+     * notamment si le champ a été trouve dans une boucle parente
359
+     *
360
+     * Tableau nom du champ => index de boucle
361
+     */
362
+    public array $index_champ = [];
363
+
364
+    /** Résultat de la compilation (?) (sert au débusqueur) */
365
+    public string $code = '';
366
+
367
+    /** Source des filtres (compatibilité) (?) */
368
+    public array $fonctions = [];
369
+
370
+    // obsoletes, conserves provisoirement pour compatibilite
371
+    public $tout = false;
372
+    public $plat = false;
373
+    public $lien = false;
374 374
 }
Please login to merge, or discard this patch.
ecrire/tests/bootstrap.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -9,22 +9,22 @@  discard block
 block discarded – undo
9 9
 
10 10
 // pas en cli ? passe ton chemin ! (ce script est un vilain trou de securite)
11 11
 if (PHP_SAPI !== 'cli') {
12
-	throw new RuntimeException('Operation not allowed.');
12
+    throw new RuntimeException('Operation not allowed.');
13 13
 }
14 14
 
15 15
 // let's go spip
16 16
 if (!defined('_SPIP_TEST_INC')) {
17
-	define('_SPIP_TEST_INC', dirname(__FILE__, 2));
17
+    define('_SPIP_TEST_INC', dirname(__FILE__, 2));
18 18
 }
19 19
 
20 20
 // si rien defini on va dans le public
21 21
 
22 22
 if (!defined('_SPIP_TEST_CHDIR')) {
23
-	define('_SPIP_TEST_CHDIR', dirname(_SPIP_TEST_INC));
23
+    define('_SPIP_TEST_CHDIR', dirname(_SPIP_TEST_INC));
24 24
 }
25 25
 
26 26
 if (!defined('_DIR_TESTS')) {
27
-	define('_DIR_TESTS', substr(_SPIP_TEST_INC, strlen(_SPIP_TEST_CHDIR) + 1) . '/');
27
+    define('_DIR_TESTS', substr(_SPIP_TEST_INC, strlen(_SPIP_TEST_CHDIR) + 1) . '/');
28 28
 }
29 29
 
30 30
 // chdir pour charger SPIP
@@ -34,8 +34,8 @@  discard block
 block discarded – undo
34 34
 
35 35
 // pour notice sur recuperer_fond()
36 36
 if (!isset($GLOBALS['spip_lang'])) {
37
-	include_spip('inc/lang');
38
-	utiliser_langue_visiteur();
37
+    include_spip('inc/lang');
38
+    utiliser_langue_visiteur();
39 39
 }
40 40
 
41 41
 $GLOBALS['taille_des_logs'] = 1024;
@@ -46,16 +46,16 @@  discard block
 block discarded – undo
46 46
 @error_reporting(E_ALL);
47 47
 
48 48
 function spip_tests_loger_webmestre() {
49
-	// il faut charger une session webmestre
50
-	include_spip('base/abstract_sql');
51
-	$webmestre = sql_fetsel('*', 'spip_auteurs', "statut='0minirezo' AND webmestre='oui'", '', 'id_auteur', '0,1');
52
-	include_spip('inc/auth');
53
-	auth_loger($webmestre);
49
+    // il faut charger une session webmestre
50
+    include_spip('base/abstract_sql');
51
+    $webmestre = sql_fetsel('*', 'spip_auteurs', "statut='0minirezo' AND webmestre='oui'", '', 'id_auteur', '0,1');
52
+    include_spip('inc/auth');
53
+    auth_loger($webmestre);
54 54
 }
55 55
 
56 56
 function spip_tests_deloger_webmestre() {
57
-	if (!empty($GLOBALS['visiteur_session']['id_auteur'])) {
58
-		supprimer_sessions($GLOBALS['visiteur_session']['id_auteur'], false);
59
-	}
60
-	$GLOBALS['visiteur_session'] = [];
57
+    if (!empty($GLOBALS['visiteur_session']['id_auteur'])) {
58
+        supprimer_sessions($GLOBALS['visiteur_session']['id_auteur'], false);
59
+    }
60
+    $GLOBALS['visiteur_session'] = [];
61 61
 }
Please login to merge, or discard this patch.