Completed
Push — master ( 9b54d2...c65e43 )
by cam
01:57
created
ecrire/inc/distant.php 3 patches
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -220,8 +220,7 @@
 block discarded – undo
220 220
 						break;
221 221
 					}
222 222
 				}
223
-			}
224
-			else {
223
+			} else {
225 224
 				$ip = false;
226 225
 			}
227 226
 		}
Please login to merge, or discard this patch.
Indentation   +1100 added lines, -1100 removed lines patch added patch discarded remove patch
@@ -17,32 +17,32 @@  discard block
 block discarded – undo
17 17
  * @package SPIP\Core\Distant
18 18
  **/
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 if (!defined('_INC_DISTANT_VERSION_HTTP')) {
24
-	define('_INC_DISTANT_VERSION_HTTP', 'HTTP/1.0');
24
+    define('_INC_DISTANT_VERSION_HTTP', 'HTTP/1.0');
25 25
 }
26 26
 if (!defined('_INC_DISTANT_CONTENT_ENCODING')) {
27
-	define('_INC_DISTANT_CONTENT_ENCODING', 'gzip');
27
+    define('_INC_DISTANT_CONTENT_ENCODING', 'gzip');
28 28
 }
29 29
 if (!defined('_INC_DISTANT_USER_AGENT')) {
30
-	define('_INC_DISTANT_USER_AGENT', 'SPIP-' . $GLOBALS['spip_version_affichee'] . ' (' . $GLOBALS['home_server'] . ')');
30
+    define('_INC_DISTANT_USER_AGENT', 'SPIP-' . $GLOBALS['spip_version_affichee'] . ' (' . $GLOBALS['home_server'] . ')');
31 31
 }
32 32
 if (!defined('_INC_DISTANT_MAX_SIZE')) {
33
-	define('_INC_DISTANT_MAX_SIZE', 2_097_152);
33
+    define('_INC_DISTANT_MAX_SIZE', 2_097_152);
34 34
 }
35 35
 if (!defined('_INC_DISTANT_CONNECT_TIMEOUT')) {
36
-	define('_INC_DISTANT_CONNECT_TIMEOUT', 10);
36
+    define('_INC_DISTANT_CONNECT_TIMEOUT', 10);
37 37
 }
38 38
 
39 39
 define('_REGEXP_COPIE_LOCALE', ',' 	.
40
-	preg_replace(
41
-		'@^https?:@',
42
-		'https?:',
43
-		($GLOBALS['meta']['adresse_site'] ?? '')
44
-	)
45
-	. '/?spip.php[?]action=acceder_document.*file=(.*)$,');
40
+    preg_replace(
41
+        '@^https?:@',
42
+        'https?:',
43
+        ($GLOBALS['meta']['adresse_site'] ?? '')
44
+    )
45
+    . '/?spip.php[?]action=acceder_document.*file=(.*)$,');
46 46
 
47 47
 //@define('_COPIE_LOCALE_MAX_SIZE',2097152); // poids (inc/utils l'a fait)
48 48
 
@@ -71,105 +71,105 @@  discard block
 block discarded – undo
71 71
  */
72 72
 function copie_locale($source, $mode = 'auto', $local = null, $taille_max = null, $callback_valider_url = null) {
73 73
 
74
-	// si c'est la protection de soi-meme, retourner le path
75
-	if ($mode !== 'force' && preg_match(_REGEXP_COPIE_LOCALE, $source, $match)) {
76
-		$source = substr((string) _DIR_IMG, strlen((string) _DIR_RACINE)) . urldecode($match[1]);
77
-
78
-		return @file_exists($source) ? $source : false;
79
-	}
80
-
81
-	if (is_null($local)) {
82
-		$local = fichier_copie_locale($source);
83
-	} else {
84
-		if (_DIR_RACINE && strncmp((string) _DIR_RACINE, $local, strlen((string) _DIR_RACINE)) == 0) {
85
-			$local = substr($local, strlen((string) _DIR_RACINE));
86
-		}
87
-	}
88
-
89
-	// si $local = '' c'est un fichier refuse par fichier_copie_locale(),
90
-	// par exemple un fichier qui ne figure pas dans nos documents ;
91
-	// dans ce cas on n'essaie pas de le telecharger pour ensuite echouer
92
-	if (!$local) {
93
-		return false;
94
-	}
95
-
96
-	$localrac = _DIR_RACINE . $local;
97
-	$t = ($mode === 'force') ? false : @file_exists($localrac);
98
-
99
-	// test d'existence du fichier
100
-	if ($mode === 'test') {
101
-		return $t ? $local : '';
102
-	}
103
-
104
-	// sinon voir si on doit/peut le telecharger
105
-	if ($local === $source || !tester_url_absolue($source)) {
106
-		return $t ? $local : '';
107
-	}
108
-
109
-	if ($mode === 'modif' || !$t) {
110
-		// passer par un fichier temporaire unique pour gerer les echecs en cours de recuperation
111
-		// et des eventuelles recuperations concurantes
112
-		include_spip('inc/acces');
113
-		if (!$taille_max) {
114
-			$taille_max = _COPIE_LOCALE_MAX_SIZE;
115
-		}
116
-		$localrac_tmp = $localrac . '.tmp';
117
-		$res = recuperer_url(
118
-			$source,
119
-			['file' => $localrac_tmp, 'taille_max' => $taille_max, 'if_modified_since' => $t ? filemtime($localrac) : '']
120
-		);
121
-
122
-		if (!$res || !$res['length'] && $res['status'] != 304) {
123
-			spip_log("copie_locale : Echec recuperation $source sur $localrac_tmp status : " . ($res ? $res['status'] : '-'), 'distant' . _LOG_INFO_IMPORTANTE);
124
-			@unlink($localrac_tmp);
125
-		} else {
126
-			spip_log("copie_locale : recuperation $source sur $localrac_tmp OK | taille " . $res['length'] . ' status ' . $res['status'], 'distant');
127
-		}
128
-		if (!$res || !$res['length']) {
129
-			// si $t c'est sans doute juste un not-modified-since
130
-			return $t ? $local : false;
131
-		}
132
-
133
-		// si option valider url, verifions que l'URL finale est acceptable
134
-		if (
135
-			$callback_valider_url
136
-			&& is_callable($callback_valider_url)
137
-			&& !$callback_valider_url($res['url'])
138
-		) {
139
-			spip_log('copie_locale : url finale ' . $res['url'] . " non valide, on refuse le fichier $localrac_tmp", 'distant' . _LOG_INFO_IMPORTANTE);
140
-			@unlink($localrac_tmp);
141
-			return $t ? $local : false;
142
-		}
143
-
144
-		// on peut renommer le fichier tmp
145
-		@rename($localrac_tmp, $localrac);
146
-
147
-		// si on retrouve l'extension
148
-		if (
149
-			!empty($res['headers'])
150
-			&& ($extension = distant_trouver_extension_selon_headers($source, $res['headers']))
151
-			&& ($sanitizer = charger_fonction($extension, 'sanitizer', true))
152
-		) {
153
-			$sanitizer($localrac);
154
-		}
155
-
156
-		// pour une eventuelle indexation
157
-		pipeline(
158
-			'post_edition',
159
-			[
160
-				'args' => [
161
-					'operation' => 'copie_locale',
162
-					'source' => $source,
163
-					'fichier' => $local,
164
-					'http_res' => $res['length'],
165
-					'url' => $res['url'],
166
-				],
167
-				'data' => null
168
-			]
169
-		);
170
-	}
171
-
172
-	return $local;
74
+    // si c'est la protection de soi-meme, retourner le path
75
+    if ($mode !== 'force' && preg_match(_REGEXP_COPIE_LOCALE, $source, $match)) {
76
+        $source = substr((string) _DIR_IMG, strlen((string) _DIR_RACINE)) . urldecode($match[1]);
77
+
78
+        return @file_exists($source) ? $source : false;
79
+    }
80
+
81
+    if (is_null($local)) {
82
+        $local = fichier_copie_locale($source);
83
+    } else {
84
+        if (_DIR_RACINE && strncmp((string) _DIR_RACINE, $local, strlen((string) _DIR_RACINE)) == 0) {
85
+            $local = substr($local, strlen((string) _DIR_RACINE));
86
+        }
87
+    }
88
+
89
+    // si $local = '' c'est un fichier refuse par fichier_copie_locale(),
90
+    // par exemple un fichier qui ne figure pas dans nos documents ;
91
+    // dans ce cas on n'essaie pas de le telecharger pour ensuite echouer
92
+    if (!$local) {
93
+        return false;
94
+    }
95
+
96
+    $localrac = _DIR_RACINE . $local;
97
+    $t = ($mode === 'force') ? false : @file_exists($localrac);
98
+
99
+    // test d'existence du fichier
100
+    if ($mode === 'test') {
101
+        return $t ? $local : '';
102
+    }
103
+
104
+    // sinon voir si on doit/peut le telecharger
105
+    if ($local === $source || !tester_url_absolue($source)) {
106
+        return $t ? $local : '';
107
+    }
108
+
109
+    if ($mode === 'modif' || !$t) {
110
+        // passer par un fichier temporaire unique pour gerer les echecs en cours de recuperation
111
+        // et des eventuelles recuperations concurantes
112
+        include_spip('inc/acces');
113
+        if (!$taille_max) {
114
+            $taille_max = _COPIE_LOCALE_MAX_SIZE;
115
+        }
116
+        $localrac_tmp = $localrac . '.tmp';
117
+        $res = recuperer_url(
118
+            $source,
119
+            ['file' => $localrac_tmp, 'taille_max' => $taille_max, 'if_modified_since' => $t ? filemtime($localrac) : '']
120
+        );
121
+
122
+        if (!$res || !$res['length'] && $res['status'] != 304) {
123
+            spip_log("copie_locale : Echec recuperation $source sur $localrac_tmp status : " . ($res ? $res['status'] : '-'), 'distant' . _LOG_INFO_IMPORTANTE);
124
+            @unlink($localrac_tmp);
125
+        } else {
126
+            spip_log("copie_locale : recuperation $source sur $localrac_tmp OK | taille " . $res['length'] . ' status ' . $res['status'], 'distant');
127
+        }
128
+        if (!$res || !$res['length']) {
129
+            // si $t c'est sans doute juste un not-modified-since
130
+            return $t ? $local : false;
131
+        }
132
+
133
+        // si option valider url, verifions que l'URL finale est acceptable
134
+        if (
135
+            $callback_valider_url
136
+            && is_callable($callback_valider_url)
137
+            && !$callback_valider_url($res['url'])
138
+        ) {
139
+            spip_log('copie_locale : url finale ' . $res['url'] . " non valide, on refuse le fichier $localrac_tmp", 'distant' . _LOG_INFO_IMPORTANTE);
140
+            @unlink($localrac_tmp);
141
+            return $t ? $local : false;
142
+        }
143
+
144
+        // on peut renommer le fichier tmp
145
+        @rename($localrac_tmp, $localrac);
146
+
147
+        // si on retrouve l'extension
148
+        if (
149
+            !empty($res['headers'])
150
+            && ($extension = distant_trouver_extension_selon_headers($source, $res['headers']))
151
+            && ($sanitizer = charger_fonction($extension, 'sanitizer', true))
152
+        ) {
153
+            $sanitizer($localrac);
154
+        }
155
+
156
+        // pour une eventuelle indexation
157
+        pipeline(
158
+            'post_edition',
159
+            [
160
+                'args' => [
161
+                    'operation' => 'copie_locale',
162
+                    'source' => $source,
163
+                    'fichier' => $local,
164
+                    'http_res' => $res['length'],
165
+                    'url' => $res['url'],
166
+                ],
167
+                'data' => null
168
+            ]
169
+        );
170
+    }
171
+
172
+    return $local;
173 173
 }
174 174
 
175 175
 /**
@@ -184,97 +184,97 @@  discard block
 block discarded – undo
184 184
  *   url ou false en cas d'echec
185 185
  */
186 186
 function valider_url_distante($url, $known_hosts = []) {
187
-	if (!function_exists('protocole_verifier')) {
188
-		include_spip('inc/filtres_mini');
189
-	}
190
-
191
-	if (!protocole_verifier($url, ['http', 'https'])) {
192
-		return false;
193
-	}
194
-
195
-	$parsed_url = parse_url($url);
196
-	if (!$parsed_url || empty($parsed_url['host'])) {
197
-		return false;
198
-	}
199
-
200
-	if (isset($parsed_url['user']) || isset($parsed_url['pass'])) {
201
-		return false;
202
-	}
203
-
204
-	if (false !== strpbrk($parsed_url['host'], ':#?[]')) {
205
-		return false;
206
-	}
207
-
208
-	if (!is_array($known_hosts)) {
209
-		$known_hosts = [$known_hosts];
210
-	}
211
-	$known_hosts[] = $GLOBALS['meta']['adresse_site'];
212
-	$known_hosts[] = url_de_base();
213
-	$known_hosts = pipeline('declarer_hosts_distants', $known_hosts);
214
-
215
-	$is_known_host = false;
216
-	foreach ($known_hosts as $known_host) {
217
-		$parse_known = parse_url((string) $known_host);
218
-		if (
219
-			$parse_known
220
-			&& strtolower($parse_known['host']) === strtolower($parsed_url['host'])
221
-		) {
222
-			$is_known_host = true;
223
-			break;
224
-		}
225
-	}
226
-
227
-	if (!$is_known_host) {
228
-		$host = trim($parsed_url['host'], '.');
229
-		if (! $ip = filter_var($host, FILTER_VALIDATE_IP)) {
230
-			$ip = gethostbyname($host);
231
-			if ($ip === $host) {
232
-				// Error condition for gethostbyname()
233
-				$ip = false;
234
-			}
235
-			if ($records = dns_get_record($host)) {
236
-				foreach ($records as $record) {
237
-					// il faut que le TTL soit suffisant afin d'etre certain que le copie_locale eventuel qui suit
238
-					// se fasse sur la meme IP
239
-					if ($record['ttl'] < 10) {
240
-						$ip = false;
241
-						break;
242
-					}
243
-				}
244
-			}
245
-			else {
246
-				$ip = false;
247
-			}
248
-		}
249
-		if ($ip && ! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
250
-			return false;
251
-		}
252
-	}
253
-
254
-	if (empty($parsed_url['port'])) {
255
-		return $url;
256
-	}
257
-
258
-	$port = $parsed_url['port'];
259
-	if ($port === 80 || $port === 443 || $port === 8080) {
260
-		return $url;
261
-	}
262
-
263
-	if ($is_known_host) {
264
-		foreach ($known_hosts as $known_host) {
265
-			$parse_known = parse_url((string) $known_host);
266
-			if (
267
-				$parse_known
268
-				&& !empty($parse_known['port'])
269
-				&& strtolower($parse_known['host']) === strtolower($parsed_url['host'])
270
-				&& $parse_known['port'] == $port
271
-			) {
272
-				return $url;
273
-			}
274
-		}
275
-	}
276
-
277
-	return false;
187
+    if (!function_exists('protocole_verifier')) {
188
+        include_spip('inc/filtres_mini');
189
+    }
190
+
191
+    if (!protocole_verifier($url, ['http', 'https'])) {
192
+        return false;
193
+    }
194
+
195
+    $parsed_url = parse_url($url);
196
+    if (!$parsed_url || empty($parsed_url['host'])) {
197
+        return false;
198
+    }
199
+
200
+    if (isset($parsed_url['user']) || isset($parsed_url['pass'])) {
201
+        return false;
202
+    }
203
+
204
+    if (false !== strpbrk($parsed_url['host'], ':#?[]')) {
205
+        return false;
206
+    }
207
+
208
+    if (!is_array($known_hosts)) {
209
+        $known_hosts = [$known_hosts];
210
+    }
211
+    $known_hosts[] = $GLOBALS['meta']['adresse_site'];
212
+    $known_hosts[] = url_de_base();
213
+    $known_hosts = pipeline('declarer_hosts_distants', $known_hosts);
214
+
215
+    $is_known_host = false;
216
+    foreach ($known_hosts as $known_host) {
217
+        $parse_known = parse_url((string) $known_host);
218
+        if (
219
+            $parse_known
220
+            && strtolower($parse_known['host']) === strtolower($parsed_url['host'])
221
+        ) {
222
+            $is_known_host = true;
223
+            break;
224
+        }
225
+    }
226
+
227
+    if (!$is_known_host) {
228
+        $host = trim($parsed_url['host'], '.');
229
+        if (! $ip = filter_var($host, FILTER_VALIDATE_IP)) {
230
+            $ip = gethostbyname($host);
231
+            if ($ip === $host) {
232
+                // Error condition for gethostbyname()
233
+                $ip = false;
234
+            }
235
+            if ($records = dns_get_record($host)) {
236
+                foreach ($records as $record) {
237
+                    // il faut que le TTL soit suffisant afin d'etre certain que le copie_locale eventuel qui suit
238
+                    // se fasse sur la meme IP
239
+                    if ($record['ttl'] < 10) {
240
+                        $ip = false;
241
+                        break;
242
+                    }
243
+                }
244
+            }
245
+            else {
246
+                $ip = false;
247
+            }
248
+        }
249
+        if ($ip && ! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
250
+            return false;
251
+        }
252
+    }
253
+
254
+    if (empty($parsed_url['port'])) {
255
+        return $url;
256
+    }
257
+
258
+    $port = $parsed_url['port'];
259
+    if ($port === 80 || $port === 443 || $port === 8080) {
260
+        return $url;
261
+    }
262
+
263
+    if ($is_known_host) {
264
+        foreach ($known_hosts as $known_host) {
265
+            $parse_known = parse_url((string) $known_host);
266
+            if (
267
+                $parse_known
268
+                && !empty($parse_known['port'])
269
+                && strtolower($parse_known['host']) === strtolower($parsed_url['host'])
270
+                && $parse_known['port'] == $port
271
+            ) {
272
+                return $url;
273
+            }
274
+        }
275
+    }
276
+
277
+    return false;
278 278
 }
279 279
 
280 280
 /**
@@ -294,87 +294,87 @@  discard block
 block discarded – undo
294 294
  */
295 295
 function prepare_donnees_post($donnees, $boundary = '') {
296 296
 
297
-	// permettre a la fonction qui a demande le post de formater elle meme ses donnees
298
-	// pour un appel soap par exemple
299
-	// l'entete est separe des donnees par un double retour a la ligne
300
-	// on s'occupe ici de passer tous les retours lignes (\r\n, \r ou \n) en \r\n
301
-	$chaine = '';
302
-	if (is_string($donnees) && strlen($donnees)) {
303
-		$entete = '';
304
-		// on repasse tous les \r\n et \r en simples \n
305
-		$donnees = str_replace("\r\n", "\n", $donnees);
306
-		$donnees = str_replace("\r", "\n", $donnees);
307
-		// un double retour a la ligne signifie la fin de l'entete et le debut des donnees
308
-		$p = strpos($donnees, "\n\n");
309
-		if ($p !== false) {
310
-			$entete = str_replace("\n", "\r\n", substr($donnees, 0, $p + 1));
311
-			$donnees = substr($donnees, $p + 2);
312
-		}
313
-		$chaine = str_replace("\n", "\r\n", $donnees);
314
-	} else {
315
-		/* boundary automatique */
316
-		// Si on a plus de 500 octects de donnees, on "boundarise"
317
-		if ($boundary === '') {
318
-			$taille = 0;
319
-			foreach ($donnees as $cle => $valeur) {
320
-				if (is_array($valeur)) {
321
-					foreach ($valeur as $val2) {
322
-						$taille += strlen((string) $val2);
323
-					}
324
-				} else {
325
-					// faut-il utiliser spip_strlen() dans inc/charsets ?
326
-					$taille += strlen((string) $valeur);
327
-				}
328
-			}
329
-			if ($taille > 500) {
330
-				$boundary = substr(md5(random_int(0, mt_getrandmax()) . 'spip'), 0, 8);
331
-			}
332
-		}
333
-
334
-		if (is_string($boundary) && strlen($boundary)) {
335
-			// fabrique une chaine HTTP pour un POST avec boundary
336
-			$entete = "Content-Type: multipart/form-data; boundary=$boundary\r\n";
337
-			if (is_array($donnees)) {
338
-				foreach ($donnees as $cle => $valeur) {
339
-					if (is_array($valeur)) {
340
-						foreach ($valeur as $val2) {
341
-							$chaine .= "\r\n--$boundary\r\n";
342
-							$chaine .= "Content-Disposition: form-data; name=\"{$cle}[]\"\r\n";
343
-							$chaine .= "\r\n";
344
-							$chaine .= $val2;
345
-						}
346
-					} else {
347
-						$chaine .= "\r\n--$boundary\r\n";
348
-						$chaine .= "Content-Disposition: form-data; name=\"$cle\"\r\n";
349
-						$chaine .= "\r\n";
350
-						$chaine .= $valeur;
351
-					}
352
-				}
353
-				$chaine .= "\r\n--$boundary\r\n";
354
-			}
355
-		} else {
356
-			// fabrique une chaine HTTP simple pour un POST
357
-			$entete = "Content-Type: application/x-www-form-urlencoded\r\n";
358
-			if (is_array($donnees)) {
359
-				$chaines = [];
360
-				foreach ($donnees as $cle => $valeur) {
361
-					if (is_array($valeur)) {
362
-						foreach ($valeur as $val2) {
363
-							$chaines[] = rawurlencode($cle) . '[]=' . rawurlencode((string) $val2);
364
-						}
365
-					} else {
366
-						$chaines[] = rawurlencode($cle) . '=' . rawurlencode((string) $valeur);
367
-					}
368
-				}
369
-				$chaine = implode('&', $chaines);
370
-				unset($chaines);
371
-			} else {
372
-				$chaine = $donnees;
373
-			}
374
-		}
375
-	}
376
-
377
-	return [$entete, $chaine];
297
+    // permettre a la fonction qui a demande le post de formater elle meme ses donnees
298
+    // pour un appel soap par exemple
299
+    // l'entete est separe des donnees par un double retour a la ligne
300
+    // on s'occupe ici de passer tous les retours lignes (\r\n, \r ou \n) en \r\n
301
+    $chaine = '';
302
+    if (is_string($donnees) && strlen($donnees)) {
303
+        $entete = '';
304
+        // on repasse tous les \r\n et \r en simples \n
305
+        $donnees = str_replace("\r\n", "\n", $donnees);
306
+        $donnees = str_replace("\r", "\n", $donnees);
307
+        // un double retour a la ligne signifie la fin de l'entete et le debut des donnees
308
+        $p = strpos($donnees, "\n\n");
309
+        if ($p !== false) {
310
+            $entete = str_replace("\n", "\r\n", substr($donnees, 0, $p + 1));
311
+            $donnees = substr($donnees, $p + 2);
312
+        }
313
+        $chaine = str_replace("\n", "\r\n", $donnees);
314
+    } else {
315
+        /* boundary automatique */
316
+        // Si on a plus de 500 octects de donnees, on "boundarise"
317
+        if ($boundary === '') {
318
+            $taille = 0;
319
+            foreach ($donnees as $cle => $valeur) {
320
+                if (is_array($valeur)) {
321
+                    foreach ($valeur as $val2) {
322
+                        $taille += strlen((string) $val2);
323
+                    }
324
+                } else {
325
+                    // faut-il utiliser spip_strlen() dans inc/charsets ?
326
+                    $taille += strlen((string) $valeur);
327
+                }
328
+            }
329
+            if ($taille > 500) {
330
+                $boundary = substr(md5(random_int(0, mt_getrandmax()) . 'spip'), 0, 8);
331
+            }
332
+        }
333
+
334
+        if (is_string($boundary) && strlen($boundary)) {
335
+            // fabrique une chaine HTTP pour un POST avec boundary
336
+            $entete = "Content-Type: multipart/form-data; boundary=$boundary\r\n";
337
+            if (is_array($donnees)) {
338
+                foreach ($donnees as $cle => $valeur) {
339
+                    if (is_array($valeur)) {
340
+                        foreach ($valeur as $val2) {
341
+                            $chaine .= "\r\n--$boundary\r\n";
342
+                            $chaine .= "Content-Disposition: form-data; name=\"{$cle}[]\"\r\n";
343
+                            $chaine .= "\r\n";
344
+                            $chaine .= $val2;
345
+                        }
346
+                    } else {
347
+                        $chaine .= "\r\n--$boundary\r\n";
348
+                        $chaine .= "Content-Disposition: form-data; name=\"$cle\"\r\n";
349
+                        $chaine .= "\r\n";
350
+                        $chaine .= $valeur;
351
+                    }
352
+                }
353
+                $chaine .= "\r\n--$boundary\r\n";
354
+            }
355
+        } else {
356
+            // fabrique une chaine HTTP simple pour un POST
357
+            $entete = "Content-Type: application/x-www-form-urlencoded\r\n";
358
+            if (is_array($donnees)) {
359
+                $chaines = [];
360
+                foreach ($donnees as $cle => $valeur) {
361
+                    if (is_array($valeur)) {
362
+                        foreach ($valeur as $val2) {
363
+                            $chaines[] = rawurlencode($cle) . '[]=' . rawurlencode((string) $val2);
364
+                        }
365
+                    } else {
366
+                        $chaines[] = rawurlencode($cle) . '=' . rawurlencode((string) $valeur);
367
+                    }
368
+                }
369
+                $chaine = implode('&', $chaines);
370
+                unset($chaines);
371
+            } else {
372
+                $chaine = $donnees;
373
+            }
374
+        }
375
+    }
376
+
377
+    return [$entete, $chaine];
378 378
 }
379 379
 
380 380
 /**
@@ -385,19 +385,19 @@  discard block
 block discarded – undo
385 385
  */
386 386
 function url_to_ascii($url_idn) {
387 387
 
388
-	if ($parts = parse_url($url_idn)) {
389
-		$host = $parts['host'];
390
-		if (!preg_match(',^[a-z0-9_\.\-]+$,i', $host)) {
391
-			$converter = new ToIdn();
392
-			$host_ascii = $converter->convert($host);
393
-			$url_idn = explode($host, $url_idn, 2);
394
-			$url_idn = implode($host_ascii, $url_idn);
395
-		}
396
-		// et on urlencode les char utf si besoin dans le path
397
-		$url_idn = preg_replace_callback('/[^\x20-\x7f]/', fn($match) => urlencode((string) $match[0]), $url_idn);
398
-	}
399
-
400
-	return $url_idn;
388
+    if ($parts = parse_url($url_idn)) {
389
+        $host = $parts['host'];
390
+        if (!preg_match(',^[a-z0-9_\.\-]+$,i', $host)) {
391
+            $converter = new ToIdn();
392
+            $host_ascii = $converter->convert($host);
393
+            $url_idn = explode($host, $url_idn, 2);
394
+            $url_idn = implode($host_ascii, $url_idn);
395
+        }
396
+        // et on urlencode les char utf si besoin dans le path
397
+        $url_idn = preg_replace_callback('/[^\x20-\x7f]/', fn($match) => urlencode((string) $match[0]), $url_idn);
398
+    }
399
+
400
+    return $url_idn;
401 401
 }
402 402
 
403 403
 /**
@@ -438,214 +438,214 @@  discard block
 block discarded – undo
438 438
  *     string file : nom du fichier si enregistre dans un fichier
439 439
  */
440 440
 function recuperer_url($url, $options = []) {
441
-	// Conserve la mémoire de la méthode fournit éventuellement
442
-	$methode_demandee = $options['methode'] ?? '';
443
-	$default = [
444
-		'transcoder' => false,
445
-		'methode' => 'GET',
446
-		'taille_max' => null,
447
-		'headers' => [],
448
-		'datas' => '',
449
-		'boundary' => '',
450
-		'refuser_gz' => false,
451
-		'if_modified_since' => '',
452
-		'uri_referer' => '',
453
-		'file' => '',
454
-		'follow_location' => 10,
455
-		'version_http' => _INC_DISTANT_VERSION_HTTP,
456
-	];
457
-	$options = array_merge($default, $options);
458
-	// copier directement dans un fichier ?
459
-	$copy = $options['file'];
460
-
461
-	if ($options['methode'] == 'HEAD') {
462
-		$options['taille_max'] = 0;
463
-	}
464
-	if (is_null($options['taille_max'])) {
465
-		$options['taille_max'] = $copy ? _COPIE_LOCALE_MAX_SIZE : _INC_DISTANT_MAX_SIZE;
466
-	}
467
-
468
-	spip_log('recuperer_url ' . $options['methode'] . " sur $url", 'distant' . _LOG_DEBUG);
469
-
470
-	// Ajout des en-têtes spécifiques si besoin
471
-	$formatted_data = '';
472
-	if (!empty($options['headers'])) {
473
-		foreach ($options['headers'] as $champ => $valeur) {
474
-			$formatted_data .= $champ . ': ' . $valeur . "\r\n";
475
-		}
476
-	}
477
-
478
-	if (!empty($options['datas'])) {
479
-		[$head, $postdata] = prepare_donnees_post($options['datas'], $options['boundary']);
480
-		$head .= $formatted_data;
481
-		if (stripos($head, 'Content-Length:') === false) {
482
-			$head .= 'Content-Length: ' . strlen((string) $postdata) . "\r\n";
483
-		}
484
-		$formatted_data = $head . "\r\n" . $postdata;
485
-		if (
486
-			strlen((string) $postdata) && !$methode_demandee
487
-		) {
488
-			$options['methode'] = 'POST';
489
-		}
490
-	} elseif ($formatted_data) {
491
-		$formatted_data .= "\r\n";
492
-	}
493
-
494
-	// Accepter les URLs au format feed:// ou qui ont oublie le http:// ou les urls relatives au protocole
495
-	$url = preg_replace(',^feed://,i', 'http://', $url);
496
-	if (!tester_url_absolue($url)) {
497
-		$url = 'http://' . $url;
498
-	} elseif (str_starts_with($url, '//')) {
499
-		$url = 'http:' . $url;
500
-	}
501
-
502
-	$url = url_to_ascii($url);
503
-
504
-	$result = [
505
-		'status' => 0,
506
-		'headers' => '',
507
-		'page' => '',
508
-		'length' => 0,
509
-		'last_modified' => '',
510
-		'location' => '',
511
-		'url' => $url
512
-	];
513
-
514
-	// si on ecrit directement dans un fichier, pour ne pas manipuler en memoire refuser gz
515
-	$refuser_gz = ($options['refuser_gz'] || $copy);
516
-
517
-	// ouvrir la connexion et envoyer la requete et ses en-tetes
518
-	[$handle, $fopen] = init_http(
519
-		$options['methode'],
520
-		$url,
521
-		$refuser_gz,
522
-		$options['uri_referer'],
523
-		$formatted_data,
524
-		$options['version_http'],
525
-		$options['if_modified_since']
526
-	);
527
-	if (!$handle) {
528
-		spip_log("ECHEC init_http $url", 'distant' . _LOG_ERREUR);
529
-
530
-		return false;
531
-	}
532
-
533
-	// Sauf en fopen, envoyer le flux d'entree
534
-	// et recuperer les en-tetes de reponses
535
-	if (!$fopen) {
536
-		$res = recuperer_entetes_complets($handle, $options['if_modified_since']);
537
-		if (!$res) {
538
-			fclose($handle);
539
-			$t = @parse_url($url);
540
-			$host = $t['host'];
541
-			// Chinoisierie inexplicable pour contrer
542
-			// les actions liberticides de l'empire du milieu
543
-			if (
544
-				!need_proxy($host)
545
-				&& ($res = @file_get_contents($url))
546
-			) {
547
-				$result['length'] = strlen($res);
548
-				if ($copy) {
549
-					ecrire_fichier($copy, $res);
550
-					$result['file'] = $copy;
551
-				} else {
552
-					$result['page'] = $res;
553
-				}
554
-				$res = [
555
-					'status' => 200,
556
-				];
557
-			} else {
558
-				spip_log("ECHEC chinoiserie $url", 'distant' . _LOG_ERREUR);
559
-				return false;
560
-			}
561
-		} elseif ($res['location'] && $options['follow_location']) {
562
-			$options['follow_location']--;
563
-			fclose($handle);
564
-			include_spip('inc/filtres');
565
-			$url = suivre_lien($url, $res['location']);
566
-
567
-			// une redirection doit se faire en GET, sauf status explicite 307 ou 308 qui indique de garder la meme methode
568
-			if (
569
-				$options['methode'] !== 'GET'
570
-				&& (empty($res['status']) || !in_array($res['status'], [307, 308]))
571
-			) {
572
-				$options['methode'] = 'GET';
573
-				$options['datas'] = '';
574
-			}
575
-			spip_log('recuperer_url recommence ' . $options['methode'] . " sur $url", 'distant' . _LOG_DEBUG);
576
-
577
-			return recuperer_url($url, $options);
578
-		} elseif ($res['status'] !== 200) {
579
-			spip_log('HTTP status ' . $res['status'] . " pour $url", 'distant');
580
-		}
581
-		$result['status'] = $res['status'];
582
-		if (isset($res['headers'])) {
583
-			$result['headers'] = $res['headers'];
584
-		}
585
-		if (isset($res['last_modified'])) {
586
-			$result['last_modified'] = $res['last_modified'];
587
-		}
588
-		if (isset($res['location'])) {
589
-			$result['location'] = $res['location'];
590
-		}
591
-	}
592
-
593
-	// on ne veut que les entetes
594
-	if (!$options['taille_max'] || $options['methode'] == 'HEAD' || $result['status'] == '304') {
595
-		spip_log('RESULTAT recuperer_url ' . $options['methode'] . " sur $url : " . json_encode($result, JSON_THROW_ON_ERROR), 'distant' . _LOG_DEBUG);
596
-		return $result;
597
-	}
598
-
599
-
600
-	// s'il faut deballer, le faire via un fichier temporaire
601
-	// sinon la memoire explose pour les gros flux
602
-
603
-	$gz = false;
604
-	if (preg_match(",\bContent-Encoding: .*gzip,is", (string) $result['headers'])) {
605
-		$gz = (_DIR_TMP . md5(uniqid(random_int(0, mt_getrandmax()))) . '.tmp.gz');
606
-	}
607
-
608
-	// si on a pas deja recuperer le contenu par une methode detournee
609
-	if (!$result['length']) {
610
-		$res = recuperer_body($handle, $options['taille_max'], $gz ?: $copy);
611
-		fclose($handle);
612
-		if ($copy) {
613
-			$result['length'] = $res;
614
-			$result['file'] = $copy;
615
-		} elseif ($res) {
616
-			$result['page'] = &$res;
617
-			$result['length'] = strlen($result['page']);
618
-		}
619
-		if (!$result['status']) {
620
-			$result['status'] = 200; // on a reussi, donc !
621
-		}
622
-	}
623
-	if (!$result['page']) {
624
-		return $result;
625
-	}
626
-
627
-	// Decompresser au besoin
628
-	if ($gz) {
629
-		$result['page'] = implode('', gzfile($gz));
630
-		supprimer_fichier($gz);
631
-	}
632
-
633
-	// Faut-il l'importer dans notre charset local ?
634
-	if ($options['transcoder']) {
635
-		include_spip('inc/charsets');
636
-		$result['page'] = transcoder_page($result['page'], $result['headers']);
637
-	}
638
-
639
-	try {
640
-		$trace = json_decode(json_encode($result, JSON_THROW_ON_ERROR), true, 512, JSON_THROW_ON_ERROR);
641
-	} catch (JsonException $e) {
642
-		$trace = [];
643
-		spip_log('Failed to parse Json data : ' . $e->getMessage(), _LOG_ERREUR);
644
-	}
645
-	$trace['page'] = '...';
646
-	spip_log('RESULTAT recuperer_url ' . $options['methode'] . " sur $url : " . json_encode($trace, JSON_THROW_ON_ERROR), 'distant' . _LOG_DEBUG);
647
-
648
-	return $result;
441
+    // Conserve la mémoire de la méthode fournit éventuellement
442
+    $methode_demandee = $options['methode'] ?? '';
443
+    $default = [
444
+        'transcoder' => false,
445
+        'methode' => 'GET',
446
+        'taille_max' => null,
447
+        'headers' => [],
448
+        'datas' => '',
449
+        'boundary' => '',
450
+        'refuser_gz' => false,
451
+        'if_modified_since' => '',
452
+        'uri_referer' => '',
453
+        'file' => '',
454
+        'follow_location' => 10,
455
+        'version_http' => _INC_DISTANT_VERSION_HTTP,
456
+    ];
457
+    $options = array_merge($default, $options);
458
+    // copier directement dans un fichier ?
459
+    $copy = $options['file'];
460
+
461
+    if ($options['methode'] == 'HEAD') {
462
+        $options['taille_max'] = 0;
463
+    }
464
+    if (is_null($options['taille_max'])) {
465
+        $options['taille_max'] = $copy ? _COPIE_LOCALE_MAX_SIZE : _INC_DISTANT_MAX_SIZE;
466
+    }
467
+
468
+    spip_log('recuperer_url ' . $options['methode'] . " sur $url", 'distant' . _LOG_DEBUG);
469
+
470
+    // Ajout des en-têtes spécifiques si besoin
471
+    $formatted_data = '';
472
+    if (!empty($options['headers'])) {
473
+        foreach ($options['headers'] as $champ => $valeur) {
474
+            $formatted_data .= $champ . ': ' . $valeur . "\r\n";
475
+        }
476
+    }
477
+
478
+    if (!empty($options['datas'])) {
479
+        [$head, $postdata] = prepare_donnees_post($options['datas'], $options['boundary']);
480
+        $head .= $formatted_data;
481
+        if (stripos($head, 'Content-Length:') === false) {
482
+            $head .= 'Content-Length: ' . strlen((string) $postdata) . "\r\n";
483
+        }
484
+        $formatted_data = $head . "\r\n" . $postdata;
485
+        if (
486
+            strlen((string) $postdata) && !$methode_demandee
487
+        ) {
488
+            $options['methode'] = 'POST';
489
+        }
490
+    } elseif ($formatted_data) {
491
+        $formatted_data .= "\r\n";
492
+    }
493
+
494
+    // Accepter les URLs au format feed:// ou qui ont oublie le http:// ou les urls relatives au protocole
495
+    $url = preg_replace(',^feed://,i', 'http://', $url);
496
+    if (!tester_url_absolue($url)) {
497
+        $url = 'http://' . $url;
498
+    } elseif (str_starts_with($url, '//')) {
499
+        $url = 'http:' . $url;
500
+    }
501
+
502
+    $url = url_to_ascii($url);
503
+
504
+    $result = [
505
+        'status' => 0,
506
+        'headers' => '',
507
+        'page' => '',
508
+        'length' => 0,
509
+        'last_modified' => '',
510
+        'location' => '',
511
+        'url' => $url
512
+    ];
513
+
514
+    // si on ecrit directement dans un fichier, pour ne pas manipuler en memoire refuser gz
515
+    $refuser_gz = ($options['refuser_gz'] || $copy);
516
+
517
+    // ouvrir la connexion et envoyer la requete et ses en-tetes
518
+    [$handle, $fopen] = init_http(
519
+        $options['methode'],
520
+        $url,
521
+        $refuser_gz,
522
+        $options['uri_referer'],
523
+        $formatted_data,
524
+        $options['version_http'],
525
+        $options['if_modified_since']
526
+    );
527
+    if (!$handle) {
528
+        spip_log("ECHEC init_http $url", 'distant' . _LOG_ERREUR);
529
+
530
+        return false;
531
+    }
532
+
533
+    // Sauf en fopen, envoyer le flux d'entree
534
+    // et recuperer les en-tetes de reponses
535
+    if (!$fopen) {
536
+        $res = recuperer_entetes_complets($handle, $options['if_modified_since']);
537
+        if (!$res) {
538
+            fclose($handle);
539
+            $t = @parse_url($url);
540
+            $host = $t['host'];
541
+            // Chinoisierie inexplicable pour contrer
542
+            // les actions liberticides de l'empire du milieu
543
+            if (
544
+                !need_proxy($host)
545
+                && ($res = @file_get_contents($url))
546
+            ) {
547
+                $result['length'] = strlen($res);
548
+                if ($copy) {
549
+                    ecrire_fichier($copy, $res);
550
+                    $result['file'] = $copy;
551
+                } else {
552
+                    $result['page'] = $res;
553
+                }
554
+                $res = [
555
+                    'status' => 200,
556
+                ];
557
+            } else {
558
+                spip_log("ECHEC chinoiserie $url", 'distant' . _LOG_ERREUR);
559
+                return false;
560
+            }
561
+        } elseif ($res['location'] && $options['follow_location']) {
562
+            $options['follow_location']--;
563
+            fclose($handle);
564
+            include_spip('inc/filtres');
565
+            $url = suivre_lien($url, $res['location']);
566
+
567
+            // une redirection doit se faire en GET, sauf status explicite 307 ou 308 qui indique de garder la meme methode
568
+            if (
569
+                $options['methode'] !== 'GET'
570
+                && (empty($res['status']) || !in_array($res['status'], [307, 308]))
571
+            ) {
572
+                $options['methode'] = 'GET';
573
+                $options['datas'] = '';
574
+            }
575
+            spip_log('recuperer_url recommence ' . $options['methode'] . " sur $url", 'distant' . _LOG_DEBUG);
576
+
577
+            return recuperer_url($url, $options);
578
+        } elseif ($res['status'] !== 200) {
579
+            spip_log('HTTP status ' . $res['status'] . " pour $url", 'distant');
580
+        }
581
+        $result['status'] = $res['status'];
582
+        if (isset($res['headers'])) {
583
+            $result['headers'] = $res['headers'];
584
+        }
585
+        if (isset($res['last_modified'])) {
586
+            $result['last_modified'] = $res['last_modified'];
587
+        }
588
+        if (isset($res['location'])) {
589
+            $result['location'] = $res['location'];
590
+        }
591
+    }
592
+
593
+    // on ne veut que les entetes
594
+    if (!$options['taille_max'] || $options['methode'] == 'HEAD' || $result['status'] == '304') {
595
+        spip_log('RESULTAT recuperer_url ' . $options['methode'] . " sur $url : " . json_encode($result, JSON_THROW_ON_ERROR), 'distant' . _LOG_DEBUG);
596
+        return $result;
597
+    }
598
+
599
+
600
+    // s'il faut deballer, le faire via un fichier temporaire
601
+    // sinon la memoire explose pour les gros flux
602
+
603
+    $gz = false;
604
+    if (preg_match(",\bContent-Encoding: .*gzip,is", (string) $result['headers'])) {
605
+        $gz = (_DIR_TMP . md5(uniqid(random_int(0, mt_getrandmax()))) . '.tmp.gz');
606
+    }
607
+
608
+    // si on a pas deja recuperer le contenu par une methode detournee
609
+    if (!$result['length']) {
610
+        $res = recuperer_body($handle, $options['taille_max'], $gz ?: $copy);
611
+        fclose($handle);
612
+        if ($copy) {
613
+            $result['length'] = $res;
614
+            $result['file'] = $copy;
615
+        } elseif ($res) {
616
+            $result['page'] = &$res;
617
+            $result['length'] = strlen($result['page']);
618
+        }
619
+        if (!$result['status']) {
620
+            $result['status'] = 200; // on a reussi, donc !
621
+        }
622
+    }
623
+    if (!$result['page']) {
624
+        return $result;
625
+    }
626
+
627
+    // Decompresser au besoin
628
+    if ($gz) {
629
+        $result['page'] = implode('', gzfile($gz));
630
+        supprimer_fichier($gz);
631
+    }
632
+
633
+    // Faut-il l'importer dans notre charset local ?
634
+    if ($options['transcoder']) {
635
+        include_spip('inc/charsets');
636
+        $result['page'] = transcoder_page($result['page'], $result['headers']);
637
+    }
638
+
639
+    try {
640
+        $trace = json_decode(json_encode($result, JSON_THROW_ON_ERROR), true, 512, JSON_THROW_ON_ERROR);
641
+    } catch (JsonException $e) {
642
+        $trace = [];
643
+        spip_log('Failed to parse Json data : ' . $e->getMessage(), _LOG_ERREUR);
644
+    }
645
+    $trace['page'] = '...';
646
+    spip_log('RESULTAT recuperer_url ' . $options['methode'] . " sur $url : " . json_encode($trace, JSON_THROW_ON_ERROR), 'distant' . _LOG_DEBUG);
647
+
648
+    return $result;
649 649
 }
650 650
 
651 651
 /**
@@ -661,73 +661,73 @@  discard block
 block discarded – undo
661 661
  * @return array|bool|mixed
662 662
  */
663 663
 function recuperer_url_cache($url, $options = []) {
664
-	if (!defined('_DELAI_RECUPERER_URL_CACHE')) {
665
-		define('_DELAI_RECUPERER_URL_CACHE', 3600);
666
-	}
667
-	$default = [
668
-		'transcoder' => false,
669
-		'methode' => 'GET',
670
-		'taille_max' => null,
671
-		'datas' => '',
672
-		'boundary' => '',
673
-		'refuser_gz' => false,
674
-		'if_modified_since' => '',
675
-		'uri_referer' => '',
676
-		'file' => '',
677
-		'follow_location' => 10,
678
-		'version_http' => _INC_DISTANT_VERSION_HTTP,
679
-		'delai_cache' => in_array(_VAR_MODE, ['preview', 'recalcul']) ? 0 : _DELAI_RECUPERER_URL_CACHE,
680
-	];
681
-	$options = array_merge($default, $options);
682
-
683
-	// cas ou il n'est pas possible de cacher
684
-	if (!empty($options['data']) || $options['methode'] == 'POST') {
685
-		return recuperer_url($url, $options);
686
-	}
687
-
688
-	// ne pas tenter plusieurs fois la meme url en erreur (non cachee donc)
689
-	static $errors = [];
690
-	if (isset($errors[$url])) {
691
-		return $errors[$url];
692
-	}
693
-
694
-	$sig = $options;
695
-	unset($sig['if_modified_since']);
696
-	unset($sig['delai_cache']);
697
-	$sig['url'] = $url;
698
-
699
-	$dir = sous_repertoire(_DIR_CACHE, 'curl');
700
-	$cache = md5(serialize($sig)) . '-' . substr(preg_replace(',\W+,', '_', $url), 0, 80);
701
-	$sub = sous_repertoire($dir, substr($cache, 0, 2));
702
-	$cache = "$sub$cache";
703
-
704
-	$res = false;
705
-	$is_cached = file_exists($cache);
706
-	if (
707
-		$is_cached
708
-		&& filemtime($cache) > $_SERVER['REQUEST_TIME'] - $options['delai_cache']
709
-	) {
710
-		lire_fichier($cache, $res);
711
-		if ($res = unserialize($res)) {
712
-			// mettre le last_modified et le status=304 ?
713
-		}
714
-	}
715
-	if (!$res) {
716
-		$res = recuperer_url($url, $options);
717
-		// ne pas recharger cette url non cachee dans le meme hit puisque non disponible
718
-		if (!$res) {
719
-			if ($is_cached) {
720
-				// on a pas reussi a recuperer mais on avait un cache : l'utiliser
721
-				lire_fichier($cache, $res);
722
-				$res = unserialize($res);
723
-			}
724
-
725
-			return $errors[$url] = $res;
726
-		}
727
-		ecrire_fichier($cache, serialize($res));
728
-	}
729
-
730
-	return $res;
664
+    if (!defined('_DELAI_RECUPERER_URL_CACHE')) {
665
+        define('_DELAI_RECUPERER_URL_CACHE', 3600);
666
+    }
667
+    $default = [
668
+        'transcoder' => false,
669
+        'methode' => 'GET',
670
+        'taille_max' => null,
671
+        'datas' => '',
672
+        'boundary' => '',
673
+        'refuser_gz' => false,
674
+        'if_modified_since' => '',
675
+        'uri_referer' => '',
676
+        'file' => '',
677
+        'follow_location' => 10,
678
+        'version_http' => _INC_DISTANT_VERSION_HTTP,
679
+        'delai_cache' => in_array(_VAR_MODE, ['preview', 'recalcul']) ? 0 : _DELAI_RECUPERER_URL_CACHE,
680
+    ];
681
+    $options = array_merge($default, $options);
682
+
683
+    // cas ou il n'est pas possible de cacher
684
+    if (!empty($options['data']) || $options['methode'] == 'POST') {
685
+        return recuperer_url($url, $options);
686
+    }
687
+
688
+    // ne pas tenter plusieurs fois la meme url en erreur (non cachee donc)
689
+    static $errors = [];
690
+    if (isset($errors[$url])) {
691
+        return $errors[$url];
692
+    }
693
+
694
+    $sig = $options;
695
+    unset($sig['if_modified_since']);
696
+    unset($sig['delai_cache']);
697
+    $sig['url'] = $url;
698
+
699
+    $dir = sous_repertoire(_DIR_CACHE, 'curl');
700
+    $cache = md5(serialize($sig)) . '-' . substr(preg_replace(',\W+,', '_', $url), 0, 80);
701
+    $sub = sous_repertoire($dir, substr($cache, 0, 2));
702
+    $cache = "$sub$cache";
703
+
704
+    $res = false;
705
+    $is_cached = file_exists($cache);
706
+    if (
707
+        $is_cached
708
+        && filemtime($cache) > $_SERVER['REQUEST_TIME'] - $options['delai_cache']
709
+    ) {
710
+        lire_fichier($cache, $res);
711
+        if ($res = unserialize($res)) {
712
+            // mettre le last_modified et le status=304 ?
713
+        }
714
+    }
715
+    if (!$res) {
716
+        $res = recuperer_url($url, $options);
717
+        // ne pas recharger cette url non cachee dans le meme hit puisque non disponible
718
+        if (!$res) {
719
+            if ($is_cached) {
720
+                // on a pas reussi a recuperer mais on avait un cache : l'utiliser
721
+                lire_fichier($cache, $res);
722
+                $res = unserialize($res);
723
+            }
724
+
725
+            return $errors[$url] = $res;
726
+        }
727
+        ecrire_fichier($cache, serialize($res));
728
+    }
729
+
730
+    return $res;
731 731
 }
732 732
 
733 733
 /**
@@ -745,42 +745,42 @@  discard block
 block discarded – undo
745 745
  *   string contenu de la resource
746 746
  */
747 747
 function recuperer_body($handle, $taille_max = _INC_DISTANT_MAX_SIZE, $fichier = '') {
748
-	$tmpfile = null;
749
-	$taille = 0;
750
-	$result = '';
751
-	$fp = false;
752
-	if ($fichier) {
753
-		include_spip('inc/acces');
754
-		$tmpfile = "$fichier." . creer_uniqid() . '.tmp';
755
-		$fp = spip_fopen_lock($tmpfile, 'w', LOCK_EX);
756
-		if (!$fp && file_exists($fichier)) {
757
-			return filesize($fichier);
758
-		}
759
-		if (!$fp) {
760
-			return false;
761
-		}
762
-		$result = 0; // on renvoie la taille du fichier
763
-	}
764
-	while (!feof($handle) && $taille < $taille_max) {
765
-		$res = fread($handle, 16384);
766
-		$taille += strlen($res);
767
-		if ($fp) {
768
-			fwrite($fp, $res);
769
-			$result = $taille;
770
-		} else {
771
-			$result .= $res;
772
-		}
773
-	}
774
-	if ($fp) {
775
-		spip_fclose_unlock($fp);
776
-		spip_unlink($fichier);
777
-		@rename($tmpfile, $fichier);
778
-		if (!file_exists($fichier)) {
779
-			return false;
780
-		}
781
-	}
782
-
783
-	return $result;
748
+    $tmpfile = null;
749
+    $taille = 0;
750
+    $result = '';
751
+    $fp = false;
752
+    if ($fichier) {
753
+        include_spip('inc/acces');
754
+        $tmpfile = "$fichier." . creer_uniqid() . '.tmp';
755
+        $fp = spip_fopen_lock($tmpfile, 'w', LOCK_EX);
756
+        if (!$fp && file_exists($fichier)) {
757
+            return filesize($fichier);
758
+        }
759
+        if (!$fp) {
760
+            return false;
761
+        }
762
+        $result = 0; // on renvoie la taille du fichier
763
+    }
764
+    while (!feof($handle) && $taille < $taille_max) {
765
+        $res = fread($handle, 16384);
766
+        $taille += strlen($res);
767
+        if ($fp) {
768
+            fwrite($fp, $res);
769
+            $result = $taille;
770
+        } else {
771
+            $result .= $res;
772
+        }
773
+    }
774
+    if ($fp) {
775
+        spip_fclose_unlock($fp);
776
+        spip_unlink($fichier);
777
+        @rename($tmpfile, $fichier);
778
+        if (!file_exists($fichier)) {
779
+            return false;
780
+        }
781
+    }
782
+
783
+    return $result;
784 784
 }
785 785
 
786 786
 /**
@@ -802,35 +802,35 @@  discard block
 block discarded – undo
802 802
  *   string location
803 803
  */
804 804
 function recuperer_entetes_complets($handle, $if_modified_since = false) {
805
-	$result = ['status' => 0, 'headers' => [], 'last_modified' => 0, 'location' => ''];
806
-
807
-	$s = @trim(fgets($handle, 16384));
808
-	if (!preg_match(',^HTTP/\d+\.\d+ (\d+),', $s, $r)) {
809
-		return false;
810
-	}
811
-	$result['status'] = (int) $r[1];
812
-	while ($s = trim(fgets($handle, 16384))) {
813
-		$result['headers'][] = $s . "\n";
814
-		preg_match(',^([^:]*): *(.*)$,i', $s, $r);
815
-		[, $d, $v] = $r;
816
-		if (strtolower(trim($d)) == 'location' && $result['status'] >= 300 && $result['status'] < 400) {
817
-			$result['location'] = $v;
818
-		} elseif ($d == 'Last-Modified') {
819
-			$result['last_modified'] = strtotime($v);
820
-		}
821
-	}
822
-	if (
823
-		$if_modified_since
824
-		&& $result['last_modified']
825
-		&& $if_modified_since > $result['last_modified']
826
-		&& $result['status'] == 200
827
-	) {
828
-		$result['status'] = 304;
829
-	}
830
-
831
-	$result['headers'] = implode('', $result['headers']);
832
-
833
-	return $result;
805
+    $result = ['status' => 0, 'headers' => [], 'last_modified' => 0, 'location' => ''];
806
+
807
+    $s = @trim(fgets($handle, 16384));
808
+    if (!preg_match(',^HTTP/\d+\.\d+ (\d+),', $s, $r)) {
809
+        return false;
810
+    }
811
+    $result['status'] = (int) $r[1];
812
+    while ($s = trim(fgets($handle, 16384))) {
813
+        $result['headers'][] = $s . "\n";
814
+        preg_match(',^([^:]*): *(.*)$,i', $s, $r);
815
+        [, $d, $v] = $r;
816
+        if (strtolower(trim($d)) == 'location' && $result['status'] >= 300 && $result['status'] < 400) {
817
+            $result['location'] = $v;
818
+        } elseif ($d == 'Last-Modified') {
819
+            $result['last_modified'] = strtotime($v);
820
+        }
821
+    }
822
+    if (
823
+        $if_modified_since
824
+        && $result['last_modified']
825
+        && $if_modified_since > $result['last_modified']
826
+        && $result['status'] == 200
827
+    ) {
828
+        $result['status'] = 304;
829
+    }
830
+
831
+    $result['headers'] = implode('', $result['headers']);
832
+
833
+    return $result;
834 834
 }
835 835
 
836 836
 /**
@@ -852,36 +852,36 @@  discard block
 block discarded – undo
852 852
  *     Nom du fichier pour copie locale
853 853
  **/
854 854
 function nom_fichier_copie_locale($source, $extension) {
855
-	include_spip('inc/documents');
855
+    include_spip('inc/documents');
856 856
 
857
-	$d = creer_repertoire_documents('distant'); # IMG/distant/
858
-	$d = sous_repertoire($d, $extension); # IMG/distant/pdf/
857
+    $d = creer_repertoire_documents('distant'); # IMG/distant/
858
+    $d = sous_repertoire($d, $extension); # IMG/distant/pdf/
859 859
 
860
-	// on se place tout le temps comme si on était a la racine
861
-	if (_DIR_RACINE) {
862
-		$d = preg_replace(',^' . preg_quote((string) _DIR_RACINE, ',') . ',', '', (string) $d);
863
-	}
860
+    // on se place tout le temps comme si on était a la racine
861
+    if (_DIR_RACINE) {
862
+        $d = preg_replace(',^' . preg_quote((string) _DIR_RACINE, ',') . ',', '', (string) $d);
863
+    }
864 864
 
865
-	$m = md5($source);
865
+    $m = md5($source);
866 866
 
867
-	$filename =
868
-		$d
869
-		. substr(preg_replace(',[^\w-],', '', basename($source, $extension)), 0, 16)
870
-		. '-' . substr($m, 0, 8)
871
-		. ".$extension";
867
+    $filename =
868
+        $d
869
+        . substr(preg_replace(',[^\w-],', '', basename($source, $extension)), 0, 16)
870
+        . '-' . substr($m, 0, 8)
871
+        . ".$extension";
872 872
 
873
-	// ancien nommage des fichiers distants : renommer le fichier a la volee si besoin pour eviter de dupliquer les caches
874
-	$legacy_filename =
875
-		$d
876
-		. substr(preg_replace(',[^\w-],', '', basename($source)) . '-' . $m, 0, 12)
877
-		. substr($m, 0, 4)
878
-		. ".$extension";
873
+    // ancien nommage des fichiers distants : renommer le fichier a la volee si besoin pour eviter de dupliquer les caches
874
+    $legacy_filename =
875
+        $d
876
+        . substr(preg_replace(',[^\w-],', '', basename($source)) . '-' . $m, 0, 12)
877
+        . substr($m, 0, 4)
878
+        . ".$extension";
879 879
 
880
-	if (file_exists(_DIR_RACINE . $legacy_filename)) {
881
-		@rename(_DIR_RACINE . $legacy_filename, $filename);
882
-	}
880
+    if (file_exists(_DIR_RACINE . $legacy_filename)) {
881
+        @rename(_DIR_RACINE . $legacy_filename, $filename);
882
+    }
883 883
 
884
-	return $filename;
884
+    return $filename;
885 885
 }
886 886
 
887 887
 /**
@@ -900,72 +900,72 @@  discard block
 block discarded – undo
900 900
  *      - null: Copie locale impossible
901 901
  **/
902 902
 function fichier_copie_locale($source) {
903
-	// Si c'est deja local pas de souci
904
-	if (!tester_url_absolue($source)) {
905
-		if (_DIR_RACINE) {
906
-			$source = preg_replace(',^' . preg_quote((string) _DIR_RACINE, ',') . ',', '', $source);
907
-		}
908
-
909
-		return $source;
910
-	}
911
-
912
-	// optimisation : on regarde si on peut deviner l'extension dans l'url et si le fichier
913
-	// a deja ete copie en local avec cette extension
914
-	// dans ce cas elle est fiable, pas la peine de requeter en base
915
-	$path_parts = pathinfo($source);
916
-	if (!isset($path_parts['extension'])) {
917
-		$path_parts['extension'] = '';
918
-	}
919
-	$ext = $path_parts ? $path_parts['extension'] : '';
920
-	if (
921
-		$ext
922
-		&& preg_match(',^\w+$,', $ext)
923
-		&& ($f = nom_fichier_copie_locale($source, $ext))
924
-		&& file_exists(_DIR_RACINE . $f)
925
-	) {
926
-		return $f;
927
-	}
928
-
929
-
930
-	// Si c'est deja dans la table des documents,
931
-	// ramener le nom de sa copie potentielle
932
-	$ext = sql_getfetsel('extension', 'spip_documents', 'fichier=' . sql_quote($source) . " AND distant='oui' AND extension <> ''");
933
-
934
-	if ($ext) {
935
-		return nom_fichier_copie_locale($source, $ext);
936
-	}
937
-
938
-	// voir si l'extension indiquee dans le nom du fichier est ok
939
-	// et si il n'aurait pas deja ete rapatrie
940
-
941
-	$ext = $path_parts ? $path_parts['extension'] : '';
942
-
943
-	if ($ext && sql_getfetsel('extension', 'spip_types_documents', 'extension=' . sql_quote($ext))) {
944
-		$f = nom_fichier_copie_locale($source, $ext);
945
-		if (file_exists(_DIR_RACINE . $f)) {
946
-			return $f;
947
-		}
948
-	}
949
-
950
-	// Ping  pour voir si son extension est connue et autorisee
951
-	// avec mise en cache du resultat du ping
952
-
953
-	$cache = sous_repertoire(_DIR_CACHE, 'rid') . md5($source);
954
-	if (
955
-		!@file_exists($cache)
956
-		|| !($path_parts = @unserialize(spip_file_get_contents($cache)))
957
-		|| _request('var_mode') === 'recalcul'
958
-	) {
959
-		$path_parts = recuperer_infos_distantes($source, ['charger_si_petite_image' => false]);
960
-		ecrire_fichier($cache, serialize($path_parts));
961
-	}
962
-	$ext = empty($path_parts['extension']) ? '' : $path_parts['extension'];
963
-	if ($ext && sql_getfetsel('extension', 'spip_types_documents', 'extension=' . sql_quote($ext))) {
964
-		return nom_fichier_copie_locale($source, $ext);
965
-	}
966
-
967
-	spip_log("pas de copie locale pour $source", 'distant' . _LOG_ERREUR);
968
-	return null;
903
+    // Si c'est deja local pas de souci
904
+    if (!tester_url_absolue($source)) {
905
+        if (_DIR_RACINE) {
906
+            $source = preg_replace(',^' . preg_quote((string) _DIR_RACINE, ',') . ',', '', $source);
907
+        }
908
+
909
+        return $source;
910
+    }
911
+
912
+    // optimisation : on regarde si on peut deviner l'extension dans l'url et si le fichier
913
+    // a deja ete copie en local avec cette extension
914
+    // dans ce cas elle est fiable, pas la peine de requeter en base
915
+    $path_parts = pathinfo($source);
916
+    if (!isset($path_parts['extension'])) {
917
+        $path_parts['extension'] = '';
918
+    }
919
+    $ext = $path_parts ? $path_parts['extension'] : '';
920
+    if (
921
+        $ext
922
+        && preg_match(',^\w+$,', $ext)
923
+        && ($f = nom_fichier_copie_locale($source, $ext))
924
+        && file_exists(_DIR_RACINE . $f)
925
+    ) {
926
+        return $f;
927
+    }
928
+
929
+
930
+    // Si c'est deja dans la table des documents,
931
+    // ramener le nom de sa copie potentielle
932
+    $ext = sql_getfetsel('extension', 'spip_documents', 'fichier=' . sql_quote($source) . " AND distant='oui' AND extension <> ''");
933
+
934
+    if ($ext) {
935
+        return nom_fichier_copie_locale($source, $ext);
936
+    }
937
+
938
+    // voir si l'extension indiquee dans le nom du fichier est ok
939
+    // et si il n'aurait pas deja ete rapatrie
940
+
941
+    $ext = $path_parts ? $path_parts['extension'] : '';
942
+
943
+    if ($ext && sql_getfetsel('extension', 'spip_types_documents', 'extension=' . sql_quote($ext))) {
944
+        $f = nom_fichier_copie_locale($source, $ext);
945
+        if (file_exists(_DIR_RACINE . $f)) {
946
+            return $f;
947
+        }
948
+    }
949
+
950
+    // Ping  pour voir si son extension est connue et autorisee
951
+    // avec mise en cache du resultat du ping
952
+
953
+    $cache = sous_repertoire(_DIR_CACHE, 'rid') . md5($source);
954
+    if (
955
+        !@file_exists($cache)
956
+        || !($path_parts = @unserialize(spip_file_get_contents($cache)))
957
+        || _request('var_mode') === 'recalcul'
958
+    ) {
959
+        $path_parts = recuperer_infos_distantes($source, ['charger_si_petite_image' => false]);
960
+        ecrire_fichier($cache, serialize($path_parts));
961
+    }
962
+    $ext = empty($path_parts['extension']) ? '' : $path_parts['extension'];
963
+    if ($ext && sql_getfetsel('extension', 'spip_types_documents', 'extension=' . sql_quote($ext))) {
964
+        return nom_fichier_copie_locale($source, $ext);
965
+    }
966
+
967
+    spip_log("pas de copie locale pour $source", 'distant' . _LOG_ERREUR);
968
+    return null;
969 969
 }
970 970
 
971 971
 
@@ -994,129 +994,129 @@  discard block
 block discarded – undo
994 994
  **/
995 995
 function recuperer_infos_distantes($source, $options = []) {
996 996
 
997
-	// pas la peine de perdre son temps
998
-	if (!tester_url_absolue($source)) {
999
-		return false;
1000
-	}
1001
-
1002
-	$taille_max = $options['taille_max'] ?? 0;
1003
-	$charger_si_petite_image = (bool) ($options['charger_si_petite_image'] ?? true);
1004
-	$callback_valider_url = $options['callback_valider_url'] ?? null;
1005
-
1006
-	# charger les alias des types mime
1007
-	include_spip('base/typedoc');
1008
-
1009
-	$a = [];
1010
-	$mime_type = '';
1011
-	// On va directement charger le debut des images et des fichiers html,
1012
-	// de maniere a attrapper le maximum d'infos (titre, taille, etc). Si
1013
-	// ca echoue l'utilisateur devra les entrer...
1014
-	$reponse = recuperer_url($source, ['taille_max' => $taille_max, 'refuser_gz' => true]);
1015
-	if (
1016
-		$callback_valider_url
1017
-		&& is_callable($callback_valider_url)
1018
-		&& !$callback_valider_url($reponse['url'])
1019
-	) {
1020
-		return false;
1021
-	}
1022
-	$headers = $reponse['headers'] ?? '';
1023
-	$a['body'] = $reponse['page'] ?? '';
1024
-	if ($headers) {
1025
-		$mime_type = distant_trouver_mime_type_selon_headers($source, $headers);
1026
-
1027
-		if (!$extension = distant_trouver_extension_selon_headers($source, $headers)) {
1028
-			return false;
1029
-		}
1030
-
1031
-		$a['extension'] = $extension;
1032
-
1033
-		if (preg_match(",\nContent-Length: *([^[:space:]]*),i", "\n$headers", $regs)) {
1034
-			$a['taille'] = (int) $regs[1];
1035
-		}
1036
-	}
1037
-
1038
-	// Echec avec HEAD, on tente avec GET
1039
-	if (!$a && !$taille_max) {
1040
-		spip_log("tenter GET $source", 'distant');
1041
-		$options['taille_max'] = _INC_DISTANT_MAX_SIZE;
1042
-		$a = recuperer_infos_distantes($source, $options);
1043
-	}
1044
-
1045
-	// si on a rien trouve pas la peine d'insister
1046
-	if (!$a) {
1047
-		return false;
1048
-	}
1049
-
1050
-	// S'il s'agit d'une image pas trop grosse ou d'un fichier html, on va aller
1051
-	// recharger le document en GET et recuperer des donnees supplementaires...
1052
-	include_spip('inc/filtres_images_lib_mini');
1053
-	include_spip('inc/documents');
1054
-	if (
1055
-		str_starts_with($mime_type, 'image/')
1056
-		&& ($extension = _image_trouver_extension_depuis_mime($mime_type))
1057
-	) {
1058
-		if (
1059
-			$taille_max == 0
1060
-			&& (empty($a['taille']) || $a['taille'] < _INC_DISTANT_MAX_SIZE)
1061
-			&& in_array($extension, formats_image_acceptables())
1062
-			&& $charger_si_petite_image
1063
-		) {
1064
-			$options['taille_max'] = _INC_DISTANT_MAX_SIZE;
1065
-			$a = recuperer_infos_distantes($source, $options);
1066
-		} else {
1067
-			if ($a['body']) {
1068
-				$a['extension'] = corriger_extension($extension);
1069
-				$a['fichier'] = _DIR_RACINE . nom_fichier_copie_locale($source, $extension);
1070
-				ecrire_fichier($a['fichier'], $a['body']);
1071
-				$size_image = @spip_getimagesize($a['fichier']);
1072
-				$a['largeur'] = (int) $size_image[0];
1073
-				$a['hauteur'] = (int) $size_image[1];
1074
-				$a['type_image'] = true;
1075
-			}
1076
-		}
1077
-	}
1078
-
1079
-	// Fichier swf, si on n'a pas la taille, on va mettre 425x350 par defaut
1080
-	// ce sera mieux que 0x0
1081
-	// Flash is dead!
1082
-	if (
1083
-		$a
1084
-		&& isset($a['extension'])
1085
-		&& $a['extension'] == 'swf'
1086
-		&& empty($a['largeur'])
1087
-	) {
1088
-		$a['largeur'] = 425;
1089
-		$a['hauteur'] = 350;
1090
-	}
1091
-
1092
-	if ($mime_type == 'text/html') {
1093
-		include_spip('inc/filtres');
1094
-		$page = recuperer_url($source, ['transcoder' => true, 'taille_max' => _INC_DISTANT_MAX_SIZE]);
1095
-		$page = $page['page'] ?? '';
1096
-		if (preg_match(',<title>(.*?)</title>,ims', (string) $page, $regs)) {
1097
-			$a['titre'] = corriger_caracteres(trim($regs[1]));
1098
-		}
1099
-		if (!isset($a['taille']) || !$a['taille']) {
1100
-			$a['taille'] = strlen((string) $page); # a peu pres
1101
-		}
1102
-	}
1103
-	$a['mime_type'] = $mime_type;
1104
-
1105
-	return $a;
997
+    // pas la peine de perdre son temps
998
+    if (!tester_url_absolue($source)) {
999
+        return false;
1000
+    }
1001
+
1002
+    $taille_max = $options['taille_max'] ?? 0;
1003
+    $charger_si_petite_image = (bool) ($options['charger_si_petite_image'] ?? true);
1004
+    $callback_valider_url = $options['callback_valider_url'] ?? null;
1005
+
1006
+    # charger les alias des types mime
1007
+    include_spip('base/typedoc');
1008
+
1009
+    $a = [];
1010
+    $mime_type = '';
1011
+    // On va directement charger le debut des images et des fichiers html,
1012
+    // de maniere a attrapper le maximum d'infos (titre, taille, etc). Si
1013
+    // ca echoue l'utilisateur devra les entrer...
1014
+    $reponse = recuperer_url($source, ['taille_max' => $taille_max, 'refuser_gz' => true]);
1015
+    if (
1016
+        $callback_valider_url
1017
+        && is_callable($callback_valider_url)
1018
+        && !$callback_valider_url($reponse['url'])
1019
+    ) {
1020
+        return false;
1021
+    }
1022
+    $headers = $reponse['headers'] ?? '';
1023
+    $a['body'] = $reponse['page'] ?? '';
1024
+    if ($headers) {
1025
+        $mime_type = distant_trouver_mime_type_selon_headers($source, $headers);
1026
+
1027
+        if (!$extension = distant_trouver_extension_selon_headers($source, $headers)) {
1028
+            return false;
1029
+        }
1030
+
1031
+        $a['extension'] = $extension;
1032
+
1033
+        if (preg_match(",\nContent-Length: *([^[:space:]]*),i", "\n$headers", $regs)) {
1034
+            $a['taille'] = (int) $regs[1];
1035
+        }
1036
+    }
1037
+
1038
+    // Echec avec HEAD, on tente avec GET
1039
+    if (!$a && !$taille_max) {
1040
+        spip_log("tenter GET $source", 'distant');
1041
+        $options['taille_max'] = _INC_DISTANT_MAX_SIZE;
1042
+        $a = recuperer_infos_distantes($source, $options);
1043
+    }
1044
+
1045
+    // si on a rien trouve pas la peine d'insister
1046
+    if (!$a) {
1047
+        return false;
1048
+    }
1049
+
1050
+    // S'il s'agit d'une image pas trop grosse ou d'un fichier html, on va aller
1051
+    // recharger le document en GET et recuperer des donnees supplementaires...
1052
+    include_spip('inc/filtres_images_lib_mini');
1053
+    include_spip('inc/documents');
1054
+    if (
1055
+        str_starts_with($mime_type, 'image/')
1056
+        && ($extension = _image_trouver_extension_depuis_mime($mime_type))
1057
+    ) {
1058
+        if (
1059
+            $taille_max == 0
1060
+            && (empty($a['taille']) || $a['taille'] < _INC_DISTANT_MAX_SIZE)
1061
+            && in_array($extension, formats_image_acceptables())
1062
+            && $charger_si_petite_image
1063
+        ) {
1064
+            $options['taille_max'] = _INC_DISTANT_MAX_SIZE;
1065
+            $a = recuperer_infos_distantes($source, $options);
1066
+        } else {
1067
+            if ($a['body']) {
1068
+                $a['extension'] = corriger_extension($extension);
1069
+                $a['fichier'] = _DIR_RACINE . nom_fichier_copie_locale($source, $extension);
1070
+                ecrire_fichier($a['fichier'], $a['body']);
1071
+                $size_image = @spip_getimagesize($a['fichier']);
1072
+                $a['largeur'] = (int) $size_image[0];
1073
+                $a['hauteur'] = (int) $size_image[1];
1074
+                $a['type_image'] = true;
1075
+            }
1076
+        }
1077
+    }
1078
+
1079
+    // Fichier swf, si on n'a pas la taille, on va mettre 425x350 par defaut
1080
+    // ce sera mieux que 0x0
1081
+    // Flash is dead!
1082
+    if (
1083
+        $a
1084
+        && isset($a['extension'])
1085
+        && $a['extension'] == 'swf'
1086
+        && empty($a['largeur'])
1087
+    ) {
1088
+        $a['largeur'] = 425;
1089
+        $a['hauteur'] = 350;
1090
+    }
1091
+
1092
+    if ($mime_type == 'text/html') {
1093
+        include_spip('inc/filtres');
1094
+        $page = recuperer_url($source, ['transcoder' => true, 'taille_max' => _INC_DISTANT_MAX_SIZE]);
1095
+        $page = $page['page'] ?? '';
1096
+        if (preg_match(',<title>(.*?)</title>,ims', (string) $page, $regs)) {
1097
+            $a['titre'] = corriger_caracteres(trim($regs[1]));
1098
+        }
1099
+        if (!isset($a['taille']) || !$a['taille']) {
1100
+            $a['taille'] = strlen((string) $page); # a peu pres
1101
+        }
1102
+    }
1103
+    $a['mime_type'] = $mime_type;
1104
+
1105
+    return $a;
1106 1106
 }
1107 1107
 
1108 1108
 /**
1109 1109
  * Retrouver un mime type depuis les headers
1110 1110
  */
1111 1111
 function distant_trouver_mime_type_selon_headers(string $source, string $headers): string {
1112
-	$mime_type = preg_match(",\nContent-Type: *([^[:space:];]*),i", "\n$headers", $regs) ? trim($regs[1]) : ''; // inconnu
1112
+    $mime_type = preg_match(",\nContent-Type: *([^[:space:];]*),i", "\n$headers", $regs) ? trim($regs[1]) : ''; // inconnu
1113 1113
 
1114
-	// Appliquer les alias
1115
-	while (isset($GLOBALS['mime_alias'][$mime_type])) {
1116
-		$mime_type = $GLOBALS['mime_alias'][$mime_type];
1117
-	}
1114
+    // Appliquer les alias
1115
+    while (isset($GLOBALS['mime_alias'][$mime_type])) {
1116
+        $mime_type = $GLOBALS['mime_alias'][$mime_type];
1117
+    }
1118 1118
 
1119
-	return $mime_type;
1119
+    return $mime_type;
1120 1120
 }
1121 1121
 
1122 1122
 /**
@@ -1125,58 +1125,58 @@  discard block
 block discarded – undo
1125 1125
  * @return false|string
1126 1126
  */
1127 1127
 function distant_trouver_extension_selon_headers(string $source, string $headers) {
1128
-	$mime_type = distant_trouver_mime_type_selon_headers($source, $headers);
1129
-
1130
-	// pour corriger_extension()
1131
-	include_spip('inc/documents');
1132
-
1133
-	// Si on a un mime-type insignifiant
1134
-	// text/plain,application/octet-stream ou vide
1135
-	// c'est peut-etre que le serveur ne sait pas
1136
-	// ce qu'il sert ; on va tenter de detecter via l'extension de l'url
1137
-	// ou le Content-Disposition: attachment; filename=...
1138
-	$t = null;
1139
-	if (in_array($mime_type, ['text/plain', '', 'application/octet-stream'])) {
1140
-		if (!$t && preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $source, $rext)) {
1141
-			$t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text'));
1142
-		}
1143
-		if (
1144
-			!$t
1145
-			&& preg_match(',^Content-Disposition:\s*attachment;\s*filename=(.*)$,Uims', $headers, $m)
1146
-			&& preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $m[1], $rext)
1147
-		) {
1148
-			$t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text'));
1149
-		}
1150
-	}
1151
-
1152
-	// Autre mime/type (ou text/plain avec fichier d'extension inconnue)
1153
-	if (!$t) {
1154
-		$t = sql_fetsel('extension', 'spip_types_documents', 'mime_type=' . sql_quote($mime_type));
1155
-	}
1156
-
1157
-	// Toujours rien ? (ex: audio/x-ogg au lieu de application/ogg)
1158
-	// On essaie de nouveau avec l'extension
1159
-	if (
1160
-		!$t
1161
-		&& $mime_type != 'text/plain'
1162
-		&& preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $source, $rext)
1163
-	) {
1164
-		# eviter xxx.3 => 3gp (> SPIP 3)
1165
-		$t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text'));
1166
-	}
1167
-
1168
-	if ($t) {
1169
-		spip_log("mime-type $mime_type ok, extension " . $t['extension'], 'distant');
1170
-		return $t['extension'];
1171
-	} else {
1172
-		# par defaut on retombe sur '.bin' si c'est autorise
1173
-		spip_log("mime-type $mime_type inconnu", 'distant');
1174
-		$t = sql_fetsel('extension', 'spip_types_documents', "extension='bin'");
1175
-		if (!$t) {
1176
-			return false;
1177
-		}
1178
-		return $t['extension'];
1179
-	}
1128
+    $mime_type = distant_trouver_mime_type_selon_headers($source, $headers);
1129
+
1130
+    // pour corriger_extension()
1131
+    include_spip('inc/documents');
1132
+
1133
+    // Si on a un mime-type insignifiant
1134
+    // text/plain,application/octet-stream ou vide
1135
+    // c'est peut-etre que le serveur ne sait pas
1136
+    // ce qu'il sert ; on va tenter de detecter via l'extension de l'url
1137
+    // ou le Content-Disposition: attachment; filename=...
1138
+    $t = null;
1139
+    if (in_array($mime_type, ['text/plain', '', 'application/octet-stream'])) {
1140
+        if (!$t && preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $source, $rext)) {
1141
+            $t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text'));
1142
+        }
1143
+        if (
1144
+            !$t
1145
+            && preg_match(',^Content-Disposition:\s*attachment;\s*filename=(.*)$,Uims', $headers, $m)
1146
+            && preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $m[1], $rext)
1147
+        ) {
1148
+            $t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text'));
1149
+        }
1150
+    }
1151
+
1152
+    // Autre mime/type (ou text/plain avec fichier d'extension inconnue)
1153
+    if (!$t) {
1154
+        $t = sql_fetsel('extension', 'spip_types_documents', 'mime_type=' . sql_quote($mime_type));
1155
+    }
1156
+
1157
+    // Toujours rien ? (ex: audio/x-ogg au lieu de application/ogg)
1158
+    // On essaie de nouveau avec l'extension
1159
+    if (
1160
+        !$t
1161
+        && $mime_type != 'text/plain'
1162
+        && preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $source, $rext)
1163
+    ) {
1164
+        # eviter xxx.3 => 3gp (> SPIP 3)
1165
+        $t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text'));
1166
+    }
1167
+
1168
+    if ($t) {
1169
+        spip_log("mime-type $mime_type ok, extension " . $t['extension'], 'distant');
1170
+        return $t['extension'];
1171
+    } else {
1172
+        # par defaut on retombe sur '.bin' si c'est autorise
1173
+        spip_log("mime-type $mime_type inconnu", 'distant');
1174
+        $t = sql_fetsel('extension', 'spip_types_documents', "extension='bin'");
1175
+        if (!$t) {
1176
+            return false;
1177
+        }
1178
+        return $t['extension'];
1179
+    }
1180 1180
 }
1181 1181
 
1182 1182
 /**
@@ -1192,45 +1192,45 @@  discard block
 block discarded – undo
1192 1192
  */
1193 1193
 function need_proxy($host, $http_proxy = null, $http_noproxy = null) {
1194 1194
 
1195
-	$http_proxy ??= $GLOBALS['meta']['http_proxy'] ?? null;
1196
-
1197
-	// rien a faire si pas de proxy :)
1198
-	if (is_null($http_proxy) || !$http_proxy = trim((string) $http_proxy)) {
1199
-		return '';
1200
-	}
1201
-
1202
-	if (is_null($http_noproxy)) {
1203
-		$http_noproxy = $GLOBALS['meta']['http_noproxy'] ?? null;
1204
-	}
1205
-	// si pas d'exception, on retourne le proxy
1206
-	if (is_null($http_noproxy) || !$http_noproxy = trim((string) $http_noproxy)) {
1207
-		return $http_proxy;
1208
-	}
1209
-
1210
-	// si le host ou l'un des domaines parents est dans $http_noproxy on fait exception
1211
-	// $http_noproxy peut contenir plusieurs domaines separes par des espaces ou retour ligne
1212
-	$http_noproxy = str_replace("\n", ' ', $http_noproxy);
1213
-	$http_noproxy = str_replace("\r", ' ', $http_noproxy);
1214
-	$http_noproxy = " $http_noproxy ";
1215
-	$domain = $host;
1216
-	// si le domaine exact www.example.org est dans les exceptions
1217
-	if (str_contains($http_noproxy, (string) " $domain ")) {
1218
-		return '';
1219
-	}
1220
-
1221
-	while (str_contains($domain, '.')) {
1222
-		$domain = explode('.', $domain);
1223
-		array_shift($domain);
1224
-		$domain = implode('.', $domain);
1225
-
1226
-		// ou si un domaine parent commencant par un . est dans les exceptions (indiquant qu'il couvre tous les sous-domaines)
1227
-		if (str_contains($http_noproxy, (string) " .$domain ")) {
1228
-			return '';
1229
-		}
1230
-	}
1231
-
1232
-	// ok c'est pas une exception
1233
-	return $http_proxy;
1195
+    $http_proxy ??= $GLOBALS['meta']['http_proxy'] ?? null;
1196
+
1197
+    // rien a faire si pas de proxy :)
1198
+    if (is_null($http_proxy) || !$http_proxy = trim((string) $http_proxy)) {
1199
+        return '';
1200
+    }
1201
+
1202
+    if (is_null($http_noproxy)) {
1203
+        $http_noproxy = $GLOBALS['meta']['http_noproxy'] ?? null;
1204
+    }
1205
+    // si pas d'exception, on retourne le proxy
1206
+    if (is_null($http_noproxy) || !$http_noproxy = trim((string) $http_noproxy)) {
1207
+        return $http_proxy;
1208
+    }
1209
+
1210
+    // si le host ou l'un des domaines parents est dans $http_noproxy on fait exception
1211
+    // $http_noproxy peut contenir plusieurs domaines separes par des espaces ou retour ligne
1212
+    $http_noproxy = str_replace("\n", ' ', $http_noproxy);
1213
+    $http_noproxy = str_replace("\r", ' ', $http_noproxy);
1214
+    $http_noproxy = " $http_noproxy ";
1215
+    $domain = $host;
1216
+    // si le domaine exact www.example.org est dans les exceptions
1217
+    if (str_contains($http_noproxy, (string) " $domain ")) {
1218
+        return '';
1219
+    }
1220
+
1221
+    while (str_contains($domain, '.')) {
1222
+        $domain = explode('.', $domain);
1223
+        array_shift($domain);
1224
+        $domain = implode('.', $domain);
1225
+
1226
+        // ou si un domaine parent commencant par un . est dans les exceptions (indiquant qu'il couvre tous les sous-domaines)
1227
+        if (str_contains($http_noproxy, (string) " .$domain ")) {
1228
+            return '';
1229
+        }
1230
+    }
1231
+
1232
+    // ok c'est pas une exception
1233
+    return $http_proxy;
1234 1234
 }
1235 1235
 
1236 1236
 
@@ -1253,60 +1253,60 @@  discard block
 block discarded – undo
1253 1253
  * @return array
1254 1254
  */
1255 1255
 function init_http($method, $url, $refuse_gz = false, $referer = '', $datas = '', $vers = 'HTTP/1.0', $date = '') {
1256
-	$user = $via_proxy = $proxy_user = '';
1257
-	$fopen = false;
1258
-
1259
-	$t = @parse_url($url);
1260
-	$host = $t['host'];
1261
-	if ($t['scheme'] == 'http') {
1262
-		$scheme = 'http';
1263
-		$noproxy = '';
1264
-	} elseif ($t['scheme'] == 'https') {
1265
-		$scheme = 'ssl';
1266
-		$noproxy = 'ssl://';
1267
-		if (!isset($t['port']) || !($port = $t['port'])) {
1268
-			$t['port'] = 443;
1269
-		}
1270
-	} else {
1271
-		$scheme = $t['scheme'];
1272
-		$noproxy = $scheme . '://';
1273
-	}
1274
-	if (isset($t['user'])) {
1275
-		// user et pass doivent être passés en urlencodé dans l'URL, on redecode ici
1276
-		$user = [urldecode($t['user']), urldecode($t['pass'])];
1277
-	}
1278
-
1279
-	if (!isset($t['port']) || !($port = $t['port'])) {
1280
-		$port = 80;
1281
-	}
1282
-	if (!isset($t['path']) || !($path = $t['path'])) {
1283
-		$path = '/';
1284
-	}
1285
-
1286
-	if (!empty($t['query'])) {
1287
-		$path .= '?' . $t['query'];
1288
-	}
1289
-
1290
-	$f = lance_requete($method, $scheme, $user, $host, $path, $port, $noproxy, $refuse_gz, $referer, $datas, $vers, $date);
1291
-	if (!$f || !is_resource($f)) {
1292
-		// fallback : fopen si on a pas fait timeout dans lance_requete
1293
-		// ce qui correspond a $f===110
1294
-		if (
1295
-			$f !== 110
1296
-			&& !need_proxy($host)
1297
-			&& !_request('tester_proxy')
1298
-			&& (!isset($GLOBALS['inc_distant_allow_fopen']) || $GLOBALS['inc_distant_allow_fopen'])
1299
-		) {
1300
-			$f = @fopen($url, 'rb');
1301
-			spip_log("connexion vers $url par simple fopen", 'distant');
1302
-			$fopen = true;
1303
-		} else {
1304
-			// echec total
1305
-			$f = false;
1306
-		}
1307
-	}
1308
-
1309
-	return [$f, $fopen];
1256
+    $user = $via_proxy = $proxy_user = '';
1257
+    $fopen = false;
1258
+
1259
+    $t = @parse_url($url);
1260
+    $host = $t['host'];
1261
+    if ($t['scheme'] == 'http') {
1262
+        $scheme = 'http';
1263
+        $noproxy = '';
1264
+    } elseif ($t['scheme'] == 'https') {
1265
+        $scheme = 'ssl';
1266
+        $noproxy = 'ssl://';
1267
+        if (!isset($t['port']) || !($port = $t['port'])) {
1268
+            $t['port'] = 443;
1269
+        }
1270
+    } else {
1271
+        $scheme = $t['scheme'];
1272
+        $noproxy = $scheme . '://';
1273
+    }
1274
+    if (isset($t['user'])) {
1275
+        // user et pass doivent être passés en urlencodé dans l'URL, on redecode ici
1276
+        $user = [urldecode($t['user']), urldecode($t['pass'])];
1277
+    }
1278
+
1279
+    if (!isset($t['port']) || !($port = $t['port'])) {
1280
+        $port = 80;
1281
+    }
1282
+    if (!isset($t['path']) || !($path = $t['path'])) {
1283
+        $path = '/';
1284
+    }
1285
+
1286
+    if (!empty($t['query'])) {
1287
+        $path .= '?' . $t['query'];
1288
+    }
1289
+
1290
+    $f = lance_requete($method, $scheme, $user, $host, $path, $port, $noproxy, $refuse_gz, $referer, $datas, $vers, $date);
1291
+    if (!$f || !is_resource($f)) {
1292
+        // fallback : fopen si on a pas fait timeout dans lance_requete
1293
+        // ce qui correspond a $f===110
1294
+        if (
1295
+            $f !== 110
1296
+            && !need_proxy($host)
1297
+            && !_request('tester_proxy')
1298
+            && (!isset($GLOBALS['inc_distant_allow_fopen']) || $GLOBALS['inc_distant_allow_fopen'])
1299
+        ) {
1300
+            $f = @fopen($url, 'rb');
1301
+            spip_log("connexion vers $url par simple fopen", 'distant');
1302
+            $fopen = true;
1303
+        } else {
1304
+            // echec total
1305
+            $f = false;
1306
+        }
1307
+    }
1308
+
1309
+    return [$f, $fopen];
1310 1310
 }
1311 1311
 
1312 1312
 /**
@@ -1341,124 +1341,124 @@  discard block
 block discarded – undo
1341 1341
  *   resource socket vers l'url demandee
1342 1342
  */
1343 1343
 function lance_requete(
1344
-	$method,
1345
-	$scheme,
1346
-	$user,
1347
-	$host,
1348
-	$path,
1349
-	$port,
1350
-	$noproxy,
1351
-	$refuse_gz = false,
1352
-	$referer = '',
1353
-	$datas = '',
1354
-	$vers = 'HTTP/1.0',
1355
-	$date = ''
1344
+    $method,
1345
+    $scheme,
1346
+    $user,
1347
+    $host,
1348
+    $path,
1349
+    $port,
1350
+    $noproxy,
1351
+    $refuse_gz = false,
1352
+    $referer = '',
1353
+    $datas = '',
1354
+    $vers = 'HTTP/1.0',
1355
+    $date = ''
1356 1356
 ) {
1357 1357
 
1358
-	$proxy_user = '';
1359
-	$http_proxy = need_proxy($host);
1360
-	if ($user) {
1361
-		$user = urlencode((string) $user[0]) . ':' . urlencode((string) $user[1]);
1362
-	}
1363
-
1364
-	$connect = '';
1365
-	if ($http_proxy) {
1366
-		if (!defined('_PROXY_HTTPS_NOT_VIA_CONNECT') && in_array($scheme, ['tls','ssl'])) {
1367
-			$path_host = ($user ? "$user@" : '') . $host . (($port != 80) ? ":$port" : '');
1368
-			$connect = 'CONNECT ' . $path_host . " $vers\r\n"
1369
-				. "Host: $path_host\r\n"
1370
-				. "Proxy-Connection: Keep-Alive\r\n";
1371
-		} else {
1372
-			$path = (in_array($scheme, ['tls','ssl']) ? 'https://' : "$scheme://")
1373
-				. ($user ? "$user@" : '')
1374
-				. "$host" . (($port != 80) ? ":$port" : '') . $path;
1375
-		}
1376
-		$t2 = @parse_url($http_proxy);
1377
-		$first_host = $t2['host'];
1378
-		$first_port = ($t2['port'] ?? null) ?: 80;
1379
-		if ($t2['user'] ?? null) {
1380
-			$proxy_user = base64_encode($t2['user'] . ':' . $t2['pass']);
1381
-		}
1382
-	} else {
1383
-		$first_host = $noproxy . $host;
1384
-		$first_port = $port;
1385
-	}
1386
-
1387
-	if ($connect) {
1388
-		$streamContext = stream_context_create([
1389
-			'ssl' => [
1390
-				'verify_peer' => false,
1391
-				'allow_self_signed' => true,
1392
-				'SNI_enabled' => true,
1393
-				'peer_name' => $host,
1394
-			]
1395
-		]);
1396
-		$f = @stream_socket_client(
1397
-			"tcp://$first_host:$first_port",
1398
-			$errno,
1399
-			$errstr,
1400
-			_INC_DISTANT_CONNECT_TIMEOUT,
1401
-			STREAM_CLIENT_CONNECT,
1402
-			$streamContext
1403
-		);
1404
-		spip_log("Recuperer $path sur $first_host:$first_port par $f (via CONNECT)", 'connect');
1405
-		if (!$f) {
1406
-			spip_log("Erreur connexion $errno $errstr", 'distant' . _LOG_ERREUR);
1407
-			return $errno;
1408
-		}
1409
-		stream_set_timeout($f, _INC_DISTANT_CONNECT_TIMEOUT);
1410
-
1411
-		fwrite($f, $connect);
1412
-		fwrite($f, "\r\n");
1413
-		$res = fread($f, 1024);
1414
-		if (
1415
-			!$res
1416
-			|| ($res = explode(' ', $res)) === []
1417
-			|| $res[1] !== '200'
1418
-		) {
1419
-			spip_log("Echec CONNECT sur $first_host:$first_port", 'connect' . _LOG_INFO_IMPORTANTE);
1420
-			fclose($f);
1421
-
1422
-			return false;
1423
-		}
1424
-		// important, car sinon on lit trop vite et les donnees ne sont pas encore dispo
1425
-		stream_set_blocking($f, true);
1426
-		// envoyer le handshake
1427
-		stream_socket_enable_crypto($f, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
1428
-		spip_log("OK CONNECT sur $first_host:$first_port", 'connect');
1429
-	} else {
1430
-		$ntry = 3;
1431
-		do {
1432
-			$f = @fsockopen($first_host, $first_port, $errno, $errstr, _INC_DISTANT_CONNECT_TIMEOUT);
1433
-		} while (!$f && $ntry-- && $errno !== 110 && sleep(1));
1434
-		spip_log("Recuperer $path sur $first_host:$first_port par $f");
1435
-		if (!$f) {
1436
-			spip_log("Erreur connexion $errno $errstr", 'distant' . _LOG_ERREUR);
1437
-
1438
-			return $errno;
1439
-		}
1440
-		stream_set_timeout($f, _INC_DISTANT_CONNECT_TIMEOUT);
1441
-	}
1442
-
1443
-	$site = $GLOBALS['meta']['adresse_site'] ?? '';
1444
-
1445
-	$host_port = $host;
1446
-	if ($port != (in_array($scheme, ['tls','ssl']) ? 443 : 80)) {
1447
-		$host_port .= ":$port";
1448
-	}
1449
-	$req = "$method $path $vers\r\n"
1450
-		. "Host: $host_port\r\n"
1451
-		. 'User-Agent: ' . _INC_DISTANT_USER_AGENT . "\r\n"
1452
-		. ($refuse_gz ? '' : ('Accept-Encoding: ' . _INC_DISTANT_CONTENT_ENCODING . "\r\n"))
1453
-		. ($site ? "Referer: $site/$referer\r\n" : '')
1454
-		. ($date ? 'If-Modified-Since: ' . (gmdate('D, d M Y H:i:s', $date) . " GMT\r\n") : '')
1455
-		. ($user ? 'Authorization: Basic ' . base64_encode(urldecode($user)) . "\r\n" : '')
1456
-		. ($proxy_user ? "Proxy-Authorization: Basic $proxy_user\r\n" : '')
1457
-		. (strpos($vers, '1.1') ? "Keep-Alive: 300\r\nConnection: keep-alive\r\n" : '');
1358
+    $proxy_user = '';
1359
+    $http_proxy = need_proxy($host);
1360
+    if ($user) {
1361
+        $user = urlencode((string) $user[0]) . ':' . urlencode((string) $user[1]);
1362
+    }
1363
+
1364
+    $connect = '';
1365
+    if ($http_proxy) {
1366
+        if (!defined('_PROXY_HTTPS_NOT_VIA_CONNECT') && in_array($scheme, ['tls','ssl'])) {
1367
+            $path_host = ($user ? "$user@" : '') . $host . (($port != 80) ? ":$port" : '');
1368
+            $connect = 'CONNECT ' . $path_host . " $vers\r\n"
1369
+                . "Host: $path_host\r\n"
1370
+                . "Proxy-Connection: Keep-Alive\r\n";
1371
+        } else {
1372
+            $path = (in_array($scheme, ['tls','ssl']) ? 'https://' : "$scheme://")
1373
+                . ($user ? "$user@" : '')
1374
+                . "$host" . (($port != 80) ? ":$port" : '') . $path;
1375
+        }
1376
+        $t2 = @parse_url($http_proxy);
1377
+        $first_host = $t2['host'];
1378
+        $first_port = ($t2['port'] ?? null) ?: 80;
1379
+        if ($t2['user'] ?? null) {
1380
+            $proxy_user = base64_encode($t2['user'] . ':' . $t2['pass']);
1381
+        }
1382
+    } else {
1383
+        $first_host = $noproxy . $host;
1384
+        $first_port = $port;
1385
+    }
1386
+
1387
+    if ($connect) {
1388
+        $streamContext = stream_context_create([
1389
+            'ssl' => [
1390
+                'verify_peer' => false,
1391
+                'allow_self_signed' => true,
1392
+                'SNI_enabled' => true,
1393
+                'peer_name' => $host,
1394
+            ]
1395
+        ]);
1396
+        $f = @stream_socket_client(
1397
+            "tcp://$first_host:$first_port",
1398
+            $errno,
1399
+            $errstr,
1400
+            _INC_DISTANT_CONNECT_TIMEOUT,
1401
+            STREAM_CLIENT_CONNECT,
1402
+            $streamContext
1403
+        );
1404
+        spip_log("Recuperer $path sur $first_host:$first_port par $f (via CONNECT)", 'connect');
1405
+        if (!$f) {
1406
+            spip_log("Erreur connexion $errno $errstr", 'distant' . _LOG_ERREUR);
1407
+            return $errno;
1408
+        }
1409
+        stream_set_timeout($f, _INC_DISTANT_CONNECT_TIMEOUT);
1410
+
1411
+        fwrite($f, $connect);
1412
+        fwrite($f, "\r\n");
1413
+        $res = fread($f, 1024);
1414
+        if (
1415
+            !$res
1416
+            || ($res = explode(' ', $res)) === []
1417
+            || $res[1] !== '200'
1418
+        ) {
1419
+            spip_log("Echec CONNECT sur $first_host:$first_port", 'connect' . _LOG_INFO_IMPORTANTE);
1420
+            fclose($f);
1421
+
1422
+            return false;
1423
+        }
1424
+        // important, car sinon on lit trop vite et les donnees ne sont pas encore dispo
1425
+        stream_set_blocking($f, true);
1426
+        // envoyer le handshake
1427
+        stream_socket_enable_crypto($f, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
1428
+        spip_log("OK CONNECT sur $first_host:$first_port", 'connect');
1429
+    } else {
1430
+        $ntry = 3;
1431
+        do {
1432
+            $f = @fsockopen($first_host, $first_port, $errno, $errstr, _INC_DISTANT_CONNECT_TIMEOUT);
1433
+        } while (!$f && $ntry-- && $errno !== 110 && sleep(1));
1434
+        spip_log("Recuperer $path sur $first_host:$first_port par $f");
1435
+        if (!$f) {
1436
+            spip_log("Erreur connexion $errno $errstr", 'distant' . _LOG_ERREUR);
1437
+
1438
+            return $errno;
1439
+        }
1440
+        stream_set_timeout($f, _INC_DISTANT_CONNECT_TIMEOUT);
1441
+    }
1442
+
1443
+    $site = $GLOBALS['meta']['adresse_site'] ?? '';
1444
+
1445
+    $host_port = $host;
1446
+    if ($port != (in_array($scheme, ['tls','ssl']) ? 443 : 80)) {
1447
+        $host_port .= ":$port";
1448
+    }
1449
+    $req = "$method $path $vers\r\n"
1450
+        . "Host: $host_port\r\n"
1451
+        . 'User-Agent: ' . _INC_DISTANT_USER_AGENT . "\r\n"
1452
+        . ($refuse_gz ? '' : ('Accept-Encoding: ' . _INC_DISTANT_CONTENT_ENCODING . "\r\n"))
1453
+        . ($site ? "Referer: $site/$referer\r\n" : '')
1454
+        . ($date ? 'If-Modified-Since: ' . (gmdate('D, d M Y H:i:s', $date) . " GMT\r\n") : '')
1455
+        . ($user ? 'Authorization: Basic ' . base64_encode(urldecode($user)) . "\r\n" : '')
1456
+        . ($proxy_user ? "Proxy-Authorization: Basic $proxy_user\r\n" : '')
1457
+        . (strpos($vers, '1.1') ? "Keep-Alive: 300\r\nConnection: keep-alive\r\n" : '');
1458 1458
 
1459 1459
 #	spip_log("Requete\n$req", 'distant');
1460
-	fwrite($f, $req);
1461
-	fwrite($f, $datas ?: "\r\n");
1460
+    fwrite($f, $req);
1461
+    fwrite($f, $datas ?: "\r\n");
1462 1462
 
1463
-	return $f;
1463
+    return $f;
1464 1464
 }
Please login to merge, or discard this patch.
Spacing   +67 added lines, -67 removed lines patch added patch discarded remove patch
@@ -27,7 +27,7 @@  discard block
 block discarded – undo
27 27
 	define('_INC_DISTANT_CONTENT_ENCODING', 'gzip');
28 28
 }
29 29
 if (!defined('_INC_DISTANT_USER_AGENT')) {
30
-	define('_INC_DISTANT_USER_AGENT', 'SPIP-' . $GLOBALS['spip_version_affichee'] . ' (' . $GLOBALS['home_server'] . ')');
30
+	define('_INC_DISTANT_USER_AGENT', 'SPIP-'.$GLOBALS['spip_version_affichee'].' ('.$GLOBALS['home_server'].')');
31 31
 }
32 32
 if (!defined('_INC_DISTANT_MAX_SIZE')) {
33 33
 	define('_INC_DISTANT_MAX_SIZE', 2_097_152);
@@ -36,7 +36,7 @@  discard block
 block discarded – undo
36 36
 	define('_INC_DISTANT_CONNECT_TIMEOUT', 10);
37 37
 }
38 38
 
39
-define('_REGEXP_COPIE_LOCALE', ',' 	.
39
+define('_REGEXP_COPIE_LOCALE', ','.
40 40
 	preg_replace(
41 41
 		'@^https?:@',
42 42
 		'https?:',
@@ -73,7 +73,7 @@  discard block
 block discarded – undo
73 73
 
74 74
 	// si c'est la protection de soi-meme, retourner le path
75 75
 	if ($mode !== 'force' && preg_match(_REGEXP_COPIE_LOCALE, $source, $match)) {
76
-		$source = substr((string) _DIR_IMG, strlen((string) _DIR_RACINE)) . urldecode($match[1]);
76
+		$source = substr((string) _DIR_IMG, strlen((string) _DIR_RACINE)).urldecode($match[1]);
77 77
 
78 78
 		return @file_exists($source) ? $source : false;
79 79
 	}
@@ -93,7 +93,7 @@  discard block
 block discarded – undo
93 93
 		return false;
94 94
 	}
95 95
 
96
-	$localrac = _DIR_RACINE . $local;
96
+	$localrac = _DIR_RACINE.$local;
97 97
 	$t = ($mode === 'force') ? false : @file_exists($localrac);
98 98
 
99 99
 	// test d'existence du fichier
@@ -113,17 +113,17 @@  discard block
 block discarded – undo
113 113
 		if (!$taille_max) {
114 114
 			$taille_max = _COPIE_LOCALE_MAX_SIZE;
115 115
 		}
116
-		$localrac_tmp = $localrac . '.tmp';
116
+		$localrac_tmp = $localrac.'.tmp';
117 117
 		$res = recuperer_url(
118 118
 			$source,
119 119
 			['file' => $localrac_tmp, 'taille_max' => $taille_max, 'if_modified_since' => $t ? filemtime($localrac) : '']
120 120
 		);
121 121
 
122 122
 		if (!$res || !$res['length'] && $res['status'] != 304) {
123
-			spip_log("copie_locale : Echec recuperation $source sur $localrac_tmp status : " . ($res ? $res['status'] : '-'), 'distant' . _LOG_INFO_IMPORTANTE);
123
+			spip_log("copie_locale : Echec recuperation $source sur $localrac_tmp status : ".($res ? $res['status'] : '-'), 'distant'._LOG_INFO_IMPORTANTE);
124 124
 			@unlink($localrac_tmp);
125 125
 		} else {
126
-			spip_log("copie_locale : recuperation $source sur $localrac_tmp OK | taille " . $res['length'] . ' status ' . $res['status'], 'distant');
126
+			spip_log("copie_locale : recuperation $source sur $localrac_tmp OK | taille ".$res['length'].' status '.$res['status'], 'distant');
127 127
 		}
128 128
 		if (!$res || !$res['length']) {
129 129
 			// si $t c'est sans doute juste un not-modified-since
@@ -136,7 +136,7 @@  discard block
 block discarded – undo
136 136
 			&& is_callable($callback_valider_url)
137 137
 			&& !$callback_valider_url($res['url'])
138 138
 		) {
139
-			spip_log('copie_locale : url finale ' . $res['url'] . " non valide, on refuse le fichier $localrac_tmp", 'distant' . _LOG_INFO_IMPORTANTE);
139
+			spip_log('copie_locale : url finale '.$res['url']." non valide, on refuse le fichier $localrac_tmp", 'distant'._LOG_INFO_IMPORTANTE);
140 140
 			@unlink($localrac_tmp);
141 141
 			return $t ? $local : false;
142 142
 		}
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
 
227 227
 	if (!$is_known_host) {
228 228
 		$host = trim($parsed_url['host'], '.');
229
-		if (! $ip = filter_var($host, FILTER_VALIDATE_IP)) {
229
+		if (!$ip = filter_var($host, FILTER_VALIDATE_IP)) {
230 230
 			$ip = gethostbyname($host);
231 231
 			if ($ip === $host) {
232 232
 				// Error condition for gethostbyname()
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
 				$ip = false;
247 247
 			}
248 248
 		}
249
-		if ($ip && ! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
249
+		if ($ip && !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
250 250
 			return false;
251 251
 		}
252 252
 	}
@@ -327,7 +327,7 @@  discard block
 block discarded – undo
327 327
 				}
328 328
 			}
329 329
 			if ($taille > 500) {
330
-				$boundary = substr(md5(random_int(0, mt_getrandmax()) . 'spip'), 0, 8);
330
+				$boundary = substr(md5(random_int(0, mt_getrandmax()).'spip'), 0, 8);
331 331
 			}
332 332
 		}
333 333
 
@@ -360,10 +360,10 @@  discard block
 block discarded – undo
360 360
 				foreach ($donnees as $cle => $valeur) {
361 361
 					if (is_array($valeur)) {
362 362
 						foreach ($valeur as $val2) {
363
-							$chaines[] = rawurlencode($cle) . '[]=' . rawurlencode((string) $val2);
363
+							$chaines[] = rawurlencode($cle).'[]='.rawurlencode((string) $val2);
364 364
 						}
365 365
 					} else {
366
-						$chaines[] = rawurlencode($cle) . '=' . rawurlencode((string) $valeur);
366
+						$chaines[] = rawurlencode($cle).'='.rawurlencode((string) $valeur);
367 367
 					}
368 368
 				}
369 369
 				$chaine = implode('&', $chaines);
@@ -465,13 +465,13 @@  discard block
 block discarded – undo
465 465
 		$options['taille_max'] = $copy ? _COPIE_LOCALE_MAX_SIZE : _INC_DISTANT_MAX_SIZE;
466 466
 	}
467 467
 
468
-	spip_log('recuperer_url ' . $options['methode'] . " sur $url", 'distant' . _LOG_DEBUG);
468
+	spip_log('recuperer_url '.$options['methode']." sur $url", 'distant'._LOG_DEBUG);
469 469
 
470 470
 	// Ajout des en-têtes spécifiques si besoin
471 471
 	$formatted_data = '';
472 472
 	if (!empty($options['headers'])) {
473 473
 		foreach ($options['headers'] as $champ => $valeur) {
474
-			$formatted_data .= $champ . ': ' . $valeur . "\r\n";
474
+			$formatted_data .= $champ.': '.$valeur."\r\n";
475 475
 		}
476 476
 	}
477 477
 
@@ -479,9 +479,9 @@  discard block
 block discarded – undo
479 479
 		[$head, $postdata] = prepare_donnees_post($options['datas'], $options['boundary']);
480 480
 		$head .= $formatted_data;
481 481
 		if (stripos($head, 'Content-Length:') === false) {
482
-			$head .= 'Content-Length: ' . strlen((string) $postdata) . "\r\n";
482
+			$head .= 'Content-Length: '.strlen((string) $postdata)."\r\n";
483 483
 		}
484
-		$formatted_data = $head . "\r\n" . $postdata;
484
+		$formatted_data = $head."\r\n".$postdata;
485 485
 		if (
486 486
 			strlen((string) $postdata) && !$methode_demandee
487 487
 		) {
@@ -494,9 +494,9 @@  discard block
 block discarded – undo
494 494
 	// Accepter les URLs au format feed:// ou qui ont oublie le http:// ou les urls relatives au protocole
495 495
 	$url = preg_replace(',^feed://,i', 'http://', $url);
496 496
 	if (!tester_url_absolue($url)) {
497
-		$url = 'http://' . $url;
497
+		$url = 'http://'.$url;
498 498
 	} elseif (str_starts_with($url, '//')) {
499
-		$url = 'http:' . $url;
499
+		$url = 'http:'.$url;
500 500
 	}
501 501
 
502 502
 	$url = url_to_ascii($url);
@@ -525,7 +525,7 @@  discard block
 block discarded – undo
525 525
 		$options['if_modified_since']
526 526
 	);
527 527
 	if (!$handle) {
528
-		spip_log("ECHEC init_http $url", 'distant' . _LOG_ERREUR);
528
+		spip_log("ECHEC init_http $url", 'distant'._LOG_ERREUR);
529 529
 
530 530
 		return false;
531 531
 	}
@@ -555,7 +555,7 @@  discard block
 block discarded – undo
555 555
 					'status' => 200,
556 556
 				];
557 557
 			} else {
558
-				spip_log("ECHEC chinoiserie $url", 'distant' . _LOG_ERREUR);
558
+				spip_log("ECHEC chinoiserie $url", 'distant'._LOG_ERREUR);
559 559
 				return false;
560 560
 			}
561 561
 		} elseif ($res['location'] && $options['follow_location']) {
@@ -572,11 +572,11 @@  discard block
 block discarded – undo
572 572
 				$options['methode'] = 'GET';
573 573
 				$options['datas'] = '';
574 574
 			}
575
-			spip_log('recuperer_url recommence ' . $options['methode'] . " sur $url", 'distant' . _LOG_DEBUG);
575
+			spip_log('recuperer_url recommence '.$options['methode']." sur $url", 'distant'._LOG_DEBUG);
576 576
 
577 577
 			return recuperer_url($url, $options);
578 578
 		} elseif ($res['status'] !== 200) {
579
-			spip_log('HTTP status ' . $res['status'] . " pour $url", 'distant');
579
+			spip_log('HTTP status '.$res['status']." pour $url", 'distant');
580 580
 		}
581 581
 		$result['status'] = $res['status'];
582 582
 		if (isset($res['headers'])) {
@@ -592,7 +592,7 @@  discard block
 block discarded – undo
592 592
 
593 593
 	// on ne veut que les entetes
594 594
 	if (!$options['taille_max'] || $options['methode'] == 'HEAD' || $result['status'] == '304') {
595
-		spip_log('RESULTAT recuperer_url ' . $options['methode'] . " sur $url : " . json_encode($result, JSON_THROW_ON_ERROR), 'distant' . _LOG_DEBUG);
595
+		spip_log('RESULTAT recuperer_url '.$options['methode']." sur $url : ".json_encode($result, JSON_THROW_ON_ERROR), 'distant'._LOG_DEBUG);
596 596
 		return $result;
597 597
 	}
598 598
 
@@ -602,7 +602,7 @@  discard block
 block discarded – undo
602 602
 
603 603
 	$gz = false;
604 604
 	if (preg_match(",\bContent-Encoding: .*gzip,is", (string) $result['headers'])) {
605
-		$gz = (_DIR_TMP . md5(uniqid(random_int(0, mt_getrandmax()))) . '.tmp.gz');
605
+		$gz = (_DIR_TMP.md5(uniqid(random_int(0, mt_getrandmax()))).'.tmp.gz');
606 606
 	}
607 607
 
608 608
 	// si on a pas deja recuperer le contenu par une methode detournee
@@ -640,10 +640,10 @@  discard block
 block discarded – undo
640 640
 		$trace = json_decode(json_encode($result, JSON_THROW_ON_ERROR), true, 512, JSON_THROW_ON_ERROR);
641 641
 	} catch (JsonException $e) {
642 642
 		$trace = [];
643
-		spip_log('Failed to parse Json data : ' . $e->getMessage(), _LOG_ERREUR);
643
+		spip_log('Failed to parse Json data : '.$e->getMessage(), _LOG_ERREUR);
644 644
 	}
645 645
 	$trace['page'] = '...';
646
-	spip_log('RESULTAT recuperer_url ' . $options['methode'] . " sur $url : " . json_encode($trace, JSON_THROW_ON_ERROR), 'distant' . _LOG_DEBUG);
646
+	spip_log('RESULTAT recuperer_url '.$options['methode']." sur $url : ".json_encode($trace, JSON_THROW_ON_ERROR), 'distant'._LOG_DEBUG);
647 647
 
648 648
 	return $result;
649 649
 }
@@ -697,7 +697,7 @@  discard block
 block discarded – undo
697 697
 	$sig['url'] = $url;
698 698
 
699 699
 	$dir = sous_repertoire(_DIR_CACHE, 'curl');
700
-	$cache = md5(serialize($sig)) . '-' . substr(preg_replace(',\W+,', '_', $url), 0, 80);
700
+	$cache = md5(serialize($sig)).'-'.substr(preg_replace(',\W+,', '_', $url), 0, 80);
701 701
 	$sub = sous_repertoire($dir, substr($cache, 0, 2));
702 702
 	$cache = "$sub$cache";
703 703
 
@@ -751,7 +751,7 @@  discard block
 block discarded – undo
751 751
 	$fp = false;
752 752
 	if ($fichier) {
753 753
 		include_spip('inc/acces');
754
-		$tmpfile = "$fichier." . creer_uniqid() . '.tmp';
754
+		$tmpfile = "$fichier.".creer_uniqid().'.tmp';
755 755
 		$fp = spip_fopen_lock($tmpfile, 'w', LOCK_EX);
756 756
 		if (!$fp && file_exists($fichier)) {
757 757
 			return filesize($fichier);
@@ -810,7 +810,7 @@  discard block
 block discarded – undo
810 810
 	}
811 811
 	$result['status'] = (int) $r[1];
812 812
 	while ($s = trim(fgets($handle, 16384))) {
813
-		$result['headers'][] = $s . "\n";
813
+		$result['headers'][] = $s."\n";
814 814
 		preg_match(',^([^:]*): *(.*)$,i', $s, $r);
815 815
 		[, $d, $v] = $r;
816 816
 		if (strtolower(trim($d)) == 'location' && $result['status'] >= 300 && $result['status'] < 400) {
@@ -859,7 +859,7 @@  discard block
 block discarded – undo
859 859
 
860 860
 	// on se place tout le temps comme si on était a la racine
861 861
 	if (_DIR_RACINE) {
862
-		$d = preg_replace(',^' . preg_quote((string) _DIR_RACINE, ',') . ',', '', (string) $d);
862
+		$d = preg_replace(',^'.preg_quote((string) _DIR_RACINE, ',').',', '', (string) $d);
863 863
 	}
864 864
 
865 865
 	$m = md5($source);
@@ -867,18 +867,18 @@  discard block
 block discarded – undo
867 867
 	$filename =
868 868
 		$d
869 869
 		. substr(preg_replace(',[^\w-],', '', basename($source, $extension)), 0, 16)
870
-		. '-' . substr($m, 0, 8)
870
+		. '-'.substr($m, 0, 8)
871 871
 		. ".$extension";
872 872
 
873 873
 	// ancien nommage des fichiers distants : renommer le fichier a la volee si besoin pour eviter de dupliquer les caches
874 874
 	$legacy_filename =
875 875
 		$d
876
-		. substr(preg_replace(',[^\w-],', '', basename($source)) . '-' . $m, 0, 12)
876
+		. substr(preg_replace(',[^\w-],', '', basename($source)).'-'.$m, 0, 12)
877 877
 		. substr($m, 0, 4)
878 878
 		. ".$extension";
879 879
 
880
-	if (file_exists(_DIR_RACINE . $legacy_filename)) {
881
-		@rename(_DIR_RACINE . $legacy_filename, $filename);
880
+	if (file_exists(_DIR_RACINE.$legacy_filename)) {
881
+		@rename(_DIR_RACINE.$legacy_filename, $filename);
882 882
 	}
883 883
 
884 884
 	return $filename;
@@ -903,7 +903,7 @@  discard block
 block discarded – undo
903 903
 	// Si c'est deja local pas de souci
904 904
 	if (!tester_url_absolue($source)) {
905 905
 		if (_DIR_RACINE) {
906
-			$source = preg_replace(',^' . preg_quote((string) _DIR_RACINE, ',') . ',', '', $source);
906
+			$source = preg_replace(',^'.preg_quote((string) _DIR_RACINE, ',').',', '', $source);
907 907
 		}
908 908
 
909 909
 		return $source;
@@ -921,7 +921,7 @@  discard block
 block discarded – undo
921 921
 		$ext
922 922
 		&& preg_match(',^\w+$,', $ext)
923 923
 		&& ($f = nom_fichier_copie_locale($source, $ext))
924
-		&& file_exists(_DIR_RACINE . $f)
924
+		&& file_exists(_DIR_RACINE.$f)
925 925
 	) {
926 926
 		return $f;
927 927
 	}
@@ -929,7 +929,7 @@  discard block
 block discarded – undo
929 929
 
930 930
 	// Si c'est deja dans la table des documents,
931 931
 	// ramener le nom de sa copie potentielle
932
-	$ext = sql_getfetsel('extension', 'spip_documents', 'fichier=' . sql_quote($source) . " AND distant='oui' AND extension <> ''");
932
+	$ext = sql_getfetsel('extension', 'spip_documents', 'fichier='.sql_quote($source)." AND distant='oui' AND extension <> ''");
933 933
 
934 934
 	if ($ext) {
935 935
 		return nom_fichier_copie_locale($source, $ext);
@@ -940,9 +940,9 @@  discard block
 block discarded – undo
940 940
 
941 941
 	$ext = $path_parts ? $path_parts['extension'] : '';
942 942
 
943
-	if ($ext && sql_getfetsel('extension', 'spip_types_documents', 'extension=' . sql_quote($ext))) {
943
+	if ($ext && sql_getfetsel('extension', 'spip_types_documents', 'extension='.sql_quote($ext))) {
944 944
 		$f = nom_fichier_copie_locale($source, $ext);
945
-		if (file_exists(_DIR_RACINE . $f)) {
945
+		if (file_exists(_DIR_RACINE.$f)) {
946 946
 			return $f;
947 947
 		}
948 948
 	}
@@ -950,7 +950,7 @@  discard block
 block discarded – undo
950 950
 	// Ping  pour voir si son extension est connue et autorisee
951 951
 	// avec mise en cache du resultat du ping
952 952
 
953
-	$cache = sous_repertoire(_DIR_CACHE, 'rid') . md5($source);
953
+	$cache = sous_repertoire(_DIR_CACHE, 'rid').md5($source);
954 954
 	if (
955 955
 		!@file_exists($cache)
956 956
 		|| !($path_parts = @unserialize(spip_file_get_contents($cache)))
@@ -960,11 +960,11 @@  discard block
 block discarded – undo
960 960
 		ecrire_fichier($cache, serialize($path_parts));
961 961
 	}
962 962
 	$ext = empty($path_parts['extension']) ? '' : $path_parts['extension'];
963
-	if ($ext && sql_getfetsel('extension', 'spip_types_documents', 'extension=' . sql_quote($ext))) {
963
+	if ($ext && sql_getfetsel('extension', 'spip_types_documents', 'extension='.sql_quote($ext))) {
964 964
 		return nom_fichier_copie_locale($source, $ext);
965 965
 	}
966 966
 
967
-	spip_log("pas de copie locale pour $source", 'distant' . _LOG_ERREUR);
967
+	spip_log("pas de copie locale pour $source", 'distant'._LOG_ERREUR);
968 968
 	return null;
969 969
 }
970 970
 
@@ -1066,7 +1066,7 @@  discard block
 block discarded – undo
1066 1066
 		} else {
1067 1067
 			if ($a['body']) {
1068 1068
 				$a['extension'] = corriger_extension($extension);
1069
-				$a['fichier'] = _DIR_RACINE . nom_fichier_copie_locale($source, $extension);
1069
+				$a['fichier'] = _DIR_RACINE.nom_fichier_copie_locale($source, $extension);
1070 1070
 				ecrire_fichier($a['fichier'], $a['body']);
1071 1071
 				$size_image = @spip_getimagesize($a['fichier']);
1072 1072
 				$a['largeur'] = (int) $size_image[0];
@@ -1138,20 +1138,20 @@  discard block
 block discarded – undo
1138 1138
 	$t = null;
1139 1139
 	if (in_array($mime_type, ['text/plain', '', 'application/octet-stream'])) {
1140 1140
 		if (!$t && preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $source, $rext)) {
1141
-			$t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text'));
1141
+			$t = sql_fetsel('extension', 'spip_types_documents', 'extension='.sql_quote(corriger_extension($rext[1]), '', 'text'));
1142 1142
 		}
1143 1143
 		if (
1144 1144
 			!$t
1145 1145
 			&& preg_match(',^Content-Disposition:\s*attachment;\s*filename=(.*)$,Uims', $headers, $m)
1146 1146
 			&& preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $m[1], $rext)
1147 1147
 		) {
1148
-			$t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text'));
1148
+			$t = sql_fetsel('extension', 'spip_types_documents', 'extension='.sql_quote(corriger_extension($rext[1]), '', 'text'));
1149 1149
 		}
1150 1150
 	}
1151 1151
 
1152 1152
 	// Autre mime/type (ou text/plain avec fichier d'extension inconnue)
1153 1153
 	if (!$t) {
1154
-		$t = sql_fetsel('extension', 'spip_types_documents', 'mime_type=' . sql_quote($mime_type));
1154
+		$t = sql_fetsel('extension', 'spip_types_documents', 'mime_type='.sql_quote($mime_type));
1155 1155
 	}
1156 1156
 
1157 1157
 	// Toujours rien ? (ex: audio/x-ogg au lieu de application/ogg)
@@ -1162,11 +1162,11 @@  discard block
 block discarded – undo
1162 1162
 		&& preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $source, $rext)
1163 1163
 	) {
1164 1164
 		# eviter xxx.3 => 3gp (> SPIP 3)
1165
-		$t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text'));
1165
+		$t = sql_fetsel('extension', 'spip_types_documents', 'extension='.sql_quote(corriger_extension($rext[1]), '', 'text'));
1166 1166
 	}
1167 1167
 
1168 1168
 	if ($t) {
1169
-		spip_log("mime-type $mime_type ok, extension " . $t['extension'], 'distant');
1169
+		spip_log("mime-type $mime_type ok, extension ".$t['extension'], 'distant');
1170 1170
 		return $t['extension'];
1171 1171
 	} else {
1172 1172
 		# par defaut on retombe sur '.bin' si c'est autorise
@@ -1269,7 +1269,7 @@  discard block
 block discarded – undo
1269 1269
 		}
1270 1270
 	} else {
1271 1271
 		$scheme = $t['scheme'];
1272
-		$noproxy = $scheme . '://';
1272
+		$noproxy = $scheme.'://';
1273 1273
 	}
1274 1274
 	if (isset($t['user'])) {
1275 1275
 		// user et pass doivent être passés en urlencodé dans l'URL, on redecode ici
@@ -1284,7 +1284,7 @@  discard block
 block discarded – undo
1284 1284
 	}
1285 1285
 
1286 1286
 	if (!empty($t['query'])) {
1287
-		$path .= '?' . $t['query'];
1287
+		$path .= '?'.$t['query'];
1288 1288
 	}
1289 1289
 
1290 1290
 	$f = lance_requete($method, $scheme, $user, $host, $path, $port, $noproxy, $refuse_gz, $referer, $datas, $vers, $date);
@@ -1358,29 +1358,29 @@  discard block
 block discarded – undo
1358 1358
 	$proxy_user = '';
1359 1359
 	$http_proxy = need_proxy($host);
1360 1360
 	if ($user) {
1361
-		$user = urlencode((string) $user[0]) . ':' . urlencode((string) $user[1]);
1361
+		$user = urlencode((string) $user[0]).':'.urlencode((string) $user[1]);
1362 1362
 	}
1363 1363
 
1364 1364
 	$connect = '';
1365 1365
 	if ($http_proxy) {
1366
-		if (!defined('_PROXY_HTTPS_NOT_VIA_CONNECT') && in_array($scheme, ['tls','ssl'])) {
1367
-			$path_host = ($user ? "$user@" : '') . $host . (($port != 80) ? ":$port" : '');
1368
-			$connect = 'CONNECT ' . $path_host . " $vers\r\n"
1366
+		if (!defined('_PROXY_HTTPS_NOT_VIA_CONNECT') && in_array($scheme, ['tls', 'ssl'])) {
1367
+			$path_host = ($user ? "$user@" : '').$host.(($port != 80) ? ":$port" : '');
1368
+			$connect = 'CONNECT '.$path_host." $vers\r\n"
1369 1369
 				. "Host: $path_host\r\n"
1370 1370
 				. "Proxy-Connection: Keep-Alive\r\n";
1371 1371
 		} else {
1372
-			$path = (in_array($scheme, ['tls','ssl']) ? 'https://' : "$scheme://")
1372
+			$path = (in_array($scheme, ['tls', 'ssl']) ? 'https://' : "$scheme://")
1373 1373
 				. ($user ? "$user@" : '')
1374
-				. "$host" . (($port != 80) ? ":$port" : '') . $path;
1374
+				. "$host".(($port != 80) ? ":$port" : '').$path;
1375 1375
 		}
1376 1376
 		$t2 = @parse_url($http_proxy);
1377 1377
 		$first_host = $t2['host'];
1378 1378
 		$first_port = ($t2['port'] ?? null) ?: 80;
1379 1379
 		if ($t2['user'] ?? null) {
1380
-			$proxy_user = base64_encode($t2['user'] . ':' . $t2['pass']);
1380
+			$proxy_user = base64_encode($t2['user'].':'.$t2['pass']);
1381 1381
 		}
1382 1382
 	} else {
1383
-		$first_host = $noproxy . $host;
1383
+		$first_host = $noproxy.$host;
1384 1384
 		$first_port = $port;
1385 1385
 	}
1386 1386
 
@@ -1403,7 +1403,7 @@  discard block
 block discarded – undo
1403 1403
 		);
1404 1404
 		spip_log("Recuperer $path sur $first_host:$first_port par $f (via CONNECT)", 'connect');
1405 1405
 		if (!$f) {
1406
-			spip_log("Erreur connexion $errno $errstr", 'distant' . _LOG_ERREUR);
1406
+			spip_log("Erreur connexion $errno $errstr", 'distant'._LOG_ERREUR);
1407 1407
 			return $errno;
1408 1408
 		}
1409 1409
 		stream_set_timeout($f, _INC_DISTANT_CONNECT_TIMEOUT);
@@ -1416,7 +1416,7 @@  discard block
 block discarded – undo
1416 1416
 			|| ($res = explode(' ', $res)) === []
1417 1417
 			|| $res[1] !== '200'
1418 1418
 		) {
1419
-			spip_log("Echec CONNECT sur $first_host:$first_port", 'connect' . _LOG_INFO_IMPORTANTE);
1419
+			spip_log("Echec CONNECT sur $first_host:$first_port", 'connect'._LOG_INFO_IMPORTANTE);
1420 1420
 			fclose($f);
1421 1421
 
1422 1422
 			return false;
@@ -1433,7 +1433,7 @@  discard block
 block discarded – undo
1433 1433
 		} while (!$f && $ntry-- && $errno !== 110 && sleep(1));
1434 1434
 		spip_log("Recuperer $path sur $first_host:$first_port par $f");
1435 1435
 		if (!$f) {
1436
-			spip_log("Erreur connexion $errno $errstr", 'distant' . _LOG_ERREUR);
1436
+			spip_log("Erreur connexion $errno $errstr", 'distant'._LOG_ERREUR);
1437 1437
 
1438 1438
 			return $errno;
1439 1439
 		}
@@ -1443,16 +1443,16 @@  discard block
 block discarded – undo
1443 1443
 	$site = $GLOBALS['meta']['adresse_site'] ?? '';
1444 1444
 
1445 1445
 	$host_port = $host;
1446
-	if ($port != (in_array($scheme, ['tls','ssl']) ? 443 : 80)) {
1446
+	if ($port != (in_array($scheme, ['tls', 'ssl']) ? 443 : 80)) {
1447 1447
 		$host_port .= ":$port";
1448 1448
 	}
1449 1449
 	$req = "$method $path $vers\r\n"
1450 1450
 		. "Host: $host_port\r\n"
1451
-		. 'User-Agent: ' . _INC_DISTANT_USER_AGENT . "\r\n"
1452
-		. ($refuse_gz ? '' : ('Accept-Encoding: ' . _INC_DISTANT_CONTENT_ENCODING . "\r\n"))
1451
+		. 'User-Agent: '._INC_DISTANT_USER_AGENT."\r\n"
1452
+		. ($refuse_gz ? '' : ('Accept-Encoding: '._INC_DISTANT_CONTENT_ENCODING."\r\n"))
1453 1453
 		. ($site ? "Referer: $site/$referer\r\n" : '')
1454
-		. ($date ? 'If-Modified-Since: ' . (gmdate('D, d M Y H:i:s', $date) . " GMT\r\n") : '')
1455
-		. ($user ? 'Authorization: Basic ' . base64_encode(urldecode($user)) . "\r\n" : '')
1454
+		. ($date ? 'If-Modified-Since: '.(gmdate('D, d M Y H:i:s', $date)." GMT\r\n") : '')
1455
+		. ($user ? 'Authorization: Basic '.base64_encode(urldecode($user))."\r\n" : '')
1456 1456
 		. ($proxy_user ? "Proxy-Authorization: Basic $proxy_user\r\n" : '')
1457 1457
 		. (strpos($vers, '1.1') ? "Keep-Alive: 300\r\nConnection: keep-alive\r\n" : '');
1458 1458
 
Please login to merge, or discard this patch.
ecrire/action/inscrire_auteur.php 2 patches
Indentation   +235 added lines, -235 removed lines patch added patch discarded remove patch
@@ -20,7 +20,7 @@  discard block
 block discarded – undo
20 20
 
21 21
 
22 22
 if (!defined('_ECRIRE_INC_VERSION')) {
23
-	return;
23
+    return;
24 24
 }
25 25
 
26 26
 
@@ -43,68 +43,68 @@  discard block
 block discarded – undo
43 43
  * @return array|string
44 44
  */
45 45
 function action_inscrire_auteur_dist($statut, $mail_complet, $nom, $options = []) {
46
-	if (!is_array($options)) {
47
-		$options = ['id' => $options];
48
-	}
49
-
50
-	$f = function_exists('test_inscription')
51
-		? 'test_inscription'
52
-		: 'test_inscription_dist';
53
-	$desc = $f($statut, $mail_complet, $nom, $options);
54
-
55
-	// erreur ?
56
-	if (!is_array($desc)) {
57
-		return _T($desc);
58
-	}
59
-
60
-	include_spip('base/abstract_sql');
61
-	$res = sql_select('statut, id_auteur, login, email, nom', 'spip_auteurs', 'email=' . sql_quote($desc['email']));
62
-	// erreur ?
63
-	if (!$res) {
64
-		return _T('titre_probleme_technique');
65
-	}
66
-
67
-	$row = sql_fetch($res);
68
-	sql_free($res);
69
-	if ($row) {
70
-		if (isset($options['force_nouveau']) && $options['force_nouveau'] == true) {
71
-			$desc['id_auteur'] = $row['id_auteur'];
72
-			$desc = inscription_nouveau($desc);
73
-		} else {
74
-			$desc = $row;
75
-		}
76
-	} else // s'il n'existe pas deja, creer les identifiants
77
-	{
78
-		$desc = inscription_nouveau($desc);
79
-	}
80
-
81
-	// erreur ?
82
-	if (!is_array($desc)) {
83
-		return $desc;
84
-	}
85
-
86
-
87
-	// generer le mot de passe (ou le refaire si compte inutilise)
88
-	$desc['pass'] = creer_pass_pour_auteur($desc['id_auteur']);
89
-
90
-	// attribuer un jeton pour confirmation par clic sur un lien
91
-	$desc['jeton'] = auteur_attribuer_jeton($desc['id_auteur']);
92
-
93
-	// charger de suite cette fonction, pour ses utilitaires
94
-	$envoyer_inscription = charger_fonction('envoyer_inscription', '');
95
-	[$sujet, $msg, $from, $head] = $envoyer_inscription($desc, $nom, $statut, $options);
96
-
97
-	$notifications = charger_fonction('notifications', 'inc');
98
-	notifications_envoyer_mails($mail_complet, $msg, $sujet, $from, $head);
99
-
100
-	// Notifications
101
-	$notifications(
102
-		'inscription',
103
-		$desc['id_auteur'],
104
-		['nom' => $desc['nom'], 'email' => $desc['email']]
105
-	);
106
-
107
-	return $desc;
46
+    if (!is_array($options)) {
47
+        $options = ['id' => $options];
48
+    }
49
+
50
+    $f = function_exists('test_inscription')
51
+        ? 'test_inscription'
52
+        : 'test_inscription_dist';
53
+    $desc = $f($statut, $mail_complet, $nom, $options);
54
+
55
+    // erreur ?
56
+    if (!is_array($desc)) {
57
+        return _T($desc);
58
+    }
59
+
60
+    include_spip('base/abstract_sql');
61
+    $res = sql_select('statut, id_auteur, login, email, nom', 'spip_auteurs', 'email=' . sql_quote($desc['email']));
62
+    // erreur ?
63
+    if (!$res) {
64
+        return _T('titre_probleme_technique');
65
+    }
66
+
67
+    $row = sql_fetch($res);
68
+    sql_free($res);
69
+    if ($row) {
70
+        if (isset($options['force_nouveau']) && $options['force_nouveau'] == true) {
71
+            $desc['id_auteur'] = $row['id_auteur'];
72
+            $desc = inscription_nouveau($desc);
73
+        } else {
74
+            $desc = $row;
75
+        }
76
+    } else // s'il n'existe pas deja, creer les identifiants
77
+    {
78
+        $desc = inscription_nouveau($desc);
79
+    }
80
+
81
+    // erreur ?
82
+    if (!is_array($desc)) {
83
+        return $desc;
84
+    }
85
+
86
+
87
+    // generer le mot de passe (ou le refaire si compte inutilise)
88
+    $desc['pass'] = creer_pass_pour_auteur($desc['id_auteur']);
89
+
90
+    // attribuer un jeton pour confirmation par clic sur un lien
91
+    $desc['jeton'] = auteur_attribuer_jeton($desc['id_auteur']);
92
+
93
+    // charger de suite cette fonction, pour ses utilitaires
94
+    $envoyer_inscription = charger_fonction('envoyer_inscription', '');
95
+    [$sujet, $msg, $from, $head] = $envoyer_inscription($desc, $nom, $statut, $options);
96
+
97
+    $notifications = charger_fonction('notifications', 'inc');
98
+    notifications_envoyer_mails($mail_complet, $msg, $sujet, $from, $head);
99
+
100
+    // Notifications
101
+    $notifications(
102
+        'inscription',
103
+        $desc['id_auteur'],
104
+        ['nom' => $desc['nom'], 'email' => $desc['email']]
105
+    );
106
+
107
+    return $desc;
108 108
 }
109 109
 
110 110
 
@@ -127,23 +127,23 @@  discard block
 block discarded – undo
127 127
  *
128 128
  */
129 129
 function test_inscription_dist($statut, $mail, $nom, $options) {
130
-	include_spip('inc/filtres');
131
-	if (!$r = email_valide($mail)) {
132
-		return 'info_email_invalide';
133
-	}
134
-	$nom = trim((string) corriger_caracteres($nom));
135
-	$res = ['email' => $r, 'nom' => $nom, 'prefs' => $statut];
136
-	if (isset($options['login'])) {
137
-		$login = trim((string) corriger_caracteres($options['login']));
138
-		if (strlen($login) >= _LOGIN_TROP_COURT && strlen($nom) <= 64) {
139
-			$res['login'] = $login;
140
-		}
141
-	}
142
-	if (!isset($res['login']) && (strlen($nom) < _LOGIN_TROP_COURT || strlen($nom) > 64)) {
143
-		return 'ecrire:info_login_trop_court';
144
-	}
145
-
146
-	return $res;
130
+    include_spip('inc/filtres');
131
+    if (!$r = email_valide($mail)) {
132
+        return 'info_email_invalide';
133
+    }
134
+    $nom = trim((string) corriger_caracteres($nom));
135
+    $res = ['email' => $r, 'nom' => $nom, 'prefs' => $statut];
136
+    if (isset($options['login'])) {
137
+        $login = trim((string) corriger_caracteres($options['login']));
138
+        if (strlen($login) >= _LOGIN_TROP_COURT && strlen($nom) <= 64) {
139
+            $res['login'] = $login;
140
+        }
141
+    }
142
+    if (!isset($res['login']) && (strlen($nom) < _LOGIN_TROP_COURT || strlen($nom) > 64)) {
143
+        return 'ecrire:info_login_trop_court';
144
+    }
145
+
146
+    return $res;
147 147
 }
148 148
 
149 149
 
@@ -156,29 +156,29 @@  discard block
 block discarded – undo
156 156
  * @return mixed|string
157 157
  */
158 158
 function inscription_nouveau($desc) {
159
-	if (!isset($desc['login']) || !strlen((string) $desc['login'])) {
160
-		$desc['login'] = test_login($desc['nom'], $desc['email']);
161
-	}
159
+    if (!isset($desc['login']) || !strlen((string) $desc['login'])) {
160
+        $desc['login'] = test_login($desc['nom'], $desc['email']);
161
+    }
162 162
 
163
-	$desc['statut'] = 'nouveau';
164
-	include_spip('action/editer_auteur');
165
-	$id_auteur = $desc['id_auteur'] ?? auteur_inserer();
163
+    $desc['statut'] = 'nouveau';
164
+    include_spip('action/editer_auteur');
165
+    $id_auteur = $desc['id_auteur'] ?? auteur_inserer();
166 166
 
167
-	if (!$id_auteur) {
168
-		return _T('titre_probleme_technique');
169
-	}
167
+    if (!$id_auteur) {
168
+        return _T('titre_probleme_technique');
169
+    }
170 170
 
171
-	$desc['lang'] = $GLOBALS['spip_lang'];
171
+    $desc['lang'] = $GLOBALS['spip_lang'];
172 172
 
173
-	include_spip('inc/autoriser');
174
-	// lever l'autorisation pour pouvoir modifier le statut
175
-	autoriser_exception('modifier', 'auteur', $id_auteur);
176
-	auteur_modifier($id_auteur, $desc);
177
-	autoriser_exception('modifier', 'auteur', $id_auteur, false);
173
+    include_spip('inc/autoriser');
174
+    // lever l'autorisation pour pouvoir modifier le statut
175
+    autoriser_exception('modifier', 'auteur', $id_auteur);
176
+    auteur_modifier($id_auteur, $desc);
177
+    autoriser_exception('modifier', 'auteur', $id_auteur, false);
178 178
 
179
-	$desc['id_auteur'] = $id_auteur;
179
+    $desc['id_auteur'] = $id_auteur;
180 180
 
181
-	return $desc;
181
+    return $desc;
182 182
 }
183 183
 
184 184
 
@@ -194,27 +194,27 @@  discard block
 block discarded – undo
194 194
  * @param string $mail
195 195
  */
196 196
 function test_login($nom, $mail): string {
197
-	include_spip('inc/charsets');
198
-	$nom = strtolower((string) translitteration($nom));
199
-	$login_base = preg_replace('/[^\w\d_]/', '_', $nom);
200
-
201
-	// il faut eviter que le login soit vraiment trop court
202
-	if (strlen($login_base) < 3) {
203
-		$mail = strtolower((string) translitteration(preg_replace('/@.*/', '', $mail)));
204
-		$login_base = preg_replace('/[^\w\d]/', '_', $mail);
205
-	}
206
-	if (strlen($login_base) < 3) {
207
-		$login_base = 'user';
208
-	}
209
-
210
-	$login = $login_base;
211
-
212
-	for ($i = 1;; $i++) {
213
-		if (!sql_countsel('spip_auteurs', "login='$login'")) {
214
-			return $login;
215
-		}
216
-		$login = $login_base . $i;
217
-	}
197
+    include_spip('inc/charsets');
198
+    $nom = strtolower((string) translitteration($nom));
199
+    $login_base = preg_replace('/[^\w\d_]/', '_', $nom);
200
+
201
+    // il faut eviter que le login soit vraiment trop court
202
+    if (strlen($login_base) < 3) {
203
+        $mail = strtolower((string) translitteration(preg_replace('/@.*/', '', $mail)));
204
+        $login_base = preg_replace('/[^\w\d]/', '_', $mail);
205
+    }
206
+    if (strlen($login_base) < 3) {
207
+        $login_base = 'user';
208
+    }
209
+
210
+    $login = $login_base;
211
+
212
+    for ($i = 1;; $i++) {
213
+        if (!sql_countsel('spip_auteurs', "login='$login'")) {
214
+            return $login;
215
+        }
216
+        $login = $login_base . $i;
217
+    }
218 218
 }
219 219
 
220 220
 
@@ -232,26 +232,26 @@  discard block
 block discarded – undo
232 232
  */
233 233
 function envoyer_inscription_dist($desc, $nom, $mode, $options = []) {
234 234
 
235
-	$contexte = array_merge($desc, $options);
236
-	$contexte['nom'] = $nom;
237
-	$contexte['mode'] = $mode;
238
-	$contexte['url_confirm'] = generer_url_action('confirmer_inscription', '', true, true);
239
-	$contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'email', $desc['email']);
240
-	$contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'jeton', $desc['jeton']);
241
-	// S'il y a l'option redirect, on l'ajoute directement ici
242
-	if (isset($options['redirect'])) {
243
-		$contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'redirect', $options['redirect']);
244
-	}
245
-
246
-	$modele_mail = 'modeles/mail_inscription';
247
-	if (isset($options['modele_mail']) && $options['modele_mail']) {
248
-		$modele_mail = $options['modele_mail'];
249
-	}
250
-	$message = recuperer_fond($modele_mail, $contexte);
251
-	$from = ($options['from'] ?? '');
252
-	$head = '';
253
-
254
-	return ['', $message, $from, $head];
235
+    $contexte = array_merge($desc, $options);
236
+    $contexte['nom'] = $nom;
237
+    $contexte['mode'] = $mode;
238
+    $contexte['url_confirm'] = generer_url_action('confirmer_inscription', '', true, true);
239
+    $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'email', $desc['email']);
240
+    $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'jeton', $desc['jeton']);
241
+    // S'il y a l'option redirect, on l'ajoute directement ici
242
+    if (isset($options['redirect'])) {
243
+        $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'redirect', $options['redirect']);
244
+    }
245
+
246
+    $modele_mail = 'modeles/mail_inscription';
247
+    if (isset($options['modele_mail']) && $options['modele_mail']) {
248
+        $modele_mail = $options['modele_mail'];
249
+    }
250
+    $message = recuperer_fond($modele_mail, $contexte);
251
+    $from = ($options['from'] ?? '');
252
+    $head = '';
253
+
254
+    return ['', $message, $from, $head];
255 255
 }
256 256
 
257 257
 
@@ -262,12 +262,12 @@  discard block
 block discarded – undo
262 262
  * @return string
263 263
  */
264 264
 function creer_pass_pour_auteur($id_auteur) {
265
-	include_spip('inc/acces');
266
-	$pass = creer_pass_aleatoire(max(_PASS_LONGUEUR_MINI, 16), $id_auteur);
267
-	include_spip('action/editer_auteur');
268
-	auteur_instituer($id_auteur, ['pass' => $pass]);
265
+    include_spip('inc/acces');
266
+    $pass = creer_pass_aleatoire(max(_PASS_LONGUEUR_MINI, 16), $id_auteur);
267
+    include_spip('action/editer_auteur');
268
+    auteur_instituer($id_auteur, ['pass' => $pass]);
269 269
 
270
-	return $pass;
270
+    return $pass;
271 271
 }
272 272
 
273 273
 /**
@@ -280,17 +280,17 @@  discard block
 block discarded – undo
280 280
  * @return string
281 281
  */
282 282
 function tester_statut_inscription($statut_tmp, $id) {
283
-	include_spip('inc/autoriser');
284
-	if ($statut_tmp) {
285
-		return autoriser('inscrireauteur', $statut_tmp, $id) ? $statut_tmp : '';
286
-	} elseif (
287
-		autoriser('inscrireauteur', $statut_tmp = '1comite', $id)
288
-		|| autoriser('inscrireauteur', $statut_tmp = '6forum', $id)
289
-	) {
290
-		return $statut_tmp;
291
-	}
292
-
293
-	return '';
283
+    include_spip('inc/autoriser');
284
+    if ($statut_tmp) {
285
+        return autoriser('inscrireauteur', $statut_tmp, $id) ? $statut_tmp : '';
286
+    } elseif (
287
+        autoriser('inscrireauteur', $statut_tmp = '1comite', $id)
288
+        || autoriser('inscrireauteur', $statut_tmp = '6forum', $id)
289
+    ) {
290
+        return $statut_tmp;
291
+    }
292
+
293
+    return '';
294 294
 }
295 295
 
296 296
 
@@ -304,35 +304,35 @@  discard block
 block discarded – undo
304 304
  * @return array
305 305
  */
306 306
 function confirmer_statut_inscription($auteur) {
307
-	// securite
308
-	if ($auteur['statut'] != 'nouveau') {
309
-		return $auteur;
310
-	}
311
-
312
-	$s = $auteur['prefs'];
313
-	// securite, au cas ou prefs aurait ete corrompu (ou deja ecrase par un tableau serialize)
314
-	if (!preg_match(',^\w+$,', (string) $s)) {
315
-		$s = '6forum';
316
-	}
317
-	include_spip('inc/autoriser');
318
-	if (!autoriser('inscrireauteur', $s)) {
319
-		return $auteur;
320
-	}
321
-
322
-	include_spip('inc/autoriser');
323
-	// accorder l'autorisation de modif du statut auteur
324
-	autoriser_exception('modifier', 'auteur', $auteur['id_auteur']);
325
-	include_spip('action/editer_auteur');
326
-	// changer le statut
327
-	auteur_modifier($auteur['id_auteur'], ['statut' => $s]);
328
-	unset($_COOKIE['spip_session']); // forcer la maj de la session
329
-	// lever l'autorisation de modif du statut auteur
330
-	autoriser_exception('modifier', 'auteur', $auteur['id_auteur'], false);
331
-
332
-	// mettre a jour le statut
333
-	$auteur['statut'] = $s;
334
-
335
-	return $auteur;
307
+    // securite
308
+    if ($auteur['statut'] != 'nouveau') {
309
+        return $auteur;
310
+    }
311
+
312
+    $s = $auteur['prefs'];
313
+    // securite, au cas ou prefs aurait ete corrompu (ou deja ecrase par un tableau serialize)
314
+    if (!preg_match(',^\w+$,', (string) $s)) {
315
+        $s = '6forum';
316
+    }
317
+    include_spip('inc/autoriser');
318
+    if (!autoriser('inscrireauteur', $s)) {
319
+        return $auteur;
320
+    }
321
+
322
+    include_spip('inc/autoriser');
323
+    // accorder l'autorisation de modif du statut auteur
324
+    autoriser_exception('modifier', 'auteur', $auteur['id_auteur']);
325
+    include_spip('action/editer_auteur');
326
+    // changer le statut
327
+    auteur_modifier($auteur['id_auteur'], ['statut' => $s]);
328
+    unset($_COOKIE['spip_session']); // forcer la maj de la session
329
+    // lever l'autorisation de modif du statut auteur
330
+    autoriser_exception('modifier', 'auteur', $auteur['id_auteur'], false);
331
+
332
+    // mettre a jour le statut
333
+    $auteur['statut'] = $s;
334
+
335
+    return $auteur;
336 336
 }
337 337
 
338 338
 
@@ -346,20 +346,20 @@  discard block
 block discarded – undo
346 346
  * @return string
347 347
  */
348 348
 function auteur_attribuer_jeton($id_auteur): string {
349
-	include_spip('base/abstract_sql');
350
-	include_spip('inc/acces');
351
-
352
-	// s'assurer de l'unicite du jeton pour le couple (email,cookie)
353
-	do {
354
-		// Un morceau du jeton est lisible en bdd pour éviter de devoir déchiffrer
355
-		// tous les jetons connus pour vérifier le jeton d’un auteur.
356
-		$public = substr((string) creer_uniqid(), 0, 7) . '.';
357
-		$jeton = $public . creer_uniqid();
358
-		$jeton_chiffre_prefixe = $public . Chiffrement::chiffrer($jeton, SpipCles::secret_du_site());
359
-		sql_updateq('spip_auteurs', ['cookie_oubli' => $jeton_chiffre_prefixe], 'id_auteur=' . (int) $id_auteur);
360
-	} while (sql_countsel('spip_auteurs', 'cookie_oubli=' . sql_quote($jeton_chiffre_prefixe, '', 'string')) > 1);
361
-
362
-	return $jeton;
349
+    include_spip('base/abstract_sql');
350
+    include_spip('inc/acces');
351
+
352
+    // s'assurer de l'unicite du jeton pour le couple (email,cookie)
353
+    do {
354
+        // Un morceau du jeton est lisible en bdd pour éviter de devoir déchiffrer
355
+        // tous les jetons connus pour vérifier le jeton d’un auteur.
356
+        $public = substr((string) creer_uniqid(), 0, 7) . '.';
357
+        $jeton = $public . creer_uniqid();
358
+        $jeton_chiffre_prefixe = $public . Chiffrement::chiffrer($jeton, SpipCles::secret_du_site());
359
+        sql_updateq('spip_auteurs', ['cookie_oubli' => $jeton_chiffre_prefixe], 'id_auteur=' . (int) $id_auteur);
360
+    } while (sql_countsel('spip_auteurs', 'cookie_oubli=' . sql_quote($jeton_chiffre_prefixe, '', 'string')) > 1);
361
+
362
+    return $jeton;
363 363
 }
364 364
 
365 365
 /**
@@ -373,19 +373,19 @@  discard block
 block discarded – undo
373 373
  * @return string|null
374 374
  */
375 375
 function auteur_lire_jeton(int $id_auteur, bool $autoInit = false): ?string {
376
-	include_spip('base/abstract_sql');
377
-	$jeton_chiffre_prefixe = sql_getfetsel('cookie_oubli', 'spip_auteurs', 'id_auteur=' . $id_auteur);
378
-	if ($jeton_chiffre_prefixe) {
379
-		$jeton_chiffre = substr((string) $jeton_chiffre_prefixe, 8);
380
-		$jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site());
381
-		if ($jeton) {
382
-			return $jeton;
383
-		}
384
-	}
385
-	if ($autoInit) {
386
-		return auteur_attribuer_jeton($id_auteur);
387
-	}
388
-	return null;
376
+    include_spip('base/abstract_sql');
377
+    $jeton_chiffre_prefixe = sql_getfetsel('cookie_oubli', 'spip_auteurs', 'id_auteur=' . $id_auteur);
378
+    if ($jeton_chiffre_prefixe) {
379
+        $jeton_chiffre = substr((string) $jeton_chiffre_prefixe, 8);
380
+        $jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site());
381
+        if ($jeton) {
382
+            return $jeton;
383
+        }
384
+    }
385
+    if ($autoInit) {
386
+        return auteur_attribuer_jeton($id_auteur);
387
+    }
388
+    return null;
389 389
 }
390 390
 
391 391
 /**
@@ -395,29 +395,29 @@  discard block
 block discarded – undo
395 395
  * @return array|bool
396 396
  */
397 397
 function auteur_verifier_jeton($jeton) {
398
-	// refuser un jeton corrompu
399
-	if (preg_match(',[^0-9a-f.],i', $jeton)) {
400
-		return false;
401
-	}
402
-
403
-	include_spip('base/abstract_sql');
404
-	$public = substr($jeton, 0, 8);
405
-
406
-	// Les auteurs qui ont un jetons ressemblant
407
-	$auteurs = sql_allfetsel('*', 'spip_auteurs', 'cookie_oubli LIKE ' . sql_quote($public . '%'));
408
-	foreach ($auteurs as $auteur) {
409
-		$jeton_chiffre = substr((string) $auteur['cookie_oubli'], 8);
410
-		try {
411
-			$_jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site());
412
-		} catch (\Exception $e) {
413
-			spip_log('Échec du déchiffrage du jeton d’auteur: ' . $e->getMessage(), 'chiffrer.' . _LOG_ERREUR);
414
-			return false;
415
-		}
416
-		if ($_jeton && hash_equals($jeton, $_jeton)) {
417
-			return $auteur;
418
-		}
419
-	}
420
-	return false;
398
+    // refuser un jeton corrompu
399
+    if (preg_match(',[^0-9a-f.],i', $jeton)) {
400
+        return false;
401
+    }
402
+
403
+    include_spip('base/abstract_sql');
404
+    $public = substr($jeton, 0, 8);
405
+
406
+    // Les auteurs qui ont un jetons ressemblant
407
+    $auteurs = sql_allfetsel('*', 'spip_auteurs', 'cookie_oubli LIKE ' . sql_quote($public . '%'));
408
+    foreach ($auteurs as $auteur) {
409
+        $jeton_chiffre = substr((string) $auteur['cookie_oubli'], 8);
410
+        try {
411
+            $_jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site());
412
+        } catch (\Exception $e) {
413
+            spip_log('Échec du déchiffrage du jeton d’auteur: ' . $e->getMessage(), 'chiffrer.' . _LOG_ERREUR);
414
+            return false;
415
+        }
416
+        if ($_jeton && hash_equals($jeton, $_jeton)) {
417
+            return $auteur;
418
+        }
419
+    }
420
+    return false;
421 421
 }
422 422
 
423 423
 /**
@@ -427,6 +427,6 @@  discard block
 block discarded – undo
427 427
  * @return bool
428 428
  */
429 429
 function auteur_effacer_jeton($id_auteur) {
430
-	include_spip('base/abstract_sql');
431
-	return sql_updateq('spip_auteurs', ['cookie_oubli' => ''], 'id_auteur=' . (int) $id_auteur);
430
+    include_spip('base/abstract_sql');
431
+    return sql_updateq('spip_auteurs', ['cookie_oubli' => ''], 'id_auteur=' . (int) $id_auteur);
432 432
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -58,7 +58,7 @@  discard block
 block discarded – undo
58 58
 	}
59 59
 
60 60
 	include_spip('base/abstract_sql');
61
-	$res = sql_select('statut, id_auteur, login, email, nom', 'spip_auteurs', 'email=' . sql_quote($desc['email']));
61
+	$res = sql_select('statut, id_auteur, login, email, nom', 'spip_auteurs', 'email='.sql_quote($desc['email']));
62 62
 	// erreur ?
63 63
 	if (!$res) {
64 64
 		return _T('titre_probleme_technique');
@@ -209,11 +209,11 @@  discard block
 block discarded – undo
209 209
 
210 210
 	$login = $login_base;
211 211
 
212
-	for ($i = 1;; $i++) {
212
+	for ($i = 1; ; $i++) {
213 213
 		if (!sql_countsel('spip_auteurs', "login='$login'")) {
214 214
 			return $login;
215 215
 		}
216
-		$login = $login_base . $i;
216
+		$login = $login_base.$i;
217 217
 	}
218 218
 }
219 219
 
@@ -353,11 +353,11 @@  discard block
 block discarded – undo
353 353
 	do {
354 354
 		// Un morceau du jeton est lisible en bdd pour éviter de devoir déchiffrer
355 355
 		// tous les jetons connus pour vérifier le jeton d’un auteur.
356
-		$public = substr((string) creer_uniqid(), 0, 7) . '.';
357
-		$jeton = $public . creer_uniqid();
358
-		$jeton_chiffre_prefixe = $public . Chiffrement::chiffrer($jeton, SpipCles::secret_du_site());
359
-		sql_updateq('spip_auteurs', ['cookie_oubli' => $jeton_chiffre_prefixe], 'id_auteur=' . (int) $id_auteur);
360
-	} while (sql_countsel('spip_auteurs', 'cookie_oubli=' . sql_quote($jeton_chiffre_prefixe, '', 'string')) > 1);
356
+		$public = substr((string) creer_uniqid(), 0, 7).'.';
357
+		$jeton = $public.creer_uniqid();
358
+		$jeton_chiffre_prefixe = $public.Chiffrement::chiffrer($jeton, SpipCles::secret_du_site());
359
+		sql_updateq('spip_auteurs', ['cookie_oubli' => $jeton_chiffre_prefixe], 'id_auteur='.(int) $id_auteur);
360
+	} while (sql_countsel('spip_auteurs', 'cookie_oubli='.sql_quote($jeton_chiffre_prefixe, '', 'string')) > 1);
361 361
 
362 362
 	return $jeton;
363 363
 }
@@ -374,7 +374,7 @@  discard block
 block discarded – undo
374 374
  */
375 375
 function auteur_lire_jeton(int $id_auteur, bool $autoInit = false): ?string {
376 376
 	include_spip('base/abstract_sql');
377
-	$jeton_chiffre_prefixe = sql_getfetsel('cookie_oubli', 'spip_auteurs', 'id_auteur=' . $id_auteur);
377
+	$jeton_chiffre_prefixe = sql_getfetsel('cookie_oubli', 'spip_auteurs', 'id_auteur='.$id_auteur);
378 378
 	if ($jeton_chiffre_prefixe) {
379 379
 		$jeton_chiffre = substr((string) $jeton_chiffre_prefixe, 8);
380 380
 		$jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site());
@@ -404,13 +404,13 @@  discard block
 block discarded – undo
404 404
 	$public = substr($jeton, 0, 8);
405 405
 
406 406
 	// Les auteurs qui ont un jetons ressemblant
407
-	$auteurs = sql_allfetsel('*', 'spip_auteurs', 'cookie_oubli LIKE ' . sql_quote($public . '%'));
407
+	$auteurs = sql_allfetsel('*', 'spip_auteurs', 'cookie_oubli LIKE '.sql_quote($public.'%'));
408 408
 	foreach ($auteurs as $auteur) {
409 409
 		$jeton_chiffre = substr((string) $auteur['cookie_oubli'], 8);
410 410
 		try {
411 411
 			$_jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site());
412 412
 		} catch (\Exception $e) {
413
-			spip_log('Échec du déchiffrage du jeton d’auteur: ' . $e->getMessage(), 'chiffrer.' . _LOG_ERREUR);
413
+			spip_log('Échec du déchiffrage du jeton d’auteur: '.$e->getMessage(), 'chiffrer.'._LOG_ERREUR);
414 414
 			return false;
415 415
 		}
416 416
 		if ($_jeton && hash_equals($jeton, $_jeton)) {
@@ -428,5 +428,5 @@  discard block
 block discarded – undo
428 428
  */
429 429
 function auteur_effacer_jeton($id_auteur) {
430 430
 	include_spip('base/abstract_sql');
431
-	return sql_updateq('spip_auteurs', ['cookie_oubli' => ''], 'id_auteur=' . (int) $id_auteur);
431
+	return sql_updateq('spip_auteurs', ['cookie_oubli' => ''], 'id_auteur='.(int) $id_auteur);
432 432
 }
Please login to merge, or discard this patch.
ecrire/inc/session.php 2 patches
Indentation   +497 added lines, -497 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
  */
19 19
 
20 20
 if (!defined('_ECRIRE_INC_VERSION')) {
21
-	return;
21
+    return;
22 22
 }
23 23
 
24 24
 
@@ -39,15 +39,15 @@  discard block
 block discarded – undo
39 39
  * @return bool|null|void
40 40
  */
41 41
 function inc_session_dist($auteur = false) {
42
-	if (is_numeric($auteur)) {
43
-		return supprimer_sessions($auteur, $auteur > 0);
44
-	} else {
45
-		if (is_array($auteur)) {
46
-			return ajouter_session($auteur);
47
-		} else {
48
-			return verifier_session($auteur);
49
-		}
50
-	}
42
+    if (is_numeric($auteur)) {
43
+        return supprimer_sessions($auteur, $auteur > 0);
44
+    } else {
45
+        if (is_array($auteur)) {
46
+            return ajouter_session($auteur);
47
+        } else {
48
+            return verifier_session($auteur);
49
+        }
50
+    }
51 51
 }
52 52
 
53 53
 
@@ -76,37 +76,37 @@  discard block
 block discarded – undo
76 76
  */
77 77
 function supprimer_sessions($id_auteur, $toutes = true, $actives = true) {
78 78
 
79
-	$nb_files = 0;
80
-	$nb_max_files = (defined('_MAX_NB_SESSIONS_OUVERTES') ? _MAX_NB_SESSIONS_OUVERTES : 1000);
81
-	spip_log("supprimer sessions auteur $id_auteur", 'session');
82
-	if ($toutes || $id_auteur !== $GLOBALS['visiteur_session']['id_auteur']) {
83
-		if ($dir = opendir(_DIR_SESSIONS)) {
84
-			$t = $_SERVER['REQUEST_TIME']  - (4 * _RENOUVELLE_ALEA); // 48h par defaut
85
-			$t_short = $_SERVER['REQUEST_TIME']  - max(_RENOUVELLE_ALEA / 4, 3 * 3600); // 3h par defaut
86
-			while (($f = readdir($dir)) !== false) {
87
-				$nb_files++;
88
-				if (preg_match(',^[^\d-]*(-?\d+)_\w{32}\.php[3]?$,', $f, $regs)) {
89
-					$f = _DIR_SESSIONS . $f;
90
-					if ($actives && $regs[1] == $id_auteur || $t > filemtime($f)) {
91
-						spip_unlink($f);
92
-					}
93
-					// si il y a trop de sessions ouvertes, on purge les sessions anonymes de plus de 3H
94
-					// cf http://core.spip.org/issues/3276
95
-					elseif ($nb_files > $nb_max_files && !intval($regs[1]) && $t_short > filemtime($f)) {
96
-						spip_unlink($f);
97
-					}
98
-				}
99
-			}
100
-		}
101
-	} else {
102
-		verifier_session();
103
-		if ($cookie = lire_cookie_session()) {
104
-			spip_unlink(chemin_fichier_session('alea_ephemere', $cookie, true));
105
-		}
106
-	}
107
-
108
-	// forcer le recalcul de la session courante
109
-	spip_session(true);
79
+    $nb_files = 0;
80
+    $nb_max_files = (defined('_MAX_NB_SESSIONS_OUVERTES') ? _MAX_NB_SESSIONS_OUVERTES : 1000);
81
+    spip_log("supprimer sessions auteur $id_auteur", 'session');
82
+    if ($toutes || $id_auteur !== $GLOBALS['visiteur_session']['id_auteur']) {
83
+        if ($dir = opendir(_DIR_SESSIONS)) {
84
+            $t = $_SERVER['REQUEST_TIME']  - (4 * _RENOUVELLE_ALEA); // 48h par defaut
85
+            $t_short = $_SERVER['REQUEST_TIME']  - max(_RENOUVELLE_ALEA / 4, 3 * 3600); // 3h par defaut
86
+            while (($f = readdir($dir)) !== false) {
87
+                $nb_files++;
88
+                if (preg_match(',^[^\d-]*(-?\d+)_\w{32}\.php[3]?$,', $f, $regs)) {
89
+                    $f = _DIR_SESSIONS . $f;
90
+                    if ($actives && $regs[1] == $id_auteur || $t > filemtime($f)) {
91
+                        spip_unlink($f);
92
+                    }
93
+                    // si il y a trop de sessions ouvertes, on purge les sessions anonymes de plus de 3H
94
+                    // cf http://core.spip.org/issues/3276
95
+                    elseif ($nb_files > $nb_max_files && !intval($regs[1]) && $t_short > filemtime($f)) {
96
+                        spip_unlink($f);
97
+                    }
98
+                }
99
+            }
100
+        }
101
+    } else {
102
+        verifier_session();
103
+        if ($cookie = lire_cookie_session()) {
104
+            spip_unlink(chemin_fichier_session('alea_ephemere', $cookie, true));
105
+        }
106
+    }
107
+
108
+    // forcer le recalcul de la session courante
109
+    spip_session(true);
110 110
 }
111 111
 
112 112
 /**
@@ -124,124 +124,124 @@  discard block
 block discarded – undo
124 124
  * @return bool|string
125 125
  */
126 126
 function ajouter_session($auteur) {
127
-	// Si le client a deja une session valide pour son id_auteur
128
-	// on conserve le meme fichier
129
-
130
-	// Attention un visiteur peut avoir une session et un id=0,
131
-	// => ne pas melanger les sessions des differents visiteurs
132
-	$id_auteur = isset($auteur['id_auteur']) ? intval($auteur['id_auteur']) : 0;
133
-
134
-	// Si ce n'est pas un inscrit (les inscrits ont toujours des choses en session)
135
-	// on va vérifier s'il y a vraiment des choses à écrire
136
-	if (!$id_auteur) {
137
-		// On supprime les données de base pour voir le contenu réel de la session
138
-		$auteur_verif = $auteur;
139
-		if (isset($auteur_verif['id_auteur'])) {
140
-			unset($auteur_verif['id_auteur']);
141
-		}
142
-		if (isset($auteur_verif['hash_env'])) {
143
-			unset($auteur_verif['hash_env']);
144
-		}
145
-		if (isset($auteur_verif['ip_change'])) {
146
-			unset($auteur_verif['ip_change']);
147
-		}
148
-		if (isset($auteur_verif['date_session'])) {
149
-			unset($auteur_verif['date_session']);
150
-		}
151
-
152
-		// Les variables vraiment nulle ne sont pas à prendre en compte non plus
153
-		foreach ($auteur_verif as $variable => $valeur) {
154
-			if ($valeur === null) {
155
-				unset($auteur_verif[$variable]);
156
-			}
157
-		}
158
-
159
-		// Si après ça la session est vide alors on supprime l'éventuel fichier et on arrête là
160
-		if (!$auteur_verif) {
161
-			if ($cookie = lire_cookie_session()) {
162
-				if (isset($_SESSION[$cookie])) {
163
-					unset($_SESSION[$cookie]);
164
-				}
165
-				unset($_COOKIE['spip_session']);
166
-			}
167
-
168
-			return false;
169
-		}
170
-	}
171
-
172
-	if (
173
-		(!$cookie = lire_cookie_session())
174
-		|| intval($cookie) !== $id_auteur
175
-	) {
176
-		$cookie = $id_auteur . '_' . md5(uniqid(random_int(0, mt_getrandmax()), true));
177
-	}
178
-
179
-	// Maintenant on sait qu'on a des choses à écrire
180
-	// On s'assure d'avoir au moins ces valeurs
181
-	$auteur['id_auteur'] = $id_auteur;
182
-	if (!isset($auteur['hash_env'])) {
183
-		$auteur['hash_env'] = hash_env();
184
-	}
185
-	if (!isset($auteur['ip_change'])) {
186
-		$auteur['ip_change'] = false;
187
-	}
188
-
189
-	if (!isset($auteur['date_session'])) {
190
-		$auteur['date_session'] = time();
191
-	}
192
-	if (
193
-		isset($auteur['prefs'])
194
-		&& is_string($auteur['prefs'])
195
-		&& ($prefs = @unserialize($auteur['prefs']))
196
-	) {
197
-		$auteur['prefs'] = $prefs;
198
-	}
199
-
200
-	$fichier_session = '';
201
-
202
-	// les sessions anonymes sont stockees dans $_SESSION
203
-	if (!$id_auteur) {
204
-		spip_php_session_start();
205
-		$_SESSION[$cookie] = preparer_ecriture_session($auteur);
206
-	} else {
207
-		$fichier_session = chemin_fichier_session('alea_ephemere', $cookie);
208
-		if (!ecrire_fichier_session($fichier_session, $auteur)) {
209
-			spip_log('Echec ecriture fichier session ' . $fichier_session, 'session' . _LOG_HS);
210
-			include_spip('inc/minipres');
211
-			echo minipres();
212
-			exit;
213
-		}
214
-		// verifier et limiter le nombre maxi de sessions
215
-		// https://core.spip.net/issues/3807
216
-		lister_sessions_auteur($id_auteur);
217
-	}
218
-
219
-	// poser le cookie de session SPIP
220
-	include_spip('inc/cookie');
221
-	$duree = definir_duree_cookie_session($auteur);
222
-	$cookie = set_cookie_session($cookie, time() + $duree);
223
-	spip_log("ajoute session $fichier_session cookie $duree", 'session');
224
-
225
-	// Si on est admin, poser le cookie de correspondance
226
-	if (!function_exists('autoriser')) {
227
-		include_spip('inc/autoriser');
228
-	}
229
-	if (autoriser('ecrire', '', '', $auteur) && _DUREE_COOKIE_ADMIN) {
230
-		spip_setcookie(
231
-			'spip_admin',
232
-			'@' . ($auteur['email'] ?: $auteur['login']),
233
-			time() + max(_DUREE_COOKIE_ADMIN, $duree),
234
-			httponly: true
235
-		);
236
-	} else {
237
-		// sinon le supprimer ...
238
-		spip_setcookie('spip_admin', '', 1, httponly: true);
239
-	}
240
-
241
-	# on en profite pour purger les vieilles sessions anonymes abandonnees
242
-	# supprimer_sessions(0, true, false);
243
-
244
-	return $cookie;
127
+    // Si le client a deja une session valide pour son id_auteur
128
+    // on conserve le meme fichier
129
+
130
+    // Attention un visiteur peut avoir une session et un id=0,
131
+    // => ne pas melanger les sessions des differents visiteurs
132
+    $id_auteur = isset($auteur['id_auteur']) ? intval($auteur['id_auteur']) : 0;
133
+
134
+    // Si ce n'est pas un inscrit (les inscrits ont toujours des choses en session)
135
+    // on va vérifier s'il y a vraiment des choses à écrire
136
+    if (!$id_auteur) {
137
+        // On supprime les données de base pour voir le contenu réel de la session
138
+        $auteur_verif = $auteur;
139
+        if (isset($auteur_verif['id_auteur'])) {
140
+            unset($auteur_verif['id_auteur']);
141
+        }
142
+        if (isset($auteur_verif['hash_env'])) {
143
+            unset($auteur_verif['hash_env']);
144
+        }
145
+        if (isset($auteur_verif['ip_change'])) {
146
+            unset($auteur_verif['ip_change']);
147
+        }
148
+        if (isset($auteur_verif['date_session'])) {
149
+            unset($auteur_verif['date_session']);
150
+        }
151
+
152
+        // Les variables vraiment nulle ne sont pas à prendre en compte non plus
153
+        foreach ($auteur_verif as $variable => $valeur) {
154
+            if ($valeur === null) {
155
+                unset($auteur_verif[$variable]);
156
+            }
157
+        }
158
+
159
+        // Si après ça la session est vide alors on supprime l'éventuel fichier et on arrête là
160
+        if (!$auteur_verif) {
161
+            if ($cookie = lire_cookie_session()) {
162
+                if (isset($_SESSION[$cookie])) {
163
+                    unset($_SESSION[$cookie]);
164
+                }
165
+                unset($_COOKIE['spip_session']);
166
+            }
167
+
168
+            return false;
169
+        }
170
+    }
171
+
172
+    if (
173
+        (!$cookie = lire_cookie_session())
174
+        || intval($cookie) !== $id_auteur
175
+    ) {
176
+        $cookie = $id_auteur . '_' . md5(uniqid(random_int(0, mt_getrandmax()), true));
177
+    }
178
+
179
+    // Maintenant on sait qu'on a des choses à écrire
180
+    // On s'assure d'avoir au moins ces valeurs
181
+    $auteur['id_auteur'] = $id_auteur;
182
+    if (!isset($auteur['hash_env'])) {
183
+        $auteur['hash_env'] = hash_env();
184
+    }
185
+    if (!isset($auteur['ip_change'])) {
186
+        $auteur['ip_change'] = false;
187
+    }
188
+
189
+    if (!isset($auteur['date_session'])) {
190
+        $auteur['date_session'] = time();
191
+    }
192
+    if (
193
+        isset($auteur['prefs'])
194
+        && is_string($auteur['prefs'])
195
+        && ($prefs = @unserialize($auteur['prefs']))
196
+    ) {
197
+        $auteur['prefs'] = $prefs;
198
+    }
199
+
200
+    $fichier_session = '';
201
+
202
+    // les sessions anonymes sont stockees dans $_SESSION
203
+    if (!$id_auteur) {
204
+        spip_php_session_start();
205
+        $_SESSION[$cookie] = preparer_ecriture_session($auteur);
206
+    } else {
207
+        $fichier_session = chemin_fichier_session('alea_ephemere', $cookie);
208
+        if (!ecrire_fichier_session($fichier_session, $auteur)) {
209
+            spip_log('Echec ecriture fichier session ' . $fichier_session, 'session' . _LOG_HS);
210
+            include_spip('inc/minipres');
211
+            echo minipres();
212
+            exit;
213
+        }
214
+        // verifier et limiter le nombre maxi de sessions
215
+        // https://core.spip.net/issues/3807
216
+        lister_sessions_auteur($id_auteur);
217
+    }
218
+
219
+    // poser le cookie de session SPIP
220
+    include_spip('inc/cookie');
221
+    $duree = definir_duree_cookie_session($auteur);
222
+    $cookie = set_cookie_session($cookie, time() + $duree);
223
+    spip_log("ajoute session $fichier_session cookie $duree", 'session');
224
+
225
+    // Si on est admin, poser le cookie de correspondance
226
+    if (!function_exists('autoriser')) {
227
+        include_spip('inc/autoriser');
228
+    }
229
+    if (autoriser('ecrire', '', '', $auteur) && _DUREE_COOKIE_ADMIN) {
230
+        spip_setcookie(
231
+            'spip_admin',
232
+            '@' . ($auteur['email'] ?: $auteur['login']),
233
+            time() + max(_DUREE_COOKIE_ADMIN, $duree),
234
+            httponly: true
235
+        );
236
+    } else {
237
+        // sinon le supprimer ...
238
+        spip_setcookie('spip_admin', '', 1, httponly: true);
239
+    }
240
+
241
+    # on en profite pour purger les vieilles sessions anonymes abandonnees
242
+    # supprimer_sessions(0, true, false);
243
+
244
+    return $cookie;
245 245
 }
246 246
 
247 247
 /**
@@ -261,54 +261,54 @@  discard block
 block discarded – undo
261 261
  *     Durée en secondes
262 262
 **/
263 263
 function definir_duree_cookie_session($auteur) {
264
-	$coef = 2;
265
-	if (isset($auteur['cookie'])) {
266
-		if (is_numeric($auteur['cookie'])) {
267
-			$coef = $auteur['cookie'];
268
-		} else {
269
-			$coef = 20;
270
-		}
271
-	}
272
-	return (int)(_RENOUVELLE_ALEA * $coef);
264
+    $coef = 2;
265
+    if (isset($auteur['cookie'])) {
266
+        if (is_numeric($auteur['cookie'])) {
267
+            $coef = $auteur['cookie'];
268
+        } else {
269
+            $coef = 20;
270
+        }
271
+    }
272
+    return (int)(_RENOUVELLE_ALEA * $coef);
273 273
 }
274 274
 
275 275
 /**
276 276
  * Lire le cookie de session et le valider de façon centralisée
277 277
  */
278 278
 function lire_cookie_session(bool $accepter_test = false): ?string {
279
-	static $cookie_valide = [];
280
-	// pas de cookie ?
281
-	if (!isset($_COOKIE['spip_session'])) {
282
-		return null;
283
-	}
284
-
285
-	if (array_key_exists($_COOKIE['spip_session'], $cookie_valide)) {
286
-		return $cookie_valide[$_COOKIE['spip_session']];
287
-	}
288
-
289
-	if ($accepter_test && $_COOKIE['spip_session'] === 'test_echec_cookie') {
290
-		return 'test_echec_cookie';
291
-	}
292
-
293
-	if (!preg_match(",^\d+_[0-9a-f]{32}$,", $_COOKIE['spip_session'])) {
294
-		// cookie invalide ?
295
-		effacer_cookie_session();
296
-		return null;
297
-	}
298
-
299
-	// ok
300
-	$cookie_valide[$_COOKIE['spip_session']] = $_COOKIE['spip_session'];
301
-
302
-	return $_COOKIE['spip_session'];
279
+    static $cookie_valide = [];
280
+    // pas de cookie ?
281
+    if (!isset($_COOKIE['spip_session'])) {
282
+        return null;
283
+    }
284
+
285
+    if (array_key_exists($_COOKIE['spip_session'], $cookie_valide)) {
286
+        return $cookie_valide[$_COOKIE['spip_session']];
287
+    }
288
+
289
+    if ($accepter_test && $_COOKIE['spip_session'] === 'test_echec_cookie') {
290
+        return 'test_echec_cookie';
291
+    }
292
+
293
+    if (!preg_match(",^\d+_[0-9a-f]{32}$,", $_COOKIE['spip_session'])) {
294
+        // cookie invalide ?
295
+        effacer_cookie_session();
296
+        return null;
297
+    }
298
+
299
+    // ok
300
+    $cookie_valide[$_COOKIE['spip_session']] = $_COOKIE['spip_session'];
301
+
302
+    return $_COOKIE['spip_session'];
303 303
 }
304 304
 
305 305
 /** Annuler le cookie de session */
306 306
 function effacer_cookie_session(): void {
307
-	// supprimer le cookie
308
-	if (isset($_COOKIE['spip_session'])) {
309
-		spip_setcookie('spip_session', '', time() - 24 * 3600, httponly: true);
310
-		unset($_COOKIE['spip_session']);
311
-	}
307
+    // supprimer le cookie
308
+    if (isset($_COOKIE['spip_session'])) {
309
+        spip_setcookie('spip_session', '', time() - 24 * 3600, httponly: true);
310
+        unset($_COOKIE['spip_session']);
311
+    }
312 312
 }
313 313
 
314 314
 /**
@@ -320,20 +320,20 @@  discard block
 block discarded – undo
320 320
  *   timestamp d'expiration
321 321
  */
322 322
 function set_cookie_session(?string $valeur_cookie = null, int $expires = 0): ?string {
323
-	if ($valeur_cookie !== null) {
324
-		// vérifié par lire_cookie_session()
325
-		$_COOKIE['spip_session'] = $valeur_cookie;
326
-	}
323
+    if ($valeur_cookie !== null) {
324
+        // vérifié par lire_cookie_session()
325
+        $_COOKIE['spip_session'] = $valeur_cookie;
326
+    }
327 327
 
328
-	$valeur_cookie = lire_cookie_session();
328
+    $valeur_cookie = lire_cookie_session();
329 329
 
330
-	if ($valeur_cookie === null) {
331
-		effacer_cookie_session();
332
-	} else {
333
-		spip_setcookie('spip_session', $valeur_cookie, $expires, httponly: true);
334
-	}
330
+    if ($valeur_cookie === null) {
331
+        effacer_cookie_session();
332
+    } else {
333
+        spip_setcookie('spip_session', $valeur_cookie, $expires, httponly: true);
334
+    }
335 335
 
336
-	return $valeur_cookie;
336
+    return $valeur_cookie;
337 337
 }
338 338
 
339 339
 /**
@@ -353,91 +353,91 @@  discard block
 block discarded – undo
353 353
  * @return bool|int|null
354 354
  */
355 355
 function verifier_session($change = false) {
356
-	// si pas de cookie, c'est fichu
357
-	if (!$cookie = lire_cookie_session()) {
358
-		return false;
359
-	}
360
-
361
-	$fichier_session = '';
362
-
363
-	// est-ce une session anonyme ?
364
-	if (!intval($cookie)) {
365
-		spip_php_session_start();
366
-		if (!isset($_SESSION[$cookie]) || !is_array($_SESSION[$cookie])) {
367
-			return false;
368
-		}
369
-		$GLOBALS['visiteur_session'] = $_SESSION[$cookie];
370
-	} else {
371
-		// Tester avec alea courant
372
-		$fichier_session = chemin_fichier_session('alea_ephemere', $cookie, true);
373
-		if ($fichier_session && @file_exists($fichier_session)) {
374
-			include($fichier_session);
375
-		} else {
376
-			// Sinon, tester avec alea precedent
377
-			$fichier_session = chemin_fichier_session('alea_ephemere_ancien', $cookie, true);
378
-			if (!$fichier_session || !@file_exists($fichier_session)) {
379
-				return false;
380
-			}
381
-
382
-			// Renouveler la session avec l'alea courant
383
-			include($fichier_session);
384
-			spip_log('renouvelle session ' . $GLOBALS['visiteur_session']['id_auteur'], 'session');
385
-			spip_unlink($fichier_session);
386
-			ajouter_session($GLOBALS['visiteur_session']);
387
-		}
388
-	}
389
-
390
-	// Compatibilite ascendante : auteur_session est visiteur_session si
391
-	// c'est un auteur SPIP authentifie (tandis qu'un visiteur_session peut
392
-	// n'etre qu'identifie, sans aucune authentification).
393
-
394
-	if (isset($GLOBALS['visiteur_session']['id_auteur']) && $GLOBALS['visiteur_session']['id_auteur']) {
395
-		$GLOBALS['auteur_session'] = &$GLOBALS['visiteur_session'];
396
-	}
397
-
398
-
399
-	// Si l'adresse IP change, inc/presentation mettra une balise image
400
-	// avec un URL de rappel demandant a changer le nom de la session.
401
-	// Seul celui qui a l'IP d'origine est rejoue
402
-	// ainsi un eventuel voleur de cookie ne pourrait pas deconnecter
403
-	// sa victime, mais se ferait deconnecter par elle.
404
-	if (hash_env() != $GLOBALS['visiteur_session']['hash_env']) {
405
-		if (!$GLOBALS['visiteur_session']['ip_change']) {
406
-			define('_SESSION_REJOUER', true);
407
-			$GLOBALS['visiteur_session']['ip_change'] = true;
408
-			ajouter_session($GLOBALS['visiteur_session']);
409
-		} else {
410
-			if ($change) {
411
-				spip_log('session non rejouee, vol de cookie ?', 'session');
412
-			}
413
-		}
414
-	} else {
415
-		if ($change) {
416
-			spip_log("rejoue session $fichier_session $cookie", 'session');
417
-			if ($fichier_session) {
418
-				spip_unlink($fichier_session);
419
-			}
420
-			$GLOBALS['visiteur_session']['ip_change'] = false;
421
-			unset($_COOKIE['spip_session']);
422
-			ajouter_session($GLOBALS['visiteur_session']);
423
-		}
424
-	}
425
-
426
-	// Si la session a ete initiee il y a trop longtemps, elle est annulee
427
-	if (
428
-		isset($GLOBALS['visiteur_session'])
429
-		&& defined('_AGE_SESSION_MAX')
430
-		&& _AGE_SESSION_MAX > 0
431
-		&& time() - @$GLOBALS['visiteur_session']['date_session'] > _AGE_SESSION_MAX
432
-	) {
433
-		unset($GLOBALS['visiteur_session']);
434
-
435
-		return false;
436
-	}
437
-
438
-	return is_numeric($GLOBALS['visiteur_session']['id_auteur'])
439
-		? $GLOBALS['visiteur_session']['id_auteur']
440
-		: null;
356
+    // si pas de cookie, c'est fichu
357
+    if (!$cookie = lire_cookie_session()) {
358
+        return false;
359
+    }
360
+
361
+    $fichier_session = '';
362
+
363
+    // est-ce une session anonyme ?
364
+    if (!intval($cookie)) {
365
+        spip_php_session_start();
366
+        if (!isset($_SESSION[$cookie]) || !is_array($_SESSION[$cookie])) {
367
+            return false;
368
+        }
369
+        $GLOBALS['visiteur_session'] = $_SESSION[$cookie];
370
+    } else {
371
+        // Tester avec alea courant
372
+        $fichier_session = chemin_fichier_session('alea_ephemere', $cookie, true);
373
+        if ($fichier_session && @file_exists($fichier_session)) {
374
+            include($fichier_session);
375
+        } else {
376
+            // Sinon, tester avec alea precedent
377
+            $fichier_session = chemin_fichier_session('alea_ephemere_ancien', $cookie, true);
378
+            if (!$fichier_session || !@file_exists($fichier_session)) {
379
+                return false;
380
+            }
381
+
382
+            // Renouveler la session avec l'alea courant
383
+            include($fichier_session);
384
+            spip_log('renouvelle session ' . $GLOBALS['visiteur_session']['id_auteur'], 'session');
385
+            spip_unlink($fichier_session);
386
+            ajouter_session($GLOBALS['visiteur_session']);
387
+        }
388
+    }
389
+
390
+    // Compatibilite ascendante : auteur_session est visiteur_session si
391
+    // c'est un auteur SPIP authentifie (tandis qu'un visiteur_session peut
392
+    // n'etre qu'identifie, sans aucune authentification).
393
+
394
+    if (isset($GLOBALS['visiteur_session']['id_auteur']) && $GLOBALS['visiteur_session']['id_auteur']) {
395
+        $GLOBALS['auteur_session'] = &$GLOBALS['visiteur_session'];
396
+    }
397
+
398
+
399
+    // Si l'adresse IP change, inc/presentation mettra une balise image
400
+    // avec un URL de rappel demandant a changer le nom de la session.
401
+    // Seul celui qui a l'IP d'origine est rejoue
402
+    // ainsi un eventuel voleur de cookie ne pourrait pas deconnecter
403
+    // sa victime, mais se ferait deconnecter par elle.
404
+    if (hash_env() != $GLOBALS['visiteur_session']['hash_env']) {
405
+        if (!$GLOBALS['visiteur_session']['ip_change']) {
406
+            define('_SESSION_REJOUER', true);
407
+            $GLOBALS['visiteur_session']['ip_change'] = true;
408
+            ajouter_session($GLOBALS['visiteur_session']);
409
+        } else {
410
+            if ($change) {
411
+                spip_log('session non rejouee, vol de cookie ?', 'session');
412
+            }
413
+        }
414
+    } else {
415
+        if ($change) {
416
+            spip_log("rejoue session $fichier_session $cookie", 'session');
417
+            if ($fichier_session) {
418
+                spip_unlink($fichier_session);
419
+            }
420
+            $GLOBALS['visiteur_session']['ip_change'] = false;
421
+            unset($_COOKIE['spip_session']);
422
+            ajouter_session($GLOBALS['visiteur_session']);
423
+        }
424
+    }
425
+
426
+    // Si la session a ete initiee il y a trop longtemps, elle est annulee
427
+    if (
428
+        isset($GLOBALS['visiteur_session'])
429
+        && defined('_AGE_SESSION_MAX')
430
+        && _AGE_SESSION_MAX > 0
431
+        && time() - @$GLOBALS['visiteur_session']['date_session'] > _AGE_SESSION_MAX
432
+    ) {
433
+        unset($GLOBALS['visiteur_session']);
434
+
435
+        return false;
436
+    }
437
+
438
+    return is_numeric($GLOBALS['visiteur_session']['id_auteur'])
439
+        ? $GLOBALS['visiteur_session']['id_auteur']
440
+        : null;
441 441
 }
442 442
 
443 443
 /**
@@ -452,7 +452,7 @@  discard block
 block discarded – undo
452 452
  *     Valeur, si trouvée, `null` sinon.
453 453
  */
454 454
 function session_get($nom) {
455
-	return $GLOBALS['visiteur_session'][$nom] ?? null;
455
+    return $GLOBALS['visiteur_session'][$nom] ?? null;
456 456
 }
457 457
 
458 458
 
@@ -468,32 +468,32 @@  discard block
 block discarded – undo
468 468
  * @return void|array
469 469
  */
470 470
 function session_set($nom, $val = null) {
471
-	static $remove = [];
472
-	static $actualiser_sessions = false;
473
-	if ($nom === false) {
474
-		return $remove;
475
-	}
476
-	if (is_null($val)) {
477
-		// rien a faire
478
-		if (!isset($GLOBALS['visiteur_session'][$nom])) {
479
-			return;
480
-		}
481
-		unset($GLOBALS['visiteur_session'][$nom]);
482
-		$remove[] = $nom;
483
-	} else {
484
-		// On ajoute la valeur dans la globale
485
-		$GLOBALS['visiteur_session'][$nom] = $val;
486
-		if ($remove) {
487
-			$remove = array_diff($remove, [$nom]);
488
-		}
489
-	}
490
-	if (!$actualiser_sessions) {
491
-		// il faut creer la session si on en a pas, la premiere fois
492
-		ajouter_session($GLOBALS['visiteur_session']);
493
-		// in register la fonction qui mettra a jour toutes les sessions en fin de hit
494
-		register_shutdown_function('terminer_actualiser_sessions');
495
-		$actualiser_sessions = true;
496
-	}
471
+    static $remove = [];
472
+    static $actualiser_sessions = false;
473
+    if ($nom === false) {
474
+        return $remove;
475
+    }
476
+    if (is_null($val)) {
477
+        // rien a faire
478
+        if (!isset($GLOBALS['visiteur_session'][$nom])) {
479
+            return;
480
+        }
481
+        unset($GLOBALS['visiteur_session'][$nom]);
482
+        $remove[] = $nom;
483
+    } else {
484
+        // On ajoute la valeur dans la globale
485
+        $GLOBALS['visiteur_session'][$nom] = $val;
486
+        if ($remove) {
487
+            $remove = array_diff($remove, [$nom]);
488
+        }
489
+    }
490
+    if (!$actualiser_sessions) {
491
+        // il faut creer la session si on en a pas, la premiere fois
492
+        ajouter_session($GLOBALS['visiteur_session']);
493
+        // in register la fonction qui mettra a jour toutes les sessions en fin de hit
494
+        register_shutdown_function('terminer_actualiser_sessions');
495
+        $actualiser_sessions = true;
496
+    }
497 497
 }
498 498
 
499 499
 /**
@@ -502,12 +502,12 @@  discard block
 block discarded – undo
502 502
  * @uses actualiser_sessions()
503 503
  */
504 504
 function terminer_actualiser_sessions() {
505
-	// se remettre dans le dossier de travail au cas ou Apache a change
506
-	chdir(_ROOT_CWD);
507
-	// recuperer les variables a effacer
508
-	$remove = session_set(false);
509
-	// mettre a jour toutes les sessions
510
-	actualiser_sessions($GLOBALS['visiteur_session'], $remove);
505
+    // se remettre dans le dossier de travail au cas ou Apache a change
506
+    chdir(_ROOT_CWD);
507
+    // recuperer les variables a effacer
508
+    $remove = session_set(false);
509
+    // mettre a jour toutes les sessions
510
+    actualiser_sessions($GLOBALS['visiteur_session'], $remove);
511 511
 }
512 512
 
513 513
 
@@ -532,83 +532,83 @@  discard block
 block discarded – undo
532 532
  */
533 533
 function actualiser_sessions($auteur, $supprimer_cles = []) {
534 534
 
535
-	$id_auteur = isset($auteur['id_auteur']) ? intval($auteur['id_auteur']) : 0;
536
-	$id_auteur_courant = isset($GLOBALS['visiteur_session']['id_auteur']) ? intval($GLOBALS['visiteur_session']['id_auteur']) : 0;
537
-
538
-	// si l'auteur est celui de la session courante, verifier/creer la session si besoin
539
-	$fichier_session_courante = '';
540
-	if ($id_auteur == $id_auteur_courant) {
541
-		$auteur = array_merge($GLOBALS['visiteur_session'], $auteur);
542
-		ajouter_session($auteur);
543
-		if ($id_auteur && ($cookie = lire_cookie_session())) {
544
-			$fichier_session_courante = chemin_fichier_session('alea_ephemere', $cookie);
545
-		}
546
-	}
547
-
548
-	// si session anonyme on ne fait rien d'autre ici : les sessions anonymes sont non partagees
549
-	if (!$id_auteur) {
550
-		return;
551
-	}
552
-
553
-	// les préférences sont désérialisées, toujours.
554
-	// [fixme] Le champ 'prefs' sert aussi à l’inscription
555
-	if (isset($auteur['prefs']) && is_string($auteur['prefs'])) {
556
-		$auteur['prefs'] = @unserialize($auteur['prefs']);
557
-		if (!is_array($auteur['prefs'])) {
558
-			$auteur['prefs'] = [];
559
-		}
560
-	}
561
-
562
-	// memoriser l'auteur courant (celui qui modifie la fiche)
563
-	$sauve = $GLOBALS['visiteur_session'];
564
-
565
-	// .. mettre a jour les sessions de l'auteur cible
566
-	// attention au $ final pour ne pas risquer d'embarquer un .php.jeton temporaire
567
-	// cree par une ecriture concurente d'une session (fichier atomique temporaire)
568
-	$sessions = lister_sessions_auteur($id_auteur);
569
-
570
-	// 1ere passe : lire et fusionner les sessions
571
-	foreach ($sessions as $session) {
572
-		$GLOBALS['visiteur_session'] = [];
573
-		// a pu etre supprime entre le preg initial et le moment ou l'on arrive la (concurrence)
574
-		if (
575
-			$session !== $fichier_session_courante
576
-			&& @file_exists($session)
577
-		) {
578
-			include $session; # $GLOBALS['visiteur_session'] est alors l'auteur cible
579
-
580
-			$auteur = array_merge($GLOBALS['visiteur_session'], $auteur);
581
-		}
582
-	}
583
-
584
-	// supprimer les eventuelles cles dont on ne veut plus
585
-	foreach ($supprimer_cles as $cle) {
586
-		unset($auteur[$cle]);
587
-	}
588
-
589
-	$auteur_session = preparer_ecriture_session($auteur);
590
-
591
-	// seconde passe : ecrire les sessions qui ne sont pas a jour
592
-	foreach ($sessions as $session) {
593
-		$GLOBALS['visiteur_session'] = [];
594
-		// a pu etre supprime entre le preg initial et le moment ou l'on arrive la (concurrence)
595
-		if (@file_exists($session)) {
596
-			include $session; # $GLOBALS['visiteur_session'] est alors l'auteur cible
597
-
598
-			// est-ce que cette session est a mettre a jour ?
599
-			if ($auteur_session != $GLOBALS['visiteur_session']) {
600
-				ecrire_fichier_session($session, $auteur);
601
-			}
602
-		}
603
-	}
604
-
605
-	if ($id_auteur == $id_auteur_courant) {
606
-		$GLOBALS['visiteur_session'] = $auteur;
607
-		$GLOBALS['auteur_session'] = &$GLOBALS['visiteur_session'];
608
-	} else {
609
-		// restaurer l'auteur courant
610
-		$GLOBALS['visiteur_session'] = $sauve;
611
-	}
535
+    $id_auteur = isset($auteur['id_auteur']) ? intval($auteur['id_auteur']) : 0;
536
+    $id_auteur_courant = isset($GLOBALS['visiteur_session']['id_auteur']) ? intval($GLOBALS['visiteur_session']['id_auteur']) : 0;
537
+
538
+    // si l'auteur est celui de la session courante, verifier/creer la session si besoin
539
+    $fichier_session_courante = '';
540
+    if ($id_auteur == $id_auteur_courant) {
541
+        $auteur = array_merge($GLOBALS['visiteur_session'], $auteur);
542
+        ajouter_session($auteur);
543
+        if ($id_auteur && ($cookie = lire_cookie_session())) {
544
+            $fichier_session_courante = chemin_fichier_session('alea_ephemere', $cookie);
545
+        }
546
+    }
547
+
548
+    // si session anonyme on ne fait rien d'autre ici : les sessions anonymes sont non partagees
549
+    if (!$id_auteur) {
550
+        return;
551
+    }
552
+
553
+    // les préférences sont désérialisées, toujours.
554
+    // [fixme] Le champ 'prefs' sert aussi à l’inscription
555
+    if (isset($auteur['prefs']) && is_string($auteur['prefs'])) {
556
+        $auteur['prefs'] = @unserialize($auteur['prefs']);
557
+        if (!is_array($auteur['prefs'])) {
558
+            $auteur['prefs'] = [];
559
+        }
560
+    }
561
+
562
+    // memoriser l'auteur courant (celui qui modifie la fiche)
563
+    $sauve = $GLOBALS['visiteur_session'];
564
+
565
+    // .. mettre a jour les sessions de l'auteur cible
566
+    // attention au $ final pour ne pas risquer d'embarquer un .php.jeton temporaire
567
+    // cree par une ecriture concurente d'une session (fichier atomique temporaire)
568
+    $sessions = lister_sessions_auteur($id_auteur);
569
+
570
+    // 1ere passe : lire et fusionner les sessions
571
+    foreach ($sessions as $session) {
572
+        $GLOBALS['visiteur_session'] = [];
573
+        // a pu etre supprime entre le preg initial et le moment ou l'on arrive la (concurrence)
574
+        if (
575
+            $session !== $fichier_session_courante
576
+            && @file_exists($session)
577
+        ) {
578
+            include $session; # $GLOBALS['visiteur_session'] est alors l'auteur cible
579
+
580
+            $auteur = array_merge($GLOBALS['visiteur_session'], $auteur);
581
+        }
582
+    }
583
+
584
+    // supprimer les eventuelles cles dont on ne veut plus
585
+    foreach ($supprimer_cles as $cle) {
586
+        unset($auteur[$cle]);
587
+    }
588
+
589
+    $auteur_session = preparer_ecriture_session($auteur);
590
+
591
+    // seconde passe : ecrire les sessions qui ne sont pas a jour
592
+    foreach ($sessions as $session) {
593
+        $GLOBALS['visiteur_session'] = [];
594
+        // a pu etre supprime entre le preg initial et le moment ou l'on arrive la (concurrence)
595
+        if (@file_exists($session)) {
596
+            include $session; # $GLOBALS['visiteur_session'] est alors l'auteur cible
597
+
598
+            // est-ce que cette session est a mettre a jour ?
599
+            if ($auteur_session != $GLOBALS['visiteur_session']) {
600
+                ecrire_fichier_session($session, $auteur);
601
+            }
602
+        }
603
+    }
604
+
605
+    if ($id_auteur == $id_auteur_courant) {
606
+        $GLOBALS['visiteur_session'] = $auteur;
607
+        $GLOBALS['auteur_session'] = &$GLOBALS['visiteur_session'];
608
+    } else {
609
+        // restaurer l'auteur courant
610
+        $GLOBALS['visiteur_session'] = $sauve;
611
+    }
612 612
 }
613 613
 
614 614
 /**
@@ -622,48 +622,48 @@  discard block
 block discarded – undo
622 622
  */
623 623
 function lister_sessions_auteur($id_auteur, $nb_max = null) {
624 624
 
625
-	if (is_null($nb_max)) {
626
-		if (!defined('_NB_SESSIONS_MAX')) {
627
-			define('_NB_SESSIONS_MAX', 100);
628
-		}
629
-		$nb_max = _NB_SESSIONS_MAX;
630
-	}
631
-
632
-	// liste des sessions
633
-	$sessions = preg_files(_DIR_SESSIONS, '/' . $id_auteur . '_.*\.php$');
634
-
635
-	// si on en a plus que la limite, supprimer les plus vieilles
636
-	// si ce ne sont pas des sessions anonymes car elles sont alors chacune differentes
637
-	if (
638
-		$id_auteur
639
-		&& count($sessions) > $nb_max
640
-	) {
641
-		// limiter le nombre de sessions ouvertes par un auteur
642
-		// filemtime sur les sessions
643
-		$sessions = array_flip($sessions);
644
-
645
-		// 1ere passe : lire les filemtime
646
-		foreach ($sessions as $session => $z) {
647
-			if (
648
-				$d = @filemtime($session)
649
-			) {
650
-				$sessions[$session] = $d;
651
-			} else {
652
-				$sessions[$session] = 0;
653
-			}
654
-		}
655
-
656
-		// les plus anciennes en premier
657
-		asort($sessions);
658
-
659
-		$sessions = array_keys($sessions);
660
-		while (count($sessions) > $nb_max) {
661
-			$session = array_shift($sessions);
662
-			@unlink($session);
663
-		}
664
-	}
665
-
666
-	return $sessions;
625
+    if (is_null($nb_max)) {
626
+        if (!defined('_NB_SESSIONS_MAX')) {
627
+            define('_NB_SESSIONS_MAX', 100);
628
+        }
629
+        $nb_max = _NB_SESSIONS_MAX;
630
+    }
631
+
632
+    // liste des sessions
633
+    $sessions = preg_files(_DIR_SESSIONS, '/' . $id_auteur . '_.*\.php$');
634
+
635
+    // si on en a plus que la limite, supprimer les plus vieilles
636
+    // si ce ne sont pas des sessions anonymes car elles sont alors chacune differentes
637
+    if (
638
+        $id_auteur
639
+        && count($sessions) > $nb_max
640
+    ) {
641
+        // limiter le nombre de sessions ouvertes par un auteur
642
+        // filemtime sur les sessions
643
+        $sessions = array_flip($sessions);
644
+
645
+        // 1ere passe : lire les filemtime
646
+        foreach ($sessions as $session => $z) {
647
+            if (
648
+                $d = @filemtime($session)
649
+            ) {
650
+                $sessions[$session] = $d;
651
+            } else {
652
+                $sessions[$session] = 0;
653
+            }
654
+        }
655
+
656
+        // les plus anciennes en premier
657
+        asort($sessions);
658
+
659
+        $sessions = array_keys($sessions);
660
+        while (count($sessions) > $nb_max) {
661
+            $session = array_shift($sessions);
662
+            @unlink($session);
663
+        }
664
+    }
665
+
666
+    return $sessions;
667 667
 }
668 668
 
669 669
 
@@ -678,22 +678,22 @@  discard block
 block discarded – undo
678 678
  */
679 679
 function preparer_ecriture_session(array $auteur): array {
680 680
 
681
-	$row = $auteur;
681
+    $row = $auteur;
682 682
 
683
-	// ne pas enregistrer ces elements de securite dans le fichier de session
684
-	include_spip('inc/auth');
685
-	$auteur = auth_desensibiliser_session($auteur);
683
+    // ne pas enregistrer ces elements de securite dans le fichier de session
684
+    include_spip('inc/auth');
685
+    $auteur = auth_desensibiliser_session($auteur);
686 686
 
687
-	$auteur = pipeline('preparer_fichier_session', ['args' => ['row' => $row], 'data' => $auteur]);
687
+    $auteur = pipeline('preparer_fichier_session', ['args' => ['row' => $row], 'data' => $auteur]);
688 688
 
689
-	// ne pas enregistrer les valeurs vraiment nulle dans le fichier
690
-	foreach ($auteur as $variable => $valeur) {
691
-		if ($valeur === null) {
692
-			unset($auteur[$variable]);
693
-		}
694
-	}
689
+    // ne pas enregistrer les valeurs vraiment nulle dans le fichier
690
+    foreach ($auteur as $variable => $valeur) {
691
+        if ($valeur === null) {
692
+            unset($auteur[$variable]);
693
+        }
694
+    }
695 695
 
696
-	return $auteur;
696
+    return $auteur;
697 697
 }
698 698
 
699 699
 /**
@@ -705,39 +705,39 @@  discard block
 block discarded – undo
705 705
  */
706 706
 function ecrire_fichier_session($fichier, $auteur) {
707 707
 
708
-	$auteur = preparer_ecriture_session($auteur);
708
+    $auteur = preparer_ecriture_session($auteur);
709 709
 
710
-	// enregistrer les autres donnees du visiteur
711
-	$texte = '<' . "?php\n";
712
-	foreach ($auteur as $var => $val) {
713
-		$texte .= '$GLOBALS[\'visiteur_session\'][' . var_export($var, true) . '] = '
714
-			. var_export($val, true) . ";\n";
715
-	}
716
-	$texte .= '?' . ">\n";
710
+    // enregistrer les autres donnees du visiteur
711
+    $texte = '<' . "?php\n";
712
+    foreach ($auteur as $var => $val) {
713
+        $texte .= '$GLOBALS[\'visiteur_session\'][' . var_export($var, true) . '] = '
714
+            . var_export($val, true) . ";\n";
715
+    }
716
+    $texte .= '?' . ">\n";
717 717
 
718
-	return ecrire_fichier($fichier, $texte);
718
+    return ecrire_fichier($fichier, $texte);
719 719
 }
720 720
 
721 721
 /**
722 722
  * Calculer le chemin vers le fichier de session
723 723
  */
724 724
 function chemin_fichier_session(string $alea, string $cookie_session, bool $tantpis = false): string {
725
-	include_spip('inc/acces');
726
-	charger_aleas();
727
-
728
-	if (empty($GLOBALS['meta'][$alea])) {
729
-		if (!$tantpis) {
730
-			spip_log("fichier session ($tantpis): $alea indisponible", 'session');
731
-			include_spip('inc/minipres');
732
-			echo minipres();
733
-		}
734
-
735
-		return ''; // echec mais $tanpis
736
-	}
737
-
738
-	$repertoire = sous_repertoire(_DIR_SESSIONS, '', false, $tantpis);
739
-	$id_auteur = intval($cookie_session);
740
-	return $repertoire . $id_auteur . '_' . md5($cookie_session . ' ' . $GLOBALS['meta'][$alea]) . '.php';
725
+    include_spip('inc/acces');
726
+    charger_aleas();
727
+
728
+    if (empty($GLOBALS['meta'][$alea])) {
729
+        if (!$tantpis) {
730
+            spip_log("fichier session ($tantpis): $alea indisponible", 'session');
731
+            include_spip('inc/minipres');
732
+            echo minipres();
733
+        }
734
+
735
+        return ''; // echec mais $tanpis
736
+    }
737
+
738
+    $repertoire = sous_repertoire(_DIR_SESSIONS, '', false, $tantpis);
739
+    $id_auteur = intval($cookie_session);
740
+    return $repertoire . $id_auteur . '_' . md5($cookie_session . ' ' . $GLOBALS['meta'][$alea]) . '.php';
741 741
 }
742 742
 
743 743
 /**
@@ -748,7 +748,7 @@  discard block
 block discarded – undo
748 748
  * @param bool $tantpis
749 749
  */
750 750
 function fichier_session($alea, $tantpis = false): string {
751
-	return chemin_fichier_session((string) $alea, lire_cookie_session(), (bool) $tantpis);
751
+    return chemin_fichier_session((string) $alea, lire_cookie_session(), (bool) $tantpis);
752 752
 }
753 753
 
754 754
 
@@ -765,7 +765,7 @@  discard block
 block discarded – undo
765 765
  * @return string
766 766
  */
767 767
 function rejouer_session() {
768
-	return '<img src="' . generer_url_action('cookie', 'change_session=oui', true) . '" width="0" height="0" alt="" />';
768
+    return '<img src="' . generer_url_action('cookie', 'change_session=oui', true) . '" width="0" height="0" alt="" />';
769 769
 }
770 770
 
771 771
 
@@ -775,12 +775,12 @@  discard block
 block discarded – undo
775 775
  * @return string
776 776
  */
777 777
 function hash_env() {
778
-	static $res = '';
779
-	if ($res) {
780
-		return $res;
781
-	}
778
+    static $res = '';
779
+    if ($res) {
780
+        return $res;
781
+    }
782 782
 
783
-	return $res = md5($GLOBALS['ip'] . ($_SERVER['HTTP_USER_AGENT'] ?? ''));
783
+    return $res = md5($GLOBALS['ip'] . ($_SERVER['HTTP_USER_AGENT'] ?? ''));
784 784
 }
785 785
 
786 786
 
@@ -792,11 +792,11 @@  discard block
 block discarded – undo
792 792
  * @return bool True si une session PHP est ouverte.
793 793
  **/
794 794
 function spip_php_session_start() {
795
-	if (!is_php_session_started()) {
796
-		return session_start();
797
-	}
795
+    if (!is_php_session_started()) {
796
+        return session_start();
797
+    }
798 798
 
799
-	return true;
799
+    return true;
800 800
 }
801 801
 
802 802
 /**
@@ -806,9 +806,9 @@  discard block
 block discarded – undo
806 806
  * @return bool true si une session PHP est active
807 807
  **/
808 808
 function is_php_session_started() {
809
-	if (php_sapi_name() !== 'cli') {
810
-		return session_status() === PHP_SESSION_ACTIVE ? true : false;
811
-	}
809
+    if (php_sapi_name() !== 'cli') {
810
+        return session_status() === PHP_SESSION_ACTIVE ? true : false;
811
+    }
812 812
 
813
-	return false;
813
+    return false;
814 814
 }
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -81,12 +81,12 @@  discard block
 block discarded – undo
81 81
 	spip_log("supprimer sessions auteur $id_auteur", 'session');
82 82
 	if ($toutes || $id_auteur !== $GLOBALS['visiteur_session']['id_auteur']) {
83 83
 		if ($dir = opendir(_DIR_SESSIONS)) {
84
-			$t = $_SERVER['REQUEST_TIME']  - (4 * _RENOUVELLE_ALEA); // 48h par defaut
85
-			$t_short = $_SERVER['REQUEST_TIME']  - max(_RENOUVELLE_ALEA / 4, 3 * 3600); // 3h par defaut
84
+			$t = $_SERVER['REQUEST_TIME'] - (4 * _RENOUVELLE_ALEA); // 48h par defaut
85
+			$t_short = $_SERVER['REQUEST_TIME'] - max(_RENOUVELLE_ALEA / 4, 3 * 3600); // 3h par defaut
86 86
 			while (($f = readdir($dir)) !== false) {
87 87
 				$nb_files++;
88 88
 				if (preg_match(',^[^\d-]*(-?\d+)_\w{32}\.php[3]?$,', $f, $regs)) {
89
-					$f = _DIR_SESSIONS . $f;
89
+					$f = _DIR_SESSIONS.$f;
90 90
 					if ($actives && $regs[1] == $id_auteur || $t > filemtime($f)) {
91 91
 						spip_unlink($f);
92 92
 					}
@@ -173,7 +173,7 @@  discard block
 block discarded – undo
173 173
 		(!$cookie = lire_cookie_session())
174 174
 		|| intval($cookie) !== $id_auteur
175 175
 	) {
176
-		$cookie = $id_auteur . '_' . md5(uniqid(random_int(0, mt_getrandmax()), true));
176
+		$cookie = $id_auteur.'_'.md5(uniqid(random_int(0, mt_getrandmax()), true));
177 177
 	}
178 178
 
179 179
 	// Maintenant on sait qu'on a des choses à écrire
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
 	} else {
207 207
 		$fichier_session = chemin_fichier_session('alea_ephemere', $cookie);
208 208
 		if (!ecrire_fichier_session($fichier_session, $auteur)) {
209
-			spip_log('Echec ecriture fichier session ' . $fichier_session, 'session' . _LOG_HS);
209
+			spip_log('Echec ecriture fichier session '.$fichier_session, 'session'._LOG_HS);
210 210
 			include_spip('inc/minipres');
211 211
 			echo minipres();
212 212
 			exit;
@@ -229,9 +229,9 @@  discard block
 block discarded – undo
229 229
 	if (autoriser('ecrire', '', '', $auteur) && _DUREE_COOKIE_ADMIN) {
230 230
 		spip_setcookie(
231 231
 			'spip_admin',
232
-			'@' . ($auteur['email'] ?: $auteur['login']),
232
+			'@'.($auteur['email'] ?: $auteur['login']),
233 233
 			time() + max(_DUREE_COOKIE_ADMIN, $duree),
234
-			httponly: true
234
+			httponly : true
235 235
 		);
236 236
 	} else {
237 237
 		// sinon le supprimer ...
@@ -269,7 +269,7 @@  discard block
 block discarded – undo
269 269
 			$coef = 20;
270 270
 		}
271 271
 	}
272
-	return (int)(_RENOUVELLE_ALEA * $coef);
272
+	return (int) (_RENOUVELLE_ALEA * $coef);
273 273
 }
274 274
 
275 275
 /**
@@ -381,7 +381,7 @@  discard block
 block discarded – undo
381 381
 
382 382
 			// Renouveler la session avec l'alea courant
383 383
 			include($fichier_session);
384
-			spip_log('renouvelle session ' . $GLOBALS['visiteur_session']['id_auteur'], 'session');
384
+			spip_log('renouvelle session '.$GLOBALS['visiteur_session']['id_auteur'], 'session');
385 385
 			spip_unlink($fichier_session);
386 386
 			ajouter_session($GLOBALS['visiteur_session']);
387 387
 		}
@@ -630,7 +630,7 @@  discard block
 block discarded – undo
630 630
 	}
631 631
 
632 632
 	// liste des sessions
633
-	$sessions = preg_files(_DIR_SESSIONS, '/' . $id_auteur . '_.*\.php$');
633
+	$sessions = preg_files(_DIR_SESSIONS, '/'.$id_auteur.'_.*\.php$');
634 634
 
635 635
 	// si on en a plus que la limite, supprimer les plus vieilles
636 636
 	// si ce ne sont pas des sessions anonymes car elles sont alors chacune differentes
@@ -708,12 +708,12 @@  discard block
 block discarded – undo
708 708
 	$auteur = preparer_ecriture_session($auteur);
709 709
 
710 710
 	// enregistrer les autres donnees du visiteur
711
-	$texte = '<' . "?php\n";
711
+	$texte = '<'."?php\n";
712 712
 	foreach ($auteur as $var => $val) {
713
-		$texte .= '$GLOBALS[\'visiteur_session\'][' . var_export($var, true) . '] = '
714
-			. var_export($val, true) . ";\n";
713
+		$texte .= '$GLOBALS[\'visiteur_session\']['.var_export($var, true).'] = '
714
+			. var_export($val, true).";\n";
715 715
 	}
716
-	$texte .= '?' . ">\n";
716
+	$texte .= '?'.">\n";
717 717
 
718 718
 	return ecrire_fichier($fichier, $texte);
719 719
 }
@@ -737,7 +737,7 @@  discard block
 block discarded – undo
737 737
 
738 738
 	$repertoire = sous_repertoire(_DIR_SESSIONS, '', false, $tantpis);
739 739
 	$id_auteur = intval($cookie_session);
740
-	return $repertoire . $id_auteur . '_' . md5($cookie_session . ' ' . $GLOBALS['meta'][$alea]) . '.php';
740
+	return $repertoire.$id_auteur.'_'.md5($cookie_session.' '.$GLOBALS['meta'][$alea]).'.php';
741 741
 }
742 742
 
743 743
 /**
@@ -765,7 +765,7 @@  discard block
 block discarded – undo
765 765
  * @return string
766 766
  */
767 767
 function rejouer_session() {
768
-	return '<img src="' . generer_url_action('cookie', 'change_session=oui', true) . '" width="0" height="0" alt="" />';
768
+	return '<img src="'.generer_url_action('cookie', 'change_session=oui', true).'" width="0" height="0" alt="" />';
769 769
 }
770 770
 
771 771
 
@@ -780,7 +780,7 @@  discard block
 block discarded – undo
780 780
 		return $res;
781 781
 	}
782 782
 
783
-	return $res = md5($GLOBALS['ip'] . ($_SERVER['HTTP_USER_AGENT'] ?? ''));
783
+	return $res = md5($GLOBALS['ip'].($_SERVER['HTTP_USER_AGENT'] ?? ''));
784 784
 }
785 785
 
786 786
 
Please login to merge, or discard this patch.
ecrire/inc/filtres_images_lib_mini.php 1 patch
Indentation   +1287 added lines, -1287 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  */
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 include_spip('inc/filtres'); // par precaution
23 23
 include_spip('inc/filtres_images_mini'); // par precaution
@@ -37,21 +37,21 @@  discard block
 block discarded – undo
37 37
  *     Le code de la couleur en hexadécimal.
38 38
  */
39 39
 function _couleur_dec_to_hex($red, $green, $blue) {
40
-	$red = dechex($red);
41
-	$green = dechex($green);
42
-	$blue = dechex($blue);
43
-
44
-	if (strlen($red) == 1) {
45
-		$red = '0' . $red;
46
-	}
47
-	if (strlen($green) == 1) {
48
-		$green = '0' . $green;
49
-	}
50
-	if (strlen($blue) == 1) {
51
-		$blue = '0' . $blue;
52
-	}
53
-
54
-	return "$red$green$blue";
40
+    $red = dechex($red);
41
+    $green = dechex($green);
42
+    $blue = dechex($blue);
43
+
44
+    if (strlen($red) == 1) {
45
+        $red = '0' . $red;
46
+    }
47
+    if (strlen($green) == 1) {
48
+        $green = '0' . $green;
49
+    }
50
+    if (strlen($blue) == 1) {
51
+        $blue = '0' . $blue;
52
+    }
53
+
54
+    return "$red$green$blue";
55 55
 }
56 56
 
57 57
 /**
@@ -63,18 +63,18 @@  discard block
 block discarded – undo
63 63
  *     Un tableau des 3 éléments : rouge, vert, bleu.
64 64
  */
65 65
 function _couleur_hex_to_dec($couleur) {
66
-	$couleur ??= '';
67
-	$couleur = couleur_html_to_hex($couleur);
68
-	$couleur = ltrim($couleur, '#');
69
-	if (strlen($couleur) === 3) {
70
-		$couleur = $couleur[0] . $couleur[0] . $couleur[1] . $couleur[1] . $couleur[2] . $couleur[2];
71
-	}
72
-	$retour = [];
73
-	$retour['red'] = hexdec(substr($couleur, 0, 2));
74
-	$retour['green'] = hexdec(substr($couleur, 2, 2));
75
-	$retour['blue'] = hexdec(substr($couleur, 4, 2));
76
-
77
-	return $retour;
66
+    $couleur ??= '';
67
+    $couleur = couleur_html_to_hex($couleur);
68
+    $couleur = ltrim($couleur, '#');
69
+    if (strlen($couleur) === 3) {
70
+        $couleur = $couleur[0] . $couleur[0] . $couleur[1] . $couleur[1] . $couleur[2] . $couleur[2];
71
+    }
72
+    $retour = [];
73
+    $retour['red'] = hexdec(substr($couleur, 0, 2));
74
+    $retour['green'] = hexdec(substr($couleur, 2, 2));
75
+    $retour['blue'] = hexdec(substr($couleur, 4, 2));
76
+
77
+    return $retour;
78 78
 }
79 79
 
80 80
 
@@ -91,8 +91,8 @@  discard block
 block discarded – undo
91 91
  *     Le code de la couleur en hexadécimal.
92 92
  */
93 93
 function _couleur_hsl_to_hex($hue, $saturation, $lightness) {
94
-	$rgb = _couleur_hsl_to_rgb($hue, $saturation, $lightness);
95
-	return _couleur_dec_to_hex($rgb['r'], $rgb['g'], $rgb['b']);
94
+    $rgb = _couleur_hsl_to_rgb($hue, $saturation, $lightness);
95
+    return _couleur_dec_to_hex($rgb['r'], $rgb['g'], $rgb['b']);
96 96
 }
97 97
 
98 98
 /**
@@ -104,8 +104,8 @@  discard block
 block discarded – undo
104 104
  *     Un tableau des 3 éléments : teinte, saturation, luminosité.
105 105
  */
106 106
 function _couleur_hex_to_hsl($couleur) {
107
-	$rgb = _couleur_hex_to_dec($couleur);
108
-	return _couleur_rgb_to_hsl($rgb['red'], $rgb['green'], $rgb['blue']);
107
+    $rgb = _couleur_hex_to_dec($couleur);
108
+    return _couleur_rgb_to_hsl($rgb['red'], $rgb['green'], $rgb['blue']);
109 109
 }
110 110
 
111 111
 /**
@@ -120,55 +120,55 @@  discard block
 block discarded – undo
120 120
  * @return array
121 121
  */
122 122
 function _couleur_rgb_to_hsl($R, $G, $B) {
123
-	$H = null;
124
-	$var_R = ($R / 255); // Where RGB values = 0 ÷ 255
125
-	$var_G = ($G / 255);
126
-	$var_B = ($B / 255);
127
-
128
-	$var_Min = min($var_R, $var_G, $var_B);   //Min. value of RGB
129
-	$var_Max = max($var_R, $var_G, $var_B);   //Max. value of RGB
130
-	$del_Max = $var_Max - $var_Min;           //Delta RGB value
131
-
132
-	$L = ($var_Max + $var_Min) / 2;
133
-
134
-	if ($del_Max == 0) {
135
-		//This is a gray, no chroma...
136
-		$H = 0; //HSL results = 0 ÷ 1
137
-		$S = 0;
138
-	} else {
139
-		// Chromatic data...
140
-		$S = $L < 0.5 ? $del_Max / ($var_Max + $var_Min) : $del_Max / (2 - $var_Max - $var_Min);
141
-
142
-		$del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max;
143
-		$del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max;
144
-		$del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max;
145
-
146
-		if ($var_R === $var_Max) {
147
-			$H = $del_B - $del_G;
148
-		} else {
149
-			if ($var_G === $var_Max) {
150
-				$H = (1 / 3) + $del_R - $del_B;
151
-			} else {
152
-				if ($var_B === $var_Max) {
153
-					$H = (2 / 3) + $del_G - $del_R;
154
-				}
155
-			}
156
-		}
157
-
158
-		if ($H < 0) {
159
-			$H += 1;
160
-		}
161
-		if ($H > 1) {
162
-			$H -= 1;
163
-		}
164
-	}
165
-
166
-	$ret = [];
167
-	$ret['h'] = $H;
168
-	$ret['s'] = $S;
169
-	$ret['l'] = $L;
170
-
171
-	return $ret;
123
+    $H = null;
124
+    $var_R = ($R / 255); // Where RGB values = 0 ÷ 255
125
+    $var_G = ($G / 255);
126
+    $var_B = ($B / 255);
127
+
128
+    $var_Min = min($var_R, $var_G, $var_B);   //Min. value of RGB
129
+    $var_Max = max($var_R, $var_G, $var_B);   //Max. value of RGB
130
+    $del_Max = $var_Max - $var_Min;           //Delta RGB value
131
+
132
+    $L = ($var_Max + $var_Min) / 2;
133
+
134
+    if ($del_Max == 0) {
135
+        //This is a gray, no chroma...
136
+        $H = 0; //HSL results = 0 ÷ 1
137
+        $S = 0;
138
+    } else {
139
+        // Chromatic data...
140
+        $S = $L < 0.5 ? $del_Max / ($var_Max + $var_Min) : $del_Max / (2 - $var_Max - $var_Min);
141
+
142
+        $del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max;
143
+        $del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max;
144
+        $del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max;
145
+
146
+        if ($var_R === $var_Max) {
147
+            $H = $del_B - $del_G;
148
+        } else {
149
+            if ($var_G === $var_Max) {
150
+                $H = (1 / 3) + $del_R - $del_B;
151
+            } else {
152
+                if ($var_B === $var_Max) {
153
+                    $H = (2 / 3) + $del_G - $del_R;
154
+                }
155
+            }
156
+        }
157
+
158
+        if ($H < 0) {
159
+            $H += 1;
160
+        }
161
+        if ($H > 1) {
162
+            $H -= 1;
163
+        }
164
+    }
165
+
166
+    $ret = [];
167
+    $ret['h'] = $H;
168
+    $ret['s'] = $S;
169
+    $ret['l'] = $L;
170
+
171
+    return $ret;
172 172
 }
173 173
 
174 174
 
@@ -184,48 +184,48 @@  discard block
 block discarded – undo
184 184
  * @return array
185 185
  */
186 186
 function _couleur_hsl_to_rgb($H, $S, $L) {
187
-	// helper
188
-	$hue_2_rgb = function ($v1, $v2, $vH) {
189
-		if ($vH < 0) {
190
-			$vH += 1;
191
-		}
192
-		if ($vH > 1) {
193
-			$vH -= 1;
194
-		}
195
-		if ((6 * $vH) < 1) {
196
-			return ($v1 + ($v2 - $v1) * 6 * $vH);
197
-		}
198
-		if ((2 * $vH) < 1) {
199
-			return ($v2);
200
-		}
201
-		if ((3 * $vH) < 2) {
202
-			return ($v1 + ($v2 - $v1) * ((2 / 3) - $vH) * 6);
203
-		}
204
-
205
-		return ($v1);
206
-	};
207
-
208
-	if ($S == 0) {
209
-		// HSV values = 0 -> 1
210
-		$R = $L * 255;
211
-		$G = $L * 255;
212
-		$B = $L * 255;
213
-	} else {
214
-		$var_2 = $L < 0.5 ? $L * (1 + $S) : ($L + $S) - ($S * $L);
215
-
216
-		$var_1 = 2 * $L - $var_2;
217
-
218
-		$R = 255 * $hue_2_rgb($var_1, $var_2, $H + (1 / 3));
219
-		$G = 255 * $hue_2_rgb($var_1, $var_2, $H);
220
-		$B = 255 * $hue_2_rgb($var_1, $var_2, $H - (1 / 3));
221
-	}
222
-
223
-	$ret = [];
224
-	$ret['r'] = floor($R);
225
-	$ret['g'] = floor($G);
226
-	$ret['b'] = floor($B);
227
-
228
-	return $ret;
187
+    // helper
188
+    $hue_2_rgb = function ($v1, $v2, $vH) {
189
+        if ($vH < 0) {
190
+            $vH += 1;
191
+        }
192
+        if ($vH > 1) {
193
+            $vH -= 1;
194
+        }
195
+        if ((6 * $vH) < 1) {
196
+            return ($v1 + ($v2 - $v1) * 6 * $vH);
197
+        }
198
+        if ((2 * $vH) < 1) {
199
+            return ($v2);
200
+        }
201
+        if ((3 * $vH) < 2) {
202
+            return ($v1 + ($v2 - $v1) * ((2 / 3) - $vH) * 6);
203
+        }
204
+
205
+        return ($v1);
206
+    };
207
+
208
+    if ($S == 0) {
209
+        // HSV values = 0 -> 1
210
+        $R = $L * 255;
211
+        $G = $L * 255;
212
+        $B = $L * 255;
213
+    } else {
214
+        $var_2 = $L < 0.5 ? $L * (1 + $S) : ($L + $S) - ($S * $L);
215
+
216
+        $var_1 = 2 * $L - $var_2;
217
+
218
+        $R = 255 * $hue_2_rgb($var_1, $var_2, $H + (1 / 3));
219
+        $G = 255 * $hue_2_rgb($var_1, $var_2, $H);
220
+        $B = 255 * $hue_2_rgb($var_1, $var_2, $H - (1 / 3));
221
+    }
222
+
223
+    $ret = [];
224
+    $ret['r'] = floor($R);
225
+    $ret['g'] = floor($G);
226
+    $ret['b'] = floor($B);
227
+
228
+    return $ret;
229 229
 }
230 230
 
231 231
 /**
@@ -243,11 +243,11 @@  discard block
 block discarded – undo
243 243
  *     true si il faut supprimer le fichier temporaire ; false sinon.
244 244
  */
245 245
 function statut_effacer_images_temporaires($stat) {
246
-	static $statut = false; // par defaut on grave toute les images
247
-	if ($stat === 'get') {
248
-		return $statut;
249
-	}
250
-	$statut = (bool) $stat;
246
+    static $statut = false; // par defaut on grave toute les images
247
+    if ($stat === 'get') {
248
+        return $statut;
249
+    }
250
+    $statut = (bool) $stat;
251 251
 }
252 252
 
253 253
 
@@ -300,251 +300,251 @@  discard block
 block discarded – undo
300 300
  *     - array : tableau décrivant de l'image
301 301
  */
302 302
 function _image_valeurs_trans($img, $effet, $forcer_format = false, $fonction_creation = null, $find_in_path = false, $support_svg = false) {
303
-	$valeurs = [];
304
-	$ret = [];
305
-	$f = null;
306
-	static $images_recalcul = [];
307
-	if (strlen($img) == 0) {
308
-		return false;
309
-	}
310
-
311
-	$source = trim(extraire_attribut($img, 'src') ?? '');
312
-	if (strlen($source) < 1) {
313
-		if (!str_starts_with($img, '<img ')) {
314
-			$source = $img;
315
-			$img = "<img src='$source' />";
316
-		} else {
317
-			// pas d'attribut src sur cette balise <img../>
318
-			return false;
319
-		}
320
-	} elseif (
321
-		preg_match('@^data:image/([^;]*);base64,(.*)$@isS', $source, $regs)
322
-		&& ($extension = _image_trouver_extension_depuis_mime('image/' . $regs[1]))
323
-		&& in_array($extension, _image_extensions_acceptees_en_entree())
324
-	) {
325
-		# gerer img src="data:....base64"
326
-		$local = sous_repertoire(_DIR_VAR, 'image-data') . md5($regs[2]) . '.' . _image_extension_normalisee($extension);
327
-		if (!file_exists($local)) {
328
-			ecrire_fichier($local, base64_decode($regs[2]));
329
-		}
330
-		if ($sanitizer = charger_fonction($extension, 'sanitizer', true)) {
331
-			$sanitizer($local);
332
-		}
333
-		$source = $local;
334
-		$img = inserer_attribut($img, 'src', $source);
335
-		# eviter les mauvaises surprises lors de conversions de format
336
-		$img = inserer_attribut($img, 'width', '');
337
-		$img = inserer_attribut($img, 'height', '');
338
-	}
339
-
340
-	// les protocoles web prennent au moins 3 lettres
341
-	if (tester_url_absolue($source)) {
342
-		include_spip('inc/distant');
343
-		$fichier = _DIR_RACINE . copie_locale($source);
344
-		if (!$fichier) {
345
-			return '';
346
-		}
347
-		if (
348
-			($extension = _image_trouver_extension($fichier))
349
-			&& ($sanitizer = charger_fonction($extension, 'sanitizer', true))
350
-		) {
351
-			$sanitizer($fichier);
352
-		}
353
-	} else {
354
-		// enlever le timestamp eventuel
355
-		if (str_contains($source, '?')) {
356
-			$source = preg_replace(',[?]\d+$,', '', $source);
357
-		}
358
-		if (
359
-			str_contains($source, '?')
360
-			&& str_starts_with($source, (string) _DIR_IMG)
361
-			&& file_exists($f = preg_replace(',[?].*$,', '', $source))
362
-		) {
363
-			$source = $f;
364
-		}
365
-		$fichier = $source;
366
-	}
367
-
368
-	$terminaison_dest = '';
369
-	if ($terminaison = _image_trouver_extension($fichier)) {
370
-		$terminaison_dest = ($terminaison == 'gif') ? 'png' : $terminaison;
371
-	}
372
-
373
-	if (
374
-		$forcer_format !== false
375
-		&& ($terminaison_dest !== 'svg' || $support_svg || !in_array($forcer_format, _image_extensions_acceptees_en_sortie()))
376
-	) {
377
-		$terminaison_dest = $forcer_format;
378
-	}
379
-
380
-	if (!$terminaison_dest) {
381
-		return false;
382
-	}
383
-
384
-	$nom_fichier = substr($fichier, 0, strlen($fichier) - (strlen($terminaison) + 1));
385
-	$fichier_dest = $nom_fichier;
386
-	if (
387
-		$find_in_path && ($f = find_in_path($fichier)) && ($fichier = $f)
388
-		|| @file_exists($f = $fichier)
389
-	) {
390
-		// on ne passe jamais la balise img qui est peut-être en x2 et à laquelle on ne peut pas faire confiance
391
-		// on lit directement les infos du fichier
392
-		[$ret['hauteur'], $ret['largeur']] = taille_image($f);
393
-		$date_src = @filemtime($f);
394
-	} elseif (
395
-		@file_exists($f = "$fichier.src")
396
-		&& lire_fichier($f, $valeurs)
397
-		&& ($valeurs = unserialize($valeurs))
398
-		&& isset($valeurs['hauteur_dest'])
399
-		&& isset($valeurs['largeur_dest'])
400
-	) {
401
-		$ret['hauteur'] = $valeurs['hauteur_dest'];
402
-		$ret['largeur'] = $valeurs['largeur_dest'];
403
-		$date_src = $valeurs['date'];
404
-	} // pas de fichier source par la
405
-	else {
406
-		return false;
407
-	}
408
-
409
-	// pas de taille mesurable ?
410
-	if (
411
-		!$ret['hauteur']
412
-		|| !($ret['hauteur'] = (int) round($ret['hauteur']))
413
-		|| !$ret['largeur']
414
-		|| !($ret['largeur'] = (int) round($ret['largeur']))
415
-	) {
416
-		return false;
417
-	}
418
-
419
-	// les images calculees dependent du chemin du fichier source
420
-	// pour une meme image source et un meme filtre on aboutira a 2 fichiers selon si l'appel est dans le public ou dans le prive
421
-	// ce n'est pas totalement optimal en terme de stockage, mais chaque image est associee a un fichier .src
422
-	// qui contient la methode de reconstrucion (le filtre + les arguments d'appel) et les arguments different entre prive et public
423
-	// la mise en commun du fichier image cree donc un bug et des problemes qui necessiteraient beaucoup de complexite de code
424
-	// alors que ca concerne peu de site au final
425
-	// la release de r23632+r23633+r23634 a provoque peu de remontee de bug attestant du peu de sites impactes
426
-	$identifiant = $fichier;
427
-
428
-	// cas general :
429
-	// on a un dossier cache commun et un nom de fichier qui varie avec l'effet
430
-	// cas particulier de reduire :
431
-	// un cache par dimension, et le nom de fichier est conserve, suffixe par la dimension aussi
432
-	$cache = 'cache-gd2';
433
-	if (str_starts_with($effet, 'reduire')) {
434
-		[, $maxWidth, $maxHeight] = explode('-', $effet);
435
-		[$destWidth, $destHeight] = _image_ratio($ret['largeur'], $ret['hauteur'], $maxWidth, $maxHeight);
436
-		$ret['largeur_dest'] = $destWidth;
437
-		$ret['hauteur_dest'] = $destHeight;
438
-		$effet = "L{$destWidth}xH$destHeight";
439
-		$cache = 'cache-vignettes';
440
-		$fichier_dest = basename($fichier_dest);
441
-		if (($ret['largeur'] <= $maxWidth) && ($ret['hauteur'] <= $maxHeight)) {
442
-			// on garde la terminaison initiale car image simplement copiee
443
-			// et on postfixe son nom avec un md5 du path
444
-			$terminaison_dest = $terminaison;
445
-			$fichier_dest .= '-' . substr(md5("$identifiant"), 0, 5);
446
-		} else {
447
-			$fichier_dest .= '-' . substr(md5("$identifiant-$effet"), 0, 5);
448
-		}
449
-		$cache = sous_repertoire(_DIR_VAR, $cache);
450
-		$cache = sous_repertoire($cache, $effet);
451
-	} else {
452
-		$fichier_dest = md5("$identifiant-$effet");
453
-		$cache = sous_repertoire(_DIR_VAR, $cache);
454
-		$cache = sous_repertoire($cache, substr($fichier_dest, 0, 2));
455
-		$fichier_dest = substr($fichier_dest, 2);
456
-	}
457
-
458
-	$fichier_dest = $cache . $fichier_dest . '.' . $terminaison_dest;
459
-
460
-	$GLOBALS['images_calculees'][] = $fichier_dest;
461
-
462
-	$creer = true;
463
-	// si recalcul des images demande, recalculer chaque image une fois
464
-	if (defined('_VAR_IMAGES') && _VAR_IMAGES && !isset($images_recalcul[$fichier_dest])) {
465
-		$images_recalcul[$fichier_dest] = true;
466
-	} else {
467
-		if (@file_exists($f = $fichier_dest)) {
468
-			if (filemtime($f) >= $date_src) {
469
-				$creer = false;
470
-			}
471
-		} else {
472
-			if (
473
-				@file_exists($f = "$fichier_dest.src")
474
-				&& lire_fichier($f, $valeurs)
475
-				&& ($valeurs = unserialize($valeurs))
476
-				&& $valeurs['date'] >= $date_src
477
-			) {
478
-				$creer = false;
479
-			}
480
-		}
481
-	}
482
-	if ($creer && !@file_exists($fichier)) {
483
-		if (!@file_exists("$fichier.src")) {
484
-			spip_log("Image absente : $fichier", 'images' . _LOG_ERREUR);
485
-
486
-			return false;
487
-		}
488
-		# on reconstruit l'image source absente a partir de la chaine des .src
489
-		reconstruire_image_intermediaire($fichier);
490
-	}
491
-
492
-	if ($creer) {
493
-		spip_log(
494
-			'filtre image ' . ($fonction_creation ? reset($fonction_creation) : '') . "[$effet] sur $fichier",
495
-			'images' . _LOG_DEBUG
496
-		);
497
-	}
498
-
499
-	$term_fonction = _image_trouver_extension_pertinente($fichier);
500
-	$ret['fonction_imagecreatefrom'] = '_imagecreatefrom' . $term_fonction;
501
-	$ret['fichier'] = $fichier;
502
-	$ret['fonction_image'] = '_image_image' . $terminaison_dest;
503
-	$ret['fichier_dest'] = $fichier_dest;
504
-	$ret['format_source'] = _image_extension_normalisee($terminaison);
505
-	$ret['format_dest'] = $terminaison_dest;
506
-	$ret['date_src'] = $date_src;
507
-	$ret['creer'] = $creer;
508
-	$ret['class'] = extraire_attribut($img, 'class');
509
-	$ret['alt'] = extraire_attribut($img, 'alt');
510
-	$ret['style'] = extraire_attribut($img, 'style');
511
-	$ret['tag'] = $img;
512
-	if ($fonction_creation) {
513
-		$ret['reconstruction'] = $fonction_creation;
514
-		# ecrire ici comment creer le fichier, car il est pas sur qu'on l'ecrira reelement
515
-		# cas de image_reduire qui finalement ne reduit pas l'image source
516
-		# ca evite d'essayer de le creer au prochain hit si il n'est pas la
517
-		#ecrire_fichier($ret['fichier_dest'].'.src',serialize($ret),true);
518
-	}
519
-
520
-	$ret = pipeline('image_preparer_filtre', [
521
-			'args' => [
522
-				'img' => $img,
523
-				'effet' => $effet,
524
-				'forcer_format' => $forcer_format,
525
-				'fonction_creation' => $fonction_creation,
526
-				'find_in_path' => $find_in_path,
527
-			],
528
-			'data' => $ret
529
-		]);
530
-
531
-	// une globale pour le debug en cas de crash memoire
532
-	$GLOBALS['derniere_image_calculee'] = $ret;
533
-
534
-	// traiter le cas particulier des SVG : si le filtre n'a pas annonce explicitement qu'il savait faire, on delegue
535
-	if ($term_fonction === 'svg') {
536
-		if ($creer && !$support_svg) {
537
-			process_image_svg_identite($ret);
538
-			$ret['creer'] = false;
539
-		}
540
-	}
541
-	else {
542
-		if (!function_exists($ret['fonction_imagecreatefrom'])) {
543
-			return false;
544
-		}
545
-	}
546
-
547
-	return $ret;
303
+    $valeurs = [];
304
+    $ret = [];
305
+    $f = null;
306
+    static $images_recalcul = [];
307
+    if (strlen($img) == 0) {
308
+        return false;
309
+    }
310
+
311
+    $source = trim(extraire_attribut($img, 'src') ?? '');
312
+    if (strlen($source) < 1) {
313
+        if (!str_starts_with($img, '<img ')) {
314
+            $source = $img;
315
+            $img = "<img src='$source' />";
316
+        } else {
317
+            // pas d'attribut src sur cette balise <img../>
318
+            return false;
319
+        }
320
+    } elseif (
321
+        preg_match('@^data:image/([^;]*);base64,(.*)$@isS', $source, $regs)
322
+        && ($extension = _image_trouver_extension_depuis_mime('image/' . $regs[1]))
323
+        && in_array($extension, _image_extensions_acceptees_en_entree())
324
+    ) {
325
+        # gerer img src="data:....base64"
326
+        $local = sous_repertoire(_DIR_VAR, 'image-data') . md5($regs[2]) . '.' . _image_extension_normalisee($extension);
327
+        if (!file_exists($local)) {
328
+            ecrire_fichier($local, base64_decode($regs[2]));
329
+        }
330
+        if ($sanitizer = charger_fonction($extension, 'sanitizer', true)) {
331
+            $sanitizer($local);
332
+        }
333
+        $source = $local;
334
+        $img = inserer_attribut($img, 'src', $source);
335
+        # eviter les mauvaises surprises lors de conversions de format
336
+        $img = inserer_attribut($img, 'width', '');
337
+        $img = inserer_attribut($img, 'height', '');
338
+    }
339
+
340
+    // les protocoles web prennent au moins 3 lettres
341
+    if (tester_url_absolue($source)) {
342
+        include_spip('inc/distant');
343
+        $fichier = _DIR_RACINE . copie_locale($source);
344
+        if (!$fichier) {
345
+            return '';
346
+        }
347
+        if (
348
+            ($extension = _image_trouver_extension($fichier))
349
+            && ($sanitizer = charger_fonction($extension, 'sanitizer', true))
350
+        ) {
351
+            $sanitizer($fichier);
352
+        }
353
+    } else {
354
+        // enlever le timestamp eventuel
355
+        if (str_contains($source, '?')) {
356
+            $source = preg_replace(',[?]\d+$,', '', $source);
357
+        }
358
+        if (
359
+            str_contains($source, '?')
360
+            && str_starts_with($source, (string) _DIR_IMG)
361
+            && file_exists($f = preg_replace(',[?].*$,', '', $source))
362
+        ) {
363
+            $source = $f;
364
+        }
365
+        $fichier = $source;
366
+    }
367
+
368
+    $terminaison_dest = '';
369
+    if ($terminaison = _image_trouver_extension($fichier)) {
370
+        $terminaison_dest = ($terminaison == 'gif') ? 'png' : $terminaison;
371
+    }
372
+
373
+    if (
374
+        $forcer_format !== false
375
+        && ($terminaison_dest !== 'svg' || $support_svg || !in_array($forcer_format, _image_extensions_acceptees_en_sortie()))
376
+    ) {
377
+        $terminaison_dest = $forcer_format;
378
+    }
379
+
380
+    if (!$terminaison_dest) {
381
+        return false;
382
+    }
383
+
384
+    $nom_fichier = substr($fichier, 0, strlen($fichier) - (strlen($terminaison) + 1));
385
+    $fichier_dest = $nom_fichier;
386
+    if (
387
+        $find_in_path && ($f = find_in_path($fichier)) && ($fichier = $f)
388
+        || @file_exists($f = $fichier)
389
+    ) {
390
+        // on ne passe jamais la balise img qui est peut-être en x2 et à laquelle on ne peut pas faire confiance
391
+        // on lit directement les infos du fichier
392
+        [$ret['hauteur'], $ret['largeur']] = taille_image($f);
393
+        $date_src = @filemtime($f);
394
+    } elseif (
395
+        @file_exists($f = "$fichier.src")
396
+        && lire_fichier($f, $valeurs)
397
+        && ($valeurs = unserialize($valeurs))
398
+        && isset($valeurs['hauteur_dest'])
399
+        && isset($valeurs['largeur_dest'])
400
+    ) {
401
+        $ret['hauteur'] = $valeurs['hauteur_dest'];
402
+        $ret['largeur'] = $valeurs['largeur_dest'];
403
+        $date_src = $valeurs['date'];
404
+    } // pas de fichier source par la
405
+    else {
406
+        return false;
407
+    }
408
+
409
+    // pas de taille mesurable ?
410
+    if (
411
+        !$ret['hauteur']
412
+        || !($ret['hauteur'] = (int) round($ret['hauteur']))
413
+        || !$ret['largeur']
414
+        || !($ret['largeur'] = (int) round($ret['largeur']))
415
+    ) {
416
+        return false;
417
+    }
418
+
419
+    // les images calculees dependent du chemin du fichier source
420
+    // pour une meme image source et un meme filtre on aboutira a 2 fichiers selon si l'appel est dans le public ou dans le prive
421
+    // ce n'est pas totalement optimal en terme de stockage, mais chaque image est associee a un fichier .src
422
+    // qui contient la methode de reconstrucion (le filtre + les arguments d'appel) et les arguments different entre prive et public
423
+    // la mise en commun du fichier image cree donc un bug et des problemes qui necessiteraient beaucoup de complexite de code
424
+    // alors que ca concerne peu de site au final
425
+    // la release de r23632+r23633+r23634 a provoque peu de remontee de bug attestant du peu de sites impactes
426
+    $identifiant = $fichier;
427
+
428
+    // cas general :
429
+    // on a un dossier cache commun et un nom de fichier qui varie avec l'effet
430
+    // cas particulier de reduire :
431
+    // un cache par dimension, et le nom de fichier est conserve, suffixe par la dimension aussi
432
+    $cache = 'cache-gd2';
433
+    if (str_starts_with($effet, 'reduire')) {
434
+        [, $maxWidth, $maxHeight] = explode('-', $effet);
435
+        [$destWidth, $destHeight] = _image_ratio($ret['largeur'], $ret['hauteur'], $maxWidth, $maxHeight);
436
+        $ret['largeur_dest'] = $destWidth;
437
+        $ret['hauteur_dest'] = $destHeight;
438
+        $effet = "L{$destWidth}xH$destHeight";
439
+        $cache = 'cache-vignettes';
440
+        $fichier_dest = basename($fichier_dest);
441
+        if (($ret['largeur'] <= $maxWidth) && ($ret['hauteur'] <= $maxHeight)) {
442
+            // on garde la terminaison initiale car image simplement copiee
443
+            // et on postfixe son nom avec un md5 du path
444
+            $terminaison_dest = $terminaison;
445
+            $fichier_dest .= '-' . substr(md5("$identifiant"), 0, 5);
446
+        } else {
447
+            $fichier_dest .= '-' . substr(md5("$identifiant-$effet"), 0, 5);
448
+        }
449
+        $cache = sous_repertoire(_DIR_VAR, $cache);
450
+        $cache = sous_repertoire($cache, $effet);
451
+    } else {
452
+        $fichier_dest = md5("$identifiant-$effet");
453
+        $cache = sous_repertoire(_DIR_VAR, $cache);
454
+        $cache = sous_repertoire($cache, substr($fichier_dest, 0, 2));
455
+        $fichier_dest = substr($fichier_dest, 2);
456
+    }
457
+
458
+    $fichier_dest = $cache . $fichier_dest . '.' . $terminaison_dest;
459
+
460
+    $GLOBALS['images_calculees'][] = $fichier_dest;
461
+
462
+    $creer = true;
463
+    // si recalcul des images demande, recalculer chaque image une fois
464
+    if (defined('_VAR_IMAGES') && _VAR_IMAGES && !isset($images_recalcul[$fichier_dest])) {
465
+        $images_recalcul[$fichier_dest] = true;
466
+    } else {
467
+        if (@file_exists($f = $fichier_dest)) {
468
+            if (filemtime($f) >= $date_src) {
469
+                $creer = false;
470
+            }
471
+        } else {
472
+            if (
473
+                @file_exists($f = "$fichier_dest.src")
474
+                && lire_fichier($f, $valeurs)
475
+                && ($valeurs = unserialize($valeurs))
476
+                && $valeurs['date'] >= $date_src
477
+            ) {
478
+                $creer = false;
479
+            }
480
+        }
481
+    }
482
+    if ($creer && !@file_exists($fichier)) {
483
+        if (!@file_exists("$fichier.src")) {
484
+            spip_log("Image absente : $fichier", 'images' . _LOG_ERREUR);
485
+
486
+            return false;
487
+        }
488
+        # on reconstruit l'image source absente a partir de la chaine des .src
489
+        reconstruire_image_intermediaire($fichier);
490
+    }
491
+
492
+    if ($creer) {
493
+        spip_log(
494
+            'filtre image ' . ($fonction_creation ? reset($fonction_creation) : '') . "[$effet] sur $fichier",
495
+            'images' . _LOG_DEBUG
496
+        );
497
+    }
498
+
499
+    $term_fonction = _image_trouver_extension_pertinente($fichier);
500
+    $ret['fonction_imagecreatefrom'] = '_imagecreatefrom' . $term_fonction;
501
+    $ret['fichier'] = $fichier;
502
+    $ret['fonction_image'] = '_image_image' . $terminaison_dest;
503
+    $ret['fichier_dest'] = $fichier_dest;
504
+    $ret['format_source'] = _image_extension_normalisee($terminaison);
505
+    $ret['format_dest'] = $terminaison_dest;
506
+    $ret['date_src'] = $date_src;
507
+    $ret['creer'] = $creer;
508
+    $ret['class'] = extraire_attribut($img, 'class');
509
+    $ret['alt'] = extraire_attribut($img, 'alt');
510
+    $ret['style'] = extraire_attribut($img, 'style');
511
+    $ret['tag'] = $img;
512
+    if ($fonction_creation) {
513
+        $ret['reconstruction'] = $fonction_creation;
514
+        # ecrire ici comment creer le fichier, car il est pas sur qu'on l'ecrira reelement
515
+        # cas de image_reduire qui finalement ne reduit pas l'image source
516
+        # ca evite d'essayer de le creer au prochain hit si il n'est pas la
517
+        #ecrire_fichier($ret['fichier_dest'].'.src',serialize($ret),true);
518
+    }
519
+
520
+    $ret = pipeline('image_preparer_filtre', [
521
+            'args' => [
522
+                'img' => $img,
523
+                'effet' => $effet,
524
+                'forcer_format' => $forcer_format,
525
+                'fonction_creation' => $fonction_creation,
526
+                'find_in_path' => $find_in_path,
527
+            ],
528
+            'data' => $ret
529
+        ]);
530
+
531
+    // une globale pour le debug en cas de crash memoire
532
+    $GLOBALS['derniere_image_calculee'] = $ret;
533
+
534
+    // traiter le cas particulier des SVG : si le filtre n'a pas annonce explicitement qu'il savait faire, on delegue
535
+    if ($term_fonction === 'svg') {
536
+        if ($creer && !$support_svg) {
537
+            process_image_svg_identite($ret);
538
+            $ret['creer'] = false;
539
+        }
540
+    }
541
+    else {
542
+        if (!function_exists($ret['fonction_imagecreatefrom'])) {
543
+            return false;
544
+        }
545
+    }
546
+
547
+    return $ret;
548 548
 }
549 549
 
550 550
 
@@ -552,54 +552,54 @@  discard block
 block discarded – undo
552 552
  * Extensions d’images acceptées en entrée
553 553
  */
554 554
 function _image_extensions_acceptees_en_entree(): array {
555
-	static $extensions = null;
556
-	if (empty($extensions)) {
557
-		$extensions = ['png', 'gif', 'jpg', 'jpeg'];
558
-		if (!empty($GLOBALS['meta']['gd_formats'])) {
559
-			// action=tester renseigne gd_formats et detecte le support de webp
560
-			$extensions = array_merge(explode(',', (string) $GLOBALS['meta']['gd_formats']));
561
-			$extensions = array_map('trim', $extensions);
562
-			$extensions = array_filter($extensions);
563
-			if (in_array('jpg', $extensions)) {
564
-				$extensions[] = 'jpeg';
565
-			}
566
-			$extensions = array_unique($extensions);
567
-		}
568
-		$extensions[] = 'svg'; // on le supporte toujours avec des fonctions specifiques
569
-	}
570
-
571
-	return $extensions;
555
+    static $extensions = null;
556
+    if (empty($extensions)) {
557
+        $extensions = ['png', 'gif', 'jpg', 'jpeg'];
558
+        if (!empty($GLOBALS['meta']['gd_formats'])) {
559
+            // action=tester renseigne gd_formats et detecte le support de webp
560
+            $extensions = array_merge(explode(',', (string) $GLOBALS['meta']['gd_formats']));
561
+            $extensions = array_map('trim', $extensions);
562
+            $extensions = array_filter($extensions);
563
+            if (in_array('jpg', $extensions)) {
564
+                $extensions[] = 'jpeg';
565
+            }
566
+            $extensions = array_unique($extensions);
567
+        }
568
+        $extensions[] = 'svg'; // on le supporte toujours avec des fonctions specifiques
569
+    }
570
+
571
+    return $extensions;
572 572
 }
573 573
 
574 574
 /**
575 575
  * Extensions d’images acceptées en sortie
576 576
  */
577 577
 function _image_extensions_acceptees_en_sortie(): array {
578
-	static $extensions = null;
579
-	if (empty($extensions)) {
580
-		$extensions = _image_extensions_acceptees_en_entree();
581
-		$extensions = array_diff($extensions, ['jpeg']);
582
-		if (in_array('gif', $extensions) && !function_exists('imagegif')) {
583
-			$extensions = array_diff($extensions, ['gif']);
584
-		}
585
-		if (in_array('webp', $extensions) && !function_exists('imagewebp')) {
586
-			$extensions = array_diff($extensions, ['webp']);
587
-		}
588
-	}
589
-
590
-	return $extensions;
578
+    static $extensions = null;
579
+    if (empty($extensions)) {
580
+        $extensions = _image_extensions_acceptees_en_entree();
581
+        $extensions = array_diff($extensions, ['jpeg']);
582
+        if (in_array('gif', $extensions) && !function_exists('imagegif')) {
583
+            $extensions = array_diff($extensions, ['gif']);
584
+        }
585
+        if (in_array('webp', $extensions) && !function_exists('imagewebp')) {
586
+            $extensions = array_diff($extensions, ['webp']);
587
+        }
588
+    }
589
+
590
+    return $extensions;
591 591
 }
592 592
 
593 593
 function _image_extension_normalisee($extension) {
594
-	$extension = strtolower((string) $extension);
595
-	if ($extension === 'jpeg') {
596
-		$extension = 'jpg';
597
-	}
598
-	return $extension;
594
+    $extension = strtolower((string) $extension);
595
+    if ($extension === 'jpeg') {
596
+        $extension = 'jpg';
597
+    }
598
+    return $extension;
599 599
 }
600 600
 
601 601
 function _image_extensions_conservent_transparence() {
602
-	return ['png', 'webp'];
602
+    return ['png', 'webp'];
603 603
 }
604 604
 
605 605
 
@@ -609,11 +609,11 @@  discard block
 block discarded – undo
609 609
  * @return string
610 610
  */
611 611
 function _image_trouver_extension($path) {
612
-	$preg_extensions = implode('|', _image_extensions_acceptees_en_entree());
613
-	if (preg_match(",\.($preg_extensions)($|[?]),i", $path, $regs)) {
614
-		return strtolower($regs[1]);
615
-	}
616
-	return '';
612
+    $preg_extensions = implode('|', _image_extensions_acceptees_en_entree());
613
+    if (preg_match(",\.($preg_extensions)($|[?]),i", $path, $regs)) {
614
+        return strtolower($regs[1]);
615
+    }
616
+    return '';
617 617
 }
618 618
 
619 619
 /**
@@ -624,42 +624,42 @@  discard block
 block discarded – undo
624 624
  * @return string Extension, dans le format attendu par les fonctions 'gd' ('jpeg' pour les .jpg par exemple)
625 625
  */
626 626
 function _image_trouver_extension_pertinente($path) {
627
-	$path = supprimer_timestamp($path);
628
-	$terminaison = _image_trouver_extension($path);
629
-	if ($terminaison == 'jpg') {
630
-		$terminaison = 'jpeg';
631
-	}
632
-
633
-	if (!file_exists($path)) {
634
-		return $terminaison;
635
-	}
636
-
637
-	if (!$info = @spip_getimagesize($path)) {
638
-		return $terminaison;
639
-	}
640
-
641
-	$mime = $info['mime'] ?? image_type_to_mime_type($info[2]);
642
-
643
-	$_terminaison = _image_trouver_extension_depuis_mime($mime);
644
-	if ($_terminaison && $_terminaison !== $terminaison) {
645
-		spip_log("Mauvaise extension du fichier : $path . Son type mime est : $mime", 'images.' . _LOG_INFO_IMPORTANTE);
646
-		$terminaison = $_terminaison;
647
-	}
648
-	return $terminaison;
627
+    $path = supprimer_timestamp($path);
628
+    $terminaison = _image_trouver_extension($path);
629
+    if ($terminaison == 'jpg') {
630
+        $terminaison = 'jpeg';
631
+    }
632
+
633
+    if (!file_exists($path)) {
634
+        return $terminaison;
635
+    }
636
+
637
+    if (!$info = @spip_getimagesize($path)) {
638
+        return $terminaison;
639
+    }
640
+
641
+    $mime = $info['mime'] ?? image_type_to_mime_type($info[2]);
642
+
643
+    $_terminaison = _image_trouver_extension_depuis_mime($mime);
644
+    if ($_terminaison && $_terminaison !== $terminaison) {
645
+        spip_log("Mauvaise extension du fichier : $path . Son type mime est : $mime", 'images.' . _LOG_INFO_IMPORTANTE);
646
+        $terminaison = $_terminaison;
647
+    }
648
+    return $terminaison;
649 649
 }
650 650
 
651 651
 /**
652 652
  * Retourne une extension d’image depuis un mime-type
653 653
  */
654 654
 function _image_trouver_extension_depuis_mime(string $mime): string {
655
-	return match (strtolower($mime)) {
656
-		'image/png', 'image/x-png' => 'png',
657
-		'image/jpg', 'image/jpeg', 'image/pjpeg' => 'jpeg',
658
-		'image/gif' => 'gif',
659
-		'image/webp', 'image/x-webp' => 'webp',
660
-		'image/svg+xml' => 'svg',
661
-		default => '',
662
-	};
655
+    return match (strtolower($mime)) {
656
+        'image/png', 'image/x-png' => 'png',
657
+        'image/jpg', 'image/jpeg', 'image/pjpeg' => 'jpeg',
658
+        'image/gif' => 'gif',
659
+        'image/webp', 'image/x-webp' => 'webp',
660
+        'image/svg+xml' => 'svg',
661
+        default => '',
662
+    };
663 663
 }
664 664
 
665 665
 
@@ -679,18 +679,18 @@  discard block
 block discarded – undo
679 679
  *     Une ressource de type Image GD.
680 680
  */
681 681
 function _imagecreatefrom_func(string $func, string $filename) {
682
-	if (!function_exists($func)) {
683
-		spip_log("GD indisponible : $func inexistante. Traitement $filename impossible.", _LOG_CRITIQUE);
684
-		erreur_squelette("GD indisponible : $func inexistante. Traitement $filename impossible.");
685
-		return null;
686
-	}
687
-	$img = @$func($filename);
688
-	if (!$img) {
689
-		spip_log("Erreur lecture $func $filename", _LOG_CRITIQUE);
690
-		erreur_squelette("Erreur lecture $func $filename");
691
-		$img = imagecreate(10, 10);
692
-	}
693
-	return $img;
682
+    if (!function_exists($func)) {
683
+        spip_log("GD indisponible : $func inexistante. Traitement $filename impossible.", _LOG_CRITIQUE);
684
+        erreur_squelette("GD indisponible : $func inexistante. Traitement $filename impossible.");
685
+        return null;
686
+    }
687
+    $img = @$func($filename);
688
+    if (!$img) {
689
+        spip_log("Erreur lecture $func $filename", _LOG_CRITIQUE);
690
+        erreur_squelette("Erreur lecture $func $filename");
691
+        $img = imagecreate(10, 10);
692
+    }
693
+    return $img;
694 694
 }
695 695
 
696 696
 /**
@@ -706,7 +706,7 @@  discard block
 block discarded – undo
706 706
  *     Une ressource de type Image GD.
707 707
  */
708 708
 function _imagecreatefromjpeg($filename) {
709
-	return _imagecreatefrom_func('imagecreatefromjpeg', $filename);
709
+    return _imagecreatefrom_func('imagecreatefromjpeg', $filename);
710 710
 }
711 711
 
712 712
 /**
@@ -722,7 +722,7 @@  discard block
 block discarded – undo
722 722
  *     Une ressource de type Image GD.
723 723
  */
724 724
 function _imagecreatefrompng($filename) {
725
-	return _imagecreatefrom_func('imagecreatefrompng', $filename);
725
+    return _imagecreatefrom_func('imagecreatefrompng', $filename);
726 726
 }
727 727
 
728 728
 /**
@@ -738,7 +738,7 @@  discard block
 block discarded – undo
738 738
  *     Une ressource de type Image GD.
739 739
  */
740 740
 function _imagecreatefromgif($filename) {
741
-	return _imagecreatefrom_func('imagecreatefromgif', $filename);
741
+    return _imagecreatefrom_func('imagecreatefromgif', $filename);
742 742
 }
743 743
 
744 744
 
@@ -755,7 +755,7 @@  discard block
 block discarded – undo
755 755
  *     Une ressource de type Image GD.
756 756
  */
757 757
 function _imagecreatefromwebp($filename) {
758
-	return _imagecreatefrom_func('imagecreatefromwebp', $filename);
758
+    return _imagecreatefrom_func('imagecreatefromwebp', $filename);
759 759
 }
760 760
 
761 761
 /**
@@ -773,24 +773,24 @@  discard block
 block discarded – undo
773 773
  *     - true si une image est bien retournée.
774 774
  */
775 775
 function _image_imagepng($img, $fichier) {
776
-	if (!function_exists('imagepng')) {
777
-		return false;
778
-	}
779
-	$tmp = $fichier . '.tmp';
780
-	$ret = imagepng($img, $tmp);
781
-	if (file_exists($tmp)) {
782
-		$taille_test = @getimagesize($tmp);
783
-		if (empty($taille_test[0])) {
784
-			return false;
785
-		}
786
-
787
-		spip_unlink($fichier); // le fichier peut deja exister
788
-		@rename($tmp, $fichier);
789
-
790
-		return $ret;
791
-	}
792
-
793
-	return false;
776
+    if (!function_exists('imagepng')) {
777
+        return false;
778
+    }
779
+    $tmp = $fichier . '.tmp';
780
+    $ret = imagepng($img, $tmp);
781
+    if (file_exists($tmp)) {
782
+        $taille_test = @getimagesize($tmp);
783
+        if (empty($taille_test[0])) {
784
+            return false;
785
+        }
786
+
787
+        spip_unlink($fichier); // le fichier peut deja exister
788
+        @rename($tmp, $fichier);
789
+
790
+        return $ret;
791
+    }
792
+
793
+    return false;
794 794
 }
795 795
 
796 796
 /**
@@ -808,24 +808,24 @@  discard block
 block discarded – undo
808 808
  *     - true si une image est bien retournée.
809 809
  */
810 810
 function _image_imagegif($img, $fichier) {
811
-	if (!function_exists('imagegif')) {
812
-		return false;
813
-	}
814
-	$tmp = $fichier . '.tmp';
815
-	$ret = imagegif($img, $tmp);
816
-	if (file_exists($tmp)) {
817
-		$taille_test = @getimagesize($tmp);
818
-		if (empty($taille_test[0])) {
819
-			return false;
820
-		}
821
-
822
-		spip_unlink($fichier); // le fichier peut deja exister
823
-		@rename($tmp, $fichier);
824
-
825
-		return $ret;
826
-	}
827
-
828
-	return false;
811
+    if (!function_exists('imagegif')) {
812
+        return false;
813
+    }
814
+    $tmp = $fichier . '.tmp';
815
+    $ret = imagegif($img, $tmp);
816
+    if (file_exists($tmp)) {
817
+        $taille_test = @getimagesize($tmp);
818
+        if (empty($taille_test[0])) {
819
+            return false;
820
+        }
821
+
822
+        spip_unlink($fichier); // le fichier peut deja exister
823
+        @rename($tmp, $fichier);
824
+
825
+        return $ret;
826
+    }
827
+
828
+    return false;
829 829
 }
830 830
 
831 831
 /**
@@ -848,29 +848,29 @@  discard block
 block discarded – undo
848 848
  *     - true si une image est bien retournée.
849 849
  */
850 850
 function _image_imagejpg($img, $fichier, $qualite = _IMG_GD_QUALITE) {
851
-	if (!function_exists('imagejpeg')) {
852
-		return false;
853
-	}
854
-	$tmp = $fichier . '.tmp';
851
+    if (!function_exists('imagejpeg')) {
852
+        return false;
853
+    }
854
+    $tmp = $fichier . '.tmp';
855 855
 
856
-	// Enable interlancing
857
-	imageinterlace($img, true);
856
+    // Enable interlancing
857
+    imageinterlace($img, true);
858 858
 
859
-	$ret = imagejpeg($img, $tmp, $qualite);
859
+    $ret = imagejpeg($img, $tmp, $qualite);
860 860
 
861
-	if (file_exists($tmp)) {
862
-		$taille_test = @getimagesize($tmp);
863
-		if (empty($taille_test[0])) {
864
-			return false;
865
-		}
861
+    if (file_exists($tmp)) {
862
+        $taille_test = @getimagesize($tmp);
863
+        if (empty($taille_test[0])) {
864
+            return false;
865
+        }
866 866
 
867
-		spip_unlink($fichier); // le fichier peut deja exister
868
-		@rename($tmp, $fichier);
867
+        spip_unlink($fichier); // le fichier peut deja exister
868
+        @rename($tmp, $fichier);
869 869
 
870
-		return $ret;
871
-	}
870
+        return $ret;
871
+    }
872 872
 
873
-	return false;
873
+    return false;
874 874
 }
875 875
 
876 876
 /**
@@ -888,9 +888,9 @@  discard block
 block discarded – undo
888 888
  *     true si le fichier a bien été créé ; false sinon.
889 889
  */
890 890
 function _image_imageico($img, $fichier) {
891
-	$gd_image_array = [$img];
891
+    $gd_image_array = [$img];
892 892
 
893
-	return ecrire_fichier($fichier, phpthumb_functions::GD2ICOstring($gd_image_array));
893
+    return ecrire_fichier($fichier, phpthumb_functions::GD2ICOstring($gd_image_array));
894 894
 }
895 895
 
896 896
 
@@ -909,24 +909,24 @@  discard block
 block discarded – undo
909 909
  *     - true si une image est bien retournée.
910 910
  */
911 911
 function _image_imagewebp($img, $fichier, $qualite = _IMG_GD_QUALITE) {
912
-	if (!function_exists('imagewebp')) {
913
-		return false;
914
-	}
915
-	$tmp = $fichier . '.tmp';
916
-	$ret = imagewebp($img, $tmp, $qualite);
917
-	if (file_exists($tmp)) {
918
-		$taille_test = @getimagesize($tmp);
919
-		if (empty($taille_test[0])) {
920
-			return false;
921
-		}
922
-
923
-		spip_unlink($fichier); // le fichier peut deja exister
924
-		@rename($tmp, $fichier);
925
-
926
-		return $ret;
927
-	}
928
-
929
-	return false;
912
+    if (!function_exists('imagewebp')) {
913
+        return false;
914
+    }
915
+    $tmp = $fichier . '.tmp';
916
+    $ret = imagewebp($img, $tmp, $qualite);
917
+    if (file_exists($tmp)) {
918
+        $taille_test = @getimagesize($tmp);
919
+        if (empty($taille_test[0])) {
920
+            return false;
921
+        }
922
+
923
+        spip_unlink($fichier); // le fichier peut deja exister
924
+        @rename($tmp, $fichier);
925
+
926
+        return $ret;
927
+    }
928
+
929
+    return false;
930 930
 }
931 931
 
932 932
 /**
@@ -946,35 +946,35 @@  discard block
 block discarded – undo
946 946
  */
947 947
 function _image_imagesvg($img, $fichier) {
948 948
 
949
-	$tmp = $fichier . '.tmp';
950
-	if (!str_contains($img, '<')) {
951
-		$img = supprimer_timestamp($img);
952
-		if (!file_exists($img)) {
953
-			return false;
954
-		}
955
-		@copy($img, $tmp);
956
-		if (filesize($tmp) === filesize($img)) {
957
-			spip_unlink($fichier); // le fichier peut deja exister
958
-			@rename($tmp, $fichier);
959
-			return true;
960
-		}
961
-		return false;
962
-	}
963
-
964
-	file_put_contents($tmp, $img);
965
-	if (file_exists($tmp)) {
966
-		$taille_test = spip_getimagesize($tmp);
967
-		if (empty($taille_test[0])) {
968
-			return false;
969
-		}
970
-
971
-		spip_unlink($fichier); // le fichier peut deja exister
972
-		@rename($tmp, $fichier);
973
-
974
-		return true;
975
-	}
976
-
977
-	return false;
949
+    $tmp = $fichier . '.tmp';
950
+    if (!str_contains($img, '<')) {
951
+        $img = supprimer_timestamp($img);
952
+        if (!file_exists($img)) {
953
+            return false;
954
+        }
955
+        @copy($img, $tmp);
956
+        if (filesize($tmp) === filesize($img)) {
957
+            spip_unlink($fichier); // le fichier peut deja exister
958
+            @rename($tmp, $fichier);
959
+            return true;
960
+        }
961
+        return false;
962
+    }
963
+
964
+    file_put_contents($tmp, $img);
965
+    if (file_exists($tmp)) {
966
+        $taille_test = spip_getimagesize($tmp);
967
+        if (empty($taille_test[0])) {
968
+            return false;
969
+        }
970
+
971
+        spip_unlink($fichier); // le fichier peut deja exister
972
+        @rename($tmp, $fichier);
973
+
974
+        return true;
975
+    }
976
+
977
+    return false;
978 978
 }
979 979
 
980 980
 
@@ -1002,30 +1002,30 @@  discard block
 block discarded – undo
1002 1002
  *     - false sinon.
1003 1003
  */
1004 1004
 function _image_gd_output($img, $valeurs, $qualite = _IMG_GD_QUALITE, $fonction = null) {
1005
-	if (is_null($fonction)) {
1006
-		$fonction = '_image_image' . $valeurs['format_dest'];
1007
-	}
1008
-	$ret = false;
1009
-	#un flag pour reperer les images gravees
1010
-	$lock = (
1011
-		!statut_effacer_images_temporaires('get')
1012
-		|| @file_exists($valeurs['fichier_dest'])
1013
-		&& !@file_exists($valeurs['fichier_dest'] . '.src')
1014
-	);
1015
-	if (
1016
-		function_exists($fonction)
1017
-		&& ($ret = $fonction($img, $valeurs['fichier_dest'], $qualite)) # on a reussi a creer l'image
1018
-		&& isset($valeurs['reconstruction']) # et on sait comment la resonctruire le cas echeant
1019
-		&& !$lock && @file_exists($valeurs['fichier_dest'])
1020
-	) {
1021
-		// dans tous les cas mettre a jour la taille de l'image finale
1022
-		[$valeurs['hauteur_dest'], $valeurs['largeur_dest']] = taille_image($valeurs['fichier_dest']);
1023
-		$valeurs['date'] = @filemtime($valeurs['fichier_dest']);
1024
-		// pour la retrouver apres disparition
1025
-		ecrire_fichier($valeurs['fichier_dest'] . '.src', serialize($valeurs), true);
1026
-	}
1027
-
1028
-	return $ret;
1005
+    if (is_null($fonction)) {
1006
+        $fonction = '_image_image' . $valeurs['format_dest'];
1007
+    }
1008
+    $ret = false;
1009
+    #un flag pour reperer les images gravees
1010
+    $lock = (
1011
+        !statut_effacer_images_temporaires('get')
1012
+        || @file_exists($valeurs['fichier_dest'])
1013
+        && !@file_exists($valeurs['fichier_dest'] . '.src')
1014
+    );
1015
+    if (
1016
+        function_exists($fonction)
1017
+        && ($ret = $fonction($img, $valeurs['fichier_dest'], $qualite)) # on a reussi a creer l'image
1018
+        && isset($valeurs['reconstruction']) # et on sait comment la resonctruire le cas echeant
1019
+        && !$lock && @file_exists($valeurs['fichier_dest'])
1020
+    ) {
1021
+        // dans tous les cas mettre a jour la taille de l'image finale
1022
+        [$valeurs['hauteur_dest'], $valeurs['largeur_dest']] = taille_image($valeurs['fichier_dest']);
1023
+        $valeurs['date'] = @filemtime($valeurs['fichier_dest']);
1024
+        // pour la retrouver apres disparition
1025
+        ecrire_fichier($valeurs['fichier_dest'] . '.src', serialize($valeurs), true);
1026
+    }
1027
+
1028
+    return $ret;
1029 1029
 }
1030 1030
 
1031 1031
 /**
@@ -1038,28 +1038,28 @@  discard block
 block discarded – undo
1038 1038
  *     Chemin vers le fichier manquant
1039 1039
  **/
1040 1040
 function reconstruire_image_intermediaire($fichier_manquant) {
1041
-	$source = null;
1042
-	$reconstruire = [];
1043
-	$fichier = $fichier_manquant;
1044
-	while (
1045
-		!str_contains((string) $fichier, '://')
1046
-		&& !@file_exists($fichier)
1047
-		&& lire_fichier($src = "$fichier.src", $source)
1048
-		&& ($valeurs = unserialize($source))
1049
-		&& ($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
1050
-	) {
1051
-		spip_unlink($src); // si jamais on a un timeout pendant la reconstruction, elle se fera naturellement au hit suivant
1052
-		$reconstruire[] = $valeurs['reconstruction'];
1053
-	}
1054
-	while (count($reconstruire)) {
1055
-		$r = array_pop($reconstruire);
1056
-		$fonction = $r[0];
1057
-		$args = $r[1];
1058
-		$fonction(...$args);
1059
-	}
1060
-	// cette image intermediaire est commune a plusieurs series de filtre, il faut la conserver
1061
-	// mais l'on peut nettoyer les miettes de sa creation
1062
-	ramasse_miettes($fichier_manquant);
1041
+    $source = null;
1042
+    $reconstruire = [];
1043
+    $fichier = $fichier_manquant;
1044
+    while (
1045
+        !str_contains((string) $fichier, '://')
1046
+        && !@file_exists($fichier)
1047
+        && lire_fichier($src = "$fichier.src", $source)
1048
+        && ($valeurs = unserialize($source))
1049
+        && ($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
1050
+    ) {
1051
+        spip_unlink($src); // si jamais on a un timeout pendant la reconstruction, elle se fera naturellement au hit suivant
1052
+        $reconstruire[] = $valeurs['reconstruction'];
1053
+    }
1054
+    while (count($reconstruire)) {
1055
+        $r = array_pop($reconstruire);
1056
+        $fonction = $r[0];
1057
+        $args = $r[1];
1058
+        $fonction(...$args);
1059
+    }
1060
+    // cette image intermediaire est commune a plusieurs series de filtre, il faut la conserver
1061
+    // mais l'on peut nettoyer les miettes de sa creation
1062
+    ramasse_miettes($fichier_manquant);
1063 1063
 }
1064 1064
 
1065 1065
 /**
@@ -1079,26 +1079,26 @@  discard block
 block discarded – undo
1079 1079
  *     Chemin du fichier d'image calculé
1080 1080
  **/
1081 1081
 function ramasse_miettes($fichier) {
1082
-	$source = null;
1083
-	if (
1084
-		str_contains($fichier, '://')
1085
-		|| !lire_fichier($src = "$fichier.src", $source)
1086
-		|| !$valeurs = unserialize($source)
1087
-	) {
1088
-		return;
1089
-	}
1090
-	spip_unlink($src); # on supprime la reference a sa source pour marquer cette image comme non intermediaire
1091
-	while (
1092
-		($fichier = $valeurs['fichier'])
1093
-		&& str_starts_with((string) $fichier, (string) _DIR_VAR)
1094
-		&& lire_fichier($src = "$fichier.src", $source)
1095
-		&& ($valeurs = unserialize($source))  # et valide
1096
-	) {
1097
-		# on efface le fichier
1098
-		spip_unlink($fichier);
1099
-		# mais laisse le .src qui permet de savoir comment reconstruire l'image si besoin
1100
-		#spip_unlink($src);
1101
-	}
1082
+    $source = null;
1083
+    if (
1084
+        str_contains($fichier, '://')
1085
+        || !lire_fichier($src = "$fichier.src", $source)
1086
+        || !$valeurs = unserialize($source)
1087
+    ) {
1088
+        return;
1089
+    }
1090
+    spip_unlink($src); # on supprime la reference a sa source pour marquer cette image comme non intermediaire
1091
+    while (
1092
+        ($fichier = $valeurs['fichier'])
1093
+        && str_starts_with((string) $fichier, (string) _DIR_VAR)
1094
+        && lire_fichier($src = "$fichier.src", $source)
1095
+        && ($valeurs = unserialize($source))  # et valide
1096
+    ) {
1097
+        # on efface le fichier
1098
+        spip_unlink($fichier);
1099
+        # mais laisse le .src qui permet de savoir comment reconstruire l'image si besoin
1100
+        #spip_unlink($src);
1101
+    }
1102 1102
 }
1103 1103
 
1104 1104
 
@@ -1123,33 +1123,33 @@  discard block
 block discarded – undo
1123 1123
  *     Code HTML de l'image
1124 1124
  **/
1125 1125
 function image_graver($img) {
1126
-	// appeler le filtre post_image_filtrer qui permet de faire
1127
-	// des traitements auto a la fin d'une serie de filtres
1128
-	$img = pipeline('post_image_filtrer', $img);
1129
-
1130
-	$fichier_ori = $fichier = (extraire_attribut($img, 'src') ?? '');
1131
-	if (($p = strpos($fichier, '?')) !== false) {
1132
-		$fichier = substr($fichier, 0, $p);
1133
-	}
1134
-	if (strlen($fichier) < 1 && !str_starts_with((string) $img, '<img ')) {
1135
-		$fichier = $img;
1136
-	}
1137
-	if (strlen((string) $fichier)) {
1138
-		# si jamais le fichier final n'a pas ete calcule car suppose temporaire
1139
-		# et qu'il ne s'agit pas d'une URL
1140
-		if (!str_contains((string) $fichier, '://') && !@file_exists($fichier)) {
1141
-			reconstruire_image_intermediaire($fichier);
1142
-		}
1143
-		ramasse_miettes($fichier);
1144
-
1145
-		// ajouter le timestamp si besoin
1146
-		if (!str_contains($fichier_ori, '?')) {
1147
-			// on utilise str_replace pour attraper le onmouseover des logo si besoin
1148
-			$img = str_replace($fichier_ori, timestamp($fichier_ori), (string) $img);
1149
-		}
1150
-	}
1151
-
1152
-	return $img;
1126
+    // appeler le filtre post_image_filtrer qui permet de faire
1127
+    // des traitements auto a la fin d'une serie de filtres
1128
+    $img = pipeline('post_image_filtrer', $img);
1129
+
1130
+    $fichier_ori = $fichier = (extraire_attribut($img, 'src') ?? '');
1131
+    if (($p = strpos($fichier, '?')) !== false) {
1132
+        $fichier = substr($fichier, 0, $p);
1133
+    }
1134
+    if (strlen($fichier) < 1 && !str_starts_with((string) $img, '<img ')) {
1135
+        $fichier = $img;
1136
+    }
1137
+    if (strlen((string) $fichier)) {
1138
+        # si jamais le fichier final n'a pas ete calcule car suppose temporaire
1139
+        # et qu'il ne s'agit pas d'une URL
1140
+        if (!str_contains((string) $fichier, '://') && !@file_exists($fichier)) {
1141
+            reconstruire_image_intermediaire($fichier);
1142
+        }
1143
+        ramasse_miettes($fichier);
1144
+
1145
+        // ajouter le timestamp si besoin
1146
+        if (!str_contains($fichier_ori, '?')) {
1147
+            // on utilise str_replace pour attraper le onmouseover des logo si besoin
1148
+            $img = str_replace($fichier_ori, timestamp($fichier_ori), (string) $img);
1149
+        }
1150
+    }
1151
+
1152
+    return $img;
1153 1153
 }
1154 1154
 
1155 1155
 /**
@@ -1176,32 +1176,32 @@  discard block
 block discarded – undo
1176 1176
  *     Code html modifié de la balise.
1177 1177
  **/
1178 1178
 function _image_tag_changer_taille($tag, $width, $height, $style = false) {
1179
-	if ($style === false) {
1180
-		$style = extraire_attribut($tag, 'style');
1181
-	}
1182
-
1183
-	// enlever le width et height du style
1184
-	if ($style) {
1185
-		$style = preg_replace(',(^|;)\s*(width|height)\s*:\s*[^;]+,ims', '', $style);
1186
-	}
1187
-	if ($style && $style[0] === ';') {
1188
-		$style = substr($style, 1);
1189
-	}
1190
-
1191
-	// mettre des attributs de width et height sur les images,
1192
-	// ca accelere le rendu du navigateur
1193
-	// ca permet aux navigateurs de reserver la bonne taille
1194
-	// quand on a desactive l'affichage des images.
1195
-	$tag = inserer_attribut($tag, 'width', round($width));
1196
-	$tag = inserer_attribut($tag, 'height', round($height));
1197
-
1198
-	// attributs deprecies. Transformer en CSS
1199
-	if ($espace = extraire_attribut($tag, 'hspace')) {
1200
-		$style = "margin:{$espace}px;" . $style;
1201
-		$tag = inserer_attribut($tag, 'hspace', '');
1202
-	}
1203
-
1204
-	return inserer_attribut($tag, 'style', (string) $style, true, !(bool) $style);
1179
+    if ($style === false) {
1180
+        $style = extraire_attribut($tag, 'style');
1181
+    }
1182
+
1183
+    // enlever le width et height du style
1184
+    if ($style) {
1185
+        $style = preg_replace(',(^|;)\s*(width|height)\s*:\s*[^;]+,ims', '', $style);
1186
+    }
1187
+    if ($style && $style[0] === ';') {
1188
+        $style = substr($style, 1);
1189
+    }
1190
+
1191
+    // mettre des attributs de width et height sur les images,
1192
+    // ca accelere le rendu du navigateur
1193
+    // ca permet aux navigateurs de reserver la bonne taille
1194
+    // quand on a desactive l'affichage des images.
1195
+    $tag = inserer_attribut($tag, 'width', round($width));
1196
+    $tag = inserer_attribut($tag, 'height', round($height));
1197
+
1198
+    // attributs deprecies. Transformer en CSS
1199
+    if ($espace = extraire_attribut($tag, 'hspace')) {
1200
+        $style = "margin:{$espace}px;" . $style;
1201
+        $tag = inserer_attribut($tag, 'hspace', '');
1202
+    }
1203
+
1204
+    return inserer_attribut($tag, 'style', (string) $style, true, !(bool) $style);
1205 1205
 }
1206 1206
 
1207 1207
 
@@ -1227,70 +1227,70 @@  discard block
 block discarded – undo
1227 1227
  *     Retourne le code HTML de l'image
1228 1228
  **/
1229 1229
 function _image_ecrire_tag($valeurs, $surcharge = []) {
1230
-	$valeurs = pipeline('image_ecrire_tag_preparer', $valeurs);
1231
-
1232
-	// fermer les tags img pas bien fermes;
1233
-	$tag = str_replace('>', '/>', str_replace('/>', '>', (string) $valeurs['tag']));
1234
-
1235
-	// le style
1236
-	$style = $valeurs['style'];
1237
-	if (isset($surcharge['style'])) {
1238
-		$style = $surcharge['style'];
1239
-		unset($surcharge['style']);
1240
-	}
1241
-
1242
-	// traiter specifiquement la largeur et la hauteur
1243
-	$width = $valeurs['largeur'];
1244
-	if (isset($surcharge['width'])) {
1245
-		$width = $surcharge['width'];
1246
-		unset($surcharge['width']);
1247
-	}
1248
-	$height = $valeurs['hauteur'];
1249
-	if (isset($surcharge['height'])) {
1250
-		$height = $surcharge['height'];
1251
-		unset($surcharge['height']);
1252
-	}
1253
-
1254
-	$tag = _image_tag_changer_taille($tag, $width, $height, $style);
1255
-	// traiter specifiquement le src qui peut etre repris dans un onmouseout
1256
-	// on remplace toute les ref a src dans le tag
1257
-	$src = extraire_attribut($tag, 'src');
1258
-	if (isset($surcharge['src'])) {
1259
-		$tag = str_replace($src, $surcharge['src'], $tag);
1260
-		// si il y a des & dans src, alors ils peuvent provenir d'un &amp
1261
-		// pas garanti comme methode, mais mieux que rien
1262
-		if (str_contains($src, '&')) {
1263
-			$tag = str_replace(str_replace('&', '&amp;', $src), $surcharge['src'], $tag);
1264
-		}
1265
-		$src = $surcharge['src'];
1266
-		unset($surcharge['src']);
1267
-	}
1268
-
1269
-	$class = $valeurs['class'];
1270
-	if (isset($surcharge['class'])) {
1271
-		$class = $surcharge['class'];
1272
-		unset($surcharge['class']);
1273
-	}
1274
-	if (is_scalar($class) && strlen($class)) {
1275
-		$tag = inserer_attribut($tag, 'class', $class);
1276
-	}
1277
-
1278
-	if ($surcharge !== []) {
1279
-		foreach ($surcharge as $attribut => $valeur) {
1280
-			$tag = inserer_attribut($tag, $attribut, $valeur);
1281
-		}
1282
-	}
1283
-
1284
-	return pipeline(
1285
-		'image_ecrire_tag_finir',
1286
-		[
1287
-			'args' => [
1288
-				'valeurs' => $valeurs,
1289
-				'surcharge' => $surcharge,
1290
-			],
1291
-			'data' => $tag
1292
-		]
1293
-	);
1230
+    $valeurs = pipeline('image_ecrire_tag_preparer', $valeurs);
1231
+
1232
+    // fermer les tags img pas bien fermes;
1233
+    $tag = str_replace('>', '/>', str_replace('/>', '>', (string) $valeurs['tag']));
1234
+
1235
+    // le style
1236
+    $style = $valeurs['style'];
1237
+    if (isset($surcharge['style'])) {
1238
+        $style = $surcharge['style'];
1239
+        unset($surcharge['style']);
1240
+    }
1241
+
1242
+    // traiter specifiquement la largeur et la hauteur
1243
+    $width = $valeurs['largeur'];
1244
+    if (isset($surcharge['width'])) {
1245
+        $width = $surcharge['width'];
1246
+        unset($surcharge['width']);
1247
+    }
1248
+    $height = $valeurs['hauteur'];
1249
+    if (isset($surcharge['height'])) {
1250
+        $height = $surcharge['height'];
1251
+        unset($surcharge['height']);
1252
+    }
1253
+
1254
+    $tag = _image_tag_changer_taille($tag, $width, $height, $style);
1255
+    // traiter specifiquement le src qui peut etre repris dans un onmouseout
1256
+    // on remplace toute les ref a src dans le tag
1257
+    $src = extraire_attribut($tag, 'src');
1258
+    if (isset($surcharge['src'])) {
1259
+        $tag = str_replace($src, $surcharge['src'], $tag);
1260
+        // si il y a des & dans src, alors ils peuvent provenir d'un &amp
1261
+        // pas garanti comme methode, mais mieux que rien
1262
+        if (str_contains($src, '&')) {
1263
+            $tag = str_replace(str_replace('&', '&amp;', $src), $surcharge['src'], $tag);
1264
+        }
1265
+        $src = $surcharge['src'];
1266
+        unset($surcharge['src']);
1267
+    }
1268
+
1269
+    $class = $valeurs['class'];
1270
+    if (isset($surcharge['class'])) {
1271
+        $class = $surcharge['class'];
1272
+        unset($surcharge['class']);
1273
+    }
1274
+    if (is_scalar($class) && strlen($class)) {
1275
+        $tag = inserer_attribut($tag, 'class', $class);
1276
+    }
1277
+
1278
+    if ($surcharge !== []) {
1279
+        foreach ($surcharge as $attribut => $valeur) {
1280
+            $tag = inserer_attribut($tag, $attribut, $valeur);
1281
+        }
1282
+    }
1283
+
1284
+    return pipeline(
1285
+        'image_ecrire_tag_finir',
1286
+        [
1287
+            'args' => [
1288
+                'valeurs' => $valeurs,
1289
+                'surcharge' => $surcharge,
1290
+            ],
1291
+            'data' => $tag
1292
+        ]
1293
+    );
1294 1294
 }
1295 1295
 
1296 1296
 /**
@@ -1313,268 +1313,268 @@  discard block
 block discarded – undo
1313 1313
  *     Description de l'image, sinon null.
1314 1314
  **/
1315 1315
 function _image_creer_vignette($valeurs, $maxWidth, $maxHeight, $process = 'AUTO', $force = false) {
1316
-	$srcHeight = null;
1317
-	$retour = [];
1318
-	// ordre de preference des formats graphiques pour creer les vignettes
1319
-	// le premier format disponible, selon la methode demandee, est utilise
1320
-	$image = $valeurs['fichier'];
1321
-	$format = $valeurs['format_source'];
1322
-	$destdir = dirname((string) $valeurs['fichier_dest']);
1323
-	$destfile = basename((string) $valeurs['fichier_dest'], '.' . $valeurs['format_dest']);
1324
-
1325
-	$format_sortie = $valeurs['format_dest'];
1326
-
1327
-	if ($process == 'AUTO' && isset($GLOBALS['meta']['image_process'])) {
1328
-		$process = $GLOBALS['meta']['image_process'];
1329
-	}
1330
-
1331
-	// si le doc n'est pas une image dans un format accetpable, refuser
1332
-	if (!$force && !in_array($format, formats_image_acceptables($process === 'gd2'))) {
1333
-		return;
1334
-	}
1335
-	$destination = "$destdir/$destfile";
1336
-
1337
-	// calculer la taille
1338
-	if (($srcWidth = $valeurs['largeur']) && ($srcHeight = $valeurs['hauteur'])) {
1339
-		if (!($destWidth = $valeurs['largeur_dest']) || !($destHeight = $valeurs['hauteur_dest'])) {
1340
-			[$destWidth, $destHeight] = _image_ratio($srcWidth, $srcHeight, $maxWidth, $maxHeight);
1341
-		}
1342
-	} elseif ($process == 'convert' || $process == 'imagick') {
1343
-		$destWidth = $maxWidth;
1344
-		$destHeight = $maxHeight;
1345
-	} else {
1346
-		spip_log("echec $process sur $image");
1347
-
1348
-		return;
1349
-	}
1350
-
1351
-	$vignette = '';
1352
-
1353
-	// Si l'image est de la taille demandee (ou plus petite), simplement la retourner
1354
-	if ($srcWidth && $srcWidth <= $maxWidth && $srcHeight <= $maxHeight) {
1355
-		$vignette = $destination . '.' . $format;
1356
-		@copy($image, $vignette);
1357
-	}
1358
-
1359
-	elseif ($valeurs['format_source'] === 'svg') {
1360
-		include_spip('inc/svg');
1361
-		if ($svg = svg_redimensionner($valeurs['fichier'], $destWidth, $destHeight)) {
1362
-			$format_sortie = 'svg';
1363
-			$vignette = $destination . '.' . $format_sortie;
1364
-			$valeurs['fichier_dest'] = $vignette;
1365
-			_image_gd_output($svg, $valeurs);
1366
-		}
1367
-	}
1368
-
1369
-	// imagemagick en ligne de commande
1370
-	elseif ($process == 'convert') {
1371
-		if (!defined('_CONVERT_COMMAND')) {
1372
-			define('_CONVERT_COMMAND', 'convert');
1373
-		} // Securite : mes_options.php peut preciser le chemin absolu
1374
-		if (!defined('_RESIZE_COMMAND')) {
1375
-			define('_RESIZE_COMMAND', _CONVERT_COMMAND . ' -quality ' . _IMG_CONVERT_QUALITE . ' -orient Undefined -resize %xx%y! %src %dest');
1376
-		}
1377
-		$vignette = $destination . '.' . $format_sortie;
1378
-		$commande = str_replace(
1379
-			['%x', '%y', '%src', '%dest'],
1380
-			[
1381
-				$destWidth,
1382
-				$destHeight,
1383
-				escapeshellcmd($image),
1384
-				escapeshellcmd($vignette)
1385
-			],
1386
-			(string) _RESIZE_COMMAND
1387
-		);
1388
-		spip_log($commande);
1389
-		exec($commande);
1390
-		if (!@file_exists($vignette)) {
1391
-			spip_log("echec convert sur $vignette");
1392
-
1393
-			return;  // echec commande
1394
-		}
1395
-	}
1396
-
1397
-	// php5 imagemagick
1398
-	elseif ($process == 'imagick') {
1399
-		if (!class_exists(\Imagick::class)) {
1400
-			spip_log('Classe Imagick absente !', _LOG_ERREUR);
1401
-
1402
-			return;
1403
-		}
1404
-
1405
-		// chemin compatible Windows
1406
-		$output = realpath(dirname($destination));
1407
-		if (!$output) {
1408
-			return;
1409
-		}
1410
-		$vignette = $output . DIRECTORY_SEPARATOR . basename($destination) . '.' . $format_sortie;
1411
-
1412
-		$imagick = new Imagick();
1413
-		$imagick->readImage(realpath($image));
1414
-		$imagick->resizeImage(
1415
-			$destWidth,
1416
-			$destHeight,
1417
-			Imagick::FILTER_LANCZOS,
1418
-			1
1419
-		);//, IMAGICK_FILTER_LANCZOS, _IMG_IMAGICK_QUALITE / 100);
1420
-		$imagick->writeImage($vignette);
1421
-
1422
-		if (!@file_exists($vignette)) {
1423
-			spip_log("echec imagick sur $vignette");
1424
-
1425
-			return;
1426
-		}
1427
-		// remettre le chemin relatif car c'est ce qu'attend SPIP pour la suite (en particlier action/tester)
1428
-		$vignette = $destination . '.' . $format_sortie;
1429
-	}
1430
-
1431
-	// netpbm
1432
-	elseif ($process == 'netpbm') {
1433
-		if (!defined('_PNMSCALE_COMMAND')) {
1434
-			define('_PNMSCALE_COMMAND', 'pnmscale');
1435
-		} // Securite : mes_options.php peut preciser le chemin absolu
1436
-		if (_PNMSCALE_COMMAND == '') {
1437
-			return;
1438
-		}
1439
-		$vignette = $destination . '.' . $format_sortie;
1440
-		$pnmtojpeg_command = str_replace('pnmscale', 'pnmtojpeg', (string) _PNMSCALE_COMMAND);
1441
-		if ($format == 'jpg') {
1442
-			$jpegtopnm_command = str_replace('pnmscale', 'jpegtopnm', (string) _PNMSCALE_COMMAND);
1443
-			exec("$jpegtopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1444
-			if (!($s = @filesize($vignette))) {
1445
-				spip_unlink($vignette);
1446
-			}
1447
-			if (!@file_exists($vignette)) {
1448
-				spip_log("echec netpbm-jpg sur $vignette");
1449
-
1450
-				return;
1451
-			}
1452
-		} else {
1453
-			if ($format == 'gif') {
1454
-				$giftopnm_command = str_replace('pnmscale', 'giftopnm', (string) _PNMSCALE_COMMAND);
1455
-				exec("$giftopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1456
-				if (!($s = @filesize($vignette))) {
1457
-					spip_unlink($vignette);
1458
-				}
1459
-				if (!@file_exists($vignette)) {
1460
-					spip_log("echec netpbm-gif sur $vignette");
1461
-
1462
-					return;
1463
-				}
1464
-			} else {
1465
-				if ($format == 'png') {
1466
-					$pngtopnm_command = str_replace('pnmscale', 'pngtopnm', (string) _PNMSCALE_COMMAND);
1467
-					exec("$pngtopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1468
-					if (!($s = @filesize($vignette))) {
1469
-						spip_unlink($vignette);
1470
-					}
1471
-					if (!@file_exists($vignette)) {
1472
-						spip_log("echec netpbm-png sur $vignette");
1473
-
1474
-						return;
1475
-					}
1476
-				}
1477
-			}
1478
-		}
1479
-	}
1480
-
1481
-	// gd ou gd2
1482
-	elseif ($process === 'gd2') {
1483
-		if (!function_exists('gd_info')) {
1484
-			spip_log('Librairie GD absente !', _LOG_ERREUR);
1485
-
1486
-			return;
1487
-		}
1488
-		if (_IMG_GD_MAX_PIXELS && $srcWidth * $srcHeight > _IMG_GD_MAX_PIXELS) {
1489
-			spip_log('vignette gd2 impossible : ' . $srcWidth * $srcHeight . 'pixels');
1490
-
1491
-			return;
1492
-		}
1493
-		$destFormat = $format_sortie;
1494
-		if (!$destFormat) {
1495
-			spip_log("pas de format pour $image");
1496
-
1497
-			return;
1498
-		}
1499
-
1500
-		$fonction_imagecreatefrom = $valeurs['fonction_imagecreatefrom'];
1501
-		if (!function_exists($fonction_imagecreatefrom)) {
1502
-			return;
1503
-		}
1504
-		$srcImage = @$fonction_imagecreatefrom($image);
1505
-		if (!$srcImage) {
1506
-			spip_log('echec gd2');
1507
-
1508
-			return;
1509
-		}
1510
-
1511
-		// Initialisation de l'image destination
1512
-		$destImage = null;
1513
-		if ($process == 'gd2' && $destFormat != 'gif') {
1514
-			$destImage = ImageCreateTrueColor($destWidth, $destHeight);
1515
-		}
1516
-		if (!$destImage) {
1517
-			$destImage = ImageCreate($destWidth, $destHeight);
1518
-		}
1519
-
1520
-		// Recopie de l'image d'origine avec adaptation de la taille
1521
-		$ok = false;
1522
-		if ($process == 'gd2' && function_exists('ImageCopyResampled')) {
1523
-			if ($format == 'gif') {
1524
-				// Si un GIF est transparent,
1525
-				// fabriquer un PNG transparent
1526
-				$transp = imagecolortransparent($srcImage);
1527
-				if ($transp > 0) {
1528
-					$destFormat = 'png';
1529
-				}
1530
-			}
1531
-			if (in_array($destFormat, _image_extensions_conservent_transparence())) {
1532
-				// Conserver la transparence
1533
-				if (function_exists('imageAntiAlias')) {
1534
-					imageAntiAlias($destImage, true);
1535
-				}
1536
-				@imagealphablending($destImage, false);
1537
-				@imagesavealpha($destImage, true);
1538
-			}
1539
-			$ok = @ImageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
1540
-		}
1541
-		if (!$ok) {
1542
-			$ok = ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
1543
-		}
1544
-
1545
-		// Sauvegarde de l'image destination
1546
-		$valeurs['fichier_dest'] = $vignette = "$destination.$destFormat";
1547
-		$valeurs['format_dest'] = $format = $destFormat;
1548
-		_image_gd_output($destImage, $valeurs);
1549
-
1550
-		if ($srcImage) {
1551
-			ImageDestroy($srcImage);
1552
-		}
1553
-		ImageDestroy($destImage);
1554
-	}
1555
-
1556
-	if (!$vignette || !$size = @spip_getimagesize($vignette)) {
1557
-		$size = [$destWidth, $destHeight];
1558
-	}
1559
-
1560
-	// Gaffe: en safe mode, pas d'acces a la vignette,
1561
-	// donc risque de balancer "width='0'", ce qui masque l'image sous MSIE
1562
-	if ($size[0] < 1) {
1563
-		$size[0] = $destWidth;
1564
-	}
1565
-	if ($size[1] < 1) {
1566
-		$size[1] = $destHeight;
1567
-	}
1568
-
1569
-	$retour['width'] = $largeur = $size[0];
1570
-	$retour['height'] = $hauteur = $size[1];
1571
-
1572
-	$retour['fichier'] = $vignette;
1573
-	$retour['format'] = $format;
1574
-	$retour['date'] = @filemtime($vignette);
1575
-
1576
-	// renvoyer l'image
1577
-	return $retour;
1316
+    $srcHeight = null;
1317
+    $retour = [];
1318
+    // ordre de preference des formats graphiques pour creer les vignettes
1319
+    // le premier format disponible, selon la methode demandee, est utilise
1320
+    $image = $valeurs['fichier'];
1321
+    $format = $valeurs['format_source'];
1322
+    $destdir = dirname((string) $valeurs['fichier_dest']);
1323
+    $destfile = basename((string) $valeurs['fichier_dest'], '.' . $valeurs['format_dest']);
1324
+
1325
+    $format_sortie = $valeurs['format_dest'];
1326
+
1327
+    if ($process == 'AUTO' && isset($GLOBALS['meta']['image_process'])) {
1328
+        $process = $GLOBALS['meta']['image_process'];
1329
+    }
1330
+
1331
+    // si le doc n'est pas une image dans un format accetpable, refuser
1332
+    if (!$force && !in_array($format, formats_image_acceptables($process === 'gd2'))) {
1333
+        return;
1334
+    }
1335
+    $destination = "$destdir/$destfile";
1336
+
1337
+    // calculer la taille
1338
+    if (($srcWidth = $valeurs['largeur']) && ($srcHeight = $valeurs['hauteur'])) {
1339
+        if (!($destWidth = $valeurs['largeur_dest']) || !($destHeight = $valeurs['hauteur_dest'])) {
1340
+            [$destWidth, $destHeight] = _image_ratio($srcWidth, $srcHeight, $maxWidth, $maxHeight);
1341
+        }
1342
+    } elseif ($process == 'convert' || $process == 'imagick') {
1343
+        $destWidth = $maxWidth;
1344
+        $destHeight = $maxHeight;
1345
+    } else {
1346
+        spip_log("echec $process sur $image");
1347
+
1348
+        return;
1349
+    }
1350
+
1351
+    $vignette = '';
1352
+
1353
+    // Si l'image est de la taille demandee (ou plus petite), simplement la retourner
1354
+    if ($srcWidth && $srcWidth <= $maxWidth && $srcHeight <= $maxHeight) {
1355
+        $vignette = $destination . '.' . $format;
1356
+        @copy($image, $vignette);
1357
+    }
1358
+
1359
+    elseif ($valeurs['format_source'] === 'svg') {
1360
+        include_spip('inc/svg');
1361
+        if ($svg = svg_redimensionner($valeurs['fichier'], $destWidth, $destHeight)) {
1362
+            $format_sortie = 'svg';
1363
+            $vignette = $destination . '.' . $format_sortie;
1364
+            $valeurs['fichier_dest'] = $vignette;
1365
+            _image_gd_output($svg, $valeurs);
1366
+        }
1367
+    }
1368
+
1369
+    // imagemagick en ligne de commande
1370
+    elseif ($process == 'convert') {
1371
+        if (!defined('_CONVERT_COMMAND')) {
1372
+            define('_CONVERT_COMMAND', 'convert');
1373
+        } // Securite : mes_options.php peut preciser le chemin absolu
1374
+        if (!defined('_RESIZE_COMMAND')) {
1375
+            define('_RESIZE_COMMAND', _CONVERT_COMMAND . ' -quality ' . _IMG_CONVERT_QUALITE . ' -orient Undefined -resize %xx%y! %src %dest');
1376
+        }
1377
+        $vignette = $destination . '.' . $format_sortie;
1378
+        $commande = str_replace(
1379
+            ['%x', '%y', '%src', '%dest'],
1380
+            [
1381
+                $destWidth,
1382
+                $destHeight,
1383
+                escapeshellcmd($image),
1384
+                escapeshellcmd($vignette)
1385
+            ],
1386
+            (string) _RESIZE_COMMAND
1387
+        );
1388
+        spip_log($commande);
1389
+        exec($commande);
1390
+        if (!@file_exists($vignette)) {
1391
+            spip_log("echec convert sur $vignette");
1392
+
1393
+            return;  // echec commande
1394
+        }
1395
+    }
1396
+
1397
+    // php5 imagemagick
1398
+    elseif ($process == 'imagick') {
1399
+        if (!class_exists(\Imagick::class)) {
1400
+            spip_log('Classe Imagick absente !', _LOG_ERREUR);
1401
+
1402
+            return;
1403
+        }
1404
+
1405
+        // chemin compatible Windows
1406
+        $output = realpath(dirname($destination));
1407
+        if (!$output) {
1408
+            return;
1409
+        }
1410
+        $vignette = $output . DIRECTORY_SEPARATOR . basename($destination) . '.' . $format_sortie;
1411
+
1412
+        $imagick = new Imagick();
1413
+        $imagick->readImage(realpath($image));
1414
+        $imagick->resizeImage(
1415
+            $destWidth,
1416
+            $destHeight,
1417
+            Imagick::FILTER_LANCZOS,
1418
+            1
1419
+        );//, IMAGICK_FILTER_LANCZOS, _IMG_IMAGICK_QUALITE / 100);
1420
+        $imagick->writeImage($vignette);
1421
+
1422
+        if (!@file_exists($vignette)) {
1423
+            spip_log("echec imagick sur $vignette");
1424
+
1425
+            return;
1426
+        }
1427
+        // remettre le chemin relatif car c'est ce qu'attend SPIP pour la suite (en particlier action/tester)
1428
+        $vignette = $destination . '.' . $format_sortie;
1429
+    }
1430
+
1431
+    // netpbm
1432
+    elseif ($process == 'netpbm') {
1433
+        if (!defined('_PNMSCALE_COMMAND')) {
1434
+            define('_PNMSCALE_COMMAND', 'pnmscale');
1435
+        } // Securite : mes_options.php peut preciser le chemin absolu
1436
+        if (_PNMSCALE_COMMAND == '') {
1437
+            return;
1438
+        }
1439
+        $vignette = $destination . '.' . $format_sortie;
1440
+        $pnmtojpeg_command = str_replace('pnmscale', 'pnmtojpeg', (string) _PNMSCALE_COMMAND);
1441
+        if ($format == 'jpg') {
1442
+            $jpegtopnm_command = str_replace('pnmscale', 'jpegtopnm', (string) _PNMSCALE_COMMAND);
1443
+            exec("$jpegtopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1444
+            if (!($s = @filesize($vignette))) {
1445
+                spip_unlink($vignette);
1446
+            }
1447
+            if (!@file_exists($vignette)) {
1448
+                spip_log("echec netpbm-jpg sur $vignette");
1449
+
1450
+                return;
1451
+            }
1452
+        } else {
1453
+            if ($format == 'gif') {
1454
+                $giftopnm_command = str_replace('pnmscale', 'giftopnm', (string) _PNMSCALE_COMMAND);
1455
+                exec("$giftopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1456
+                if (!($s = @filesize($vignette))) {
1457
+                    spip_unlink($vignette);
1458
+                }
1459
+                if (!@file_exists($vignette)) {
1460
+                    spip_log("echec netpbm-gif sur $vignette");
1461
+
1462
+                    return;
1463
+                }
1464
+            } else {
1465
+                if ($format == 'png') {
1466
+                    $pngtopnm_command = str_replace('pnmscale', 'pngtopnm', (string) _PNMSCALE_COMMAND);
1467
+                    exec("$pngtopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1468
+                    if (!($s = @filesize($vignette))) {
1469
+                        spip_unlink($vignette);
1470
+                    }
1471
+                    if (!@file_exists($vignette)) {
1472
+                        spip_log("echec netpbm-png sur $vignette");
1473
+
1474
+                        return;
1475
+                    }
1476
+                }
1477
+            }
1478
+        }
1479
+    }
1480
+
1481
+    // gd ou gd2
1482
+    elseif ($process === 'gd2') {
1483
+        if (!function_exists('gd_info')) {
1484
+            spip_log('Librairie GD absente !', _LOG_ERREUR);
1485
+
1486
+            return;
1487
+        }
1488
+        if (_IMG_GD_MAX_PIXELS && $srcWidth * $srcHeight > _IMG_GD_MAX_PIXELS) {
1489
+            spip_log('vignette gd2 impossible : ' . $srcWidth * $srcHeight . 'pixels');
1490
+
1491
+            return;
1492
+        }
1493
+        $destFormat = $format_sortie;
1494
+        if (!$destFormat) {
1495
+            spip_log("pas de format pour $image");
1496
+
1497
+            return;
1498
+        }
1499
+
1500
+        $fonction_imagecreatefrom = $valeurs['fonction_imagecreatefrom'];
1501
+        if (!function_exists($fonction_imagecreatefrom)) {
1502
+            return;
1503
+        }
1504
+        $srcImage = @$fonction_imagecreatefrom($image);
1505
+        if (!$srcImage) {
1506
+            spip_log('echec gd2');
1507
+
1508
+            return;
1509
+        }
1510
+
1511
+        // Initialisation de l'image destination
1512
+        $destImage = null;
1513
+        if ($process == 'gd2' && $destFormat != 'gif') {
1514
+            $destImage = ImageCreateTrueColor($destWidth, $destHeight);
1515
+        }
1516
+        if (!$destImage) {
1517
+            $destImage = ImageCreate($destWidth, $destHeight);
1518
+        }
1519
+
1520
+        // Recopie de l'image d'origine avec adaptation de la taille
1521
+        $ok = false;
1522
+        if ($process == 'gd2' && function_exists('ImageCopyResampled')) {
1523
+            if ($format == 'gif') {
1524
+                // Si un GIF est transparent,
1525
+                // fabriquer un PNG transparent
1526
+                $transp = imagecolortransparent($srcImage);
1527
+                if ($transp > 0) {
1528
+                    $destFormat = 'png';
1529
+                }
1530
+            }
1531
+            if (in_array($destFormat, _image_extensions_conservent_transparence())) {
1532
+                // Conserver la transparence
1533
+                if (function_exists('imageAntiAlias')) {
1534
+                    imageAntiAlias($destImage, true);
1535
+                }
1536
+                @imagealphablending($destImage, false);
1537
+                @imagesavealpha($destImage, true);
1538
+            }
1539
+            $ok = @ImageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
1540
+        }
1541
+        if (!$ok) {
1542
+            $ok = ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
1543
+        }
1544
+
1545
+        // Sauvegarde de l'image destination
1546
+        $valeurs['fichier_dest'] = $vignette = "$destination.$destFormat";
1547
+        $valeurs['format_dest'] = $format = $destFormat;
1548
+        _image_gd_output($destImage, $valeurs);
1549
+
1550
+        if ($srcImage) {
1551
+            ImageDestroy($srcImage);
1552
+        }
1553
+        ImageDestroy($destImage);
1554
+    }
1555
+
1556
+    if (!$vignette || !$size = @spip_getimagesize($vignette)) {
1557
+        $size = [$destWidth, $destHeight];
1558
+    }
1559
+
1560
+    // Gaffe: en safe mode, pas d'acces a la vignette,
1561
+    // donc risque de balancer "width='0'", ce qui masque l'image sous MSIE
1562
+    if ($size[0] < 1) {
1563
+        $size[0] = $destWidth;
1564
+    }
1565
+    if ($size[1] < 1) {
1566
+        $size[1] = $destHeight;
1567
+    }
1568
+
1569
+    $retour['width'] = $largeur = $size[0];
1570
+    $retour['height'] = $hauteur = $size[1];
1571
+
1572
+    $retour['fichier'] = $vignette;
1573
+    $retour['format'] = $format;
1574
+    $retour['date'] = @filemtime($vignette);
1575
+
1576
+    // renvoyer l'image
1577
+    return $retour;
1578 1578
 }
1579 1579
 
1580 1580
 /**
@@ -1594,25 +1594,25 @@  discard block
 block discarded – undo
1594 1594
  * @return array Liste [ largeur, hauteur, ratio de réduction ]
1595 1595
  **/
1596 1596
 function _image_ratio(int $srcWidth, int $srcHeight, int $maxWidth, int $maxHeight): array {
1597
-	$ratioWidth = $srcWidth / $maxWidth;
1598
-	$ratioHeight = $srcHeight / $maxHeight;
1599
-
1600
-	if ($srcWidth <= $maxWidth && $srcHeight <= $maxHeight) {
1601
-		$destWidth = $srcWidth;
1602
-		$destHeight = $srcHeight;
1603
-	} elseif ($ratioWidth < $ratioHeight) {
1604
-		$destWidth = $srcWidth / $ratioHeight;
1605
-		$destHeight = $maxHeight;
1606
-	} else {
1607
-		$destWidth = $maxWidth;
1608
-		$destHeight = $srcHeight / $ratioWidth;
1609
-	}
1610
-
1611
-	return [
1612
-		(int) round($destWidth),
1613
-		(int) round($destHeight),
1614
-		max($ratioWidth, $ratioHeight)
1615
-	];
1597
+    $ratioWidth = $srcWidth / $maxWidth;
1598
+    $ratioHeight = $srcHeight / $maxHeight;
1599
+
1600
+    if ($srcWidth <= $maxWidth && $srcHeight <= $maxHeight) {
1601
+        $destWidth = $srcWidth;
1602
+        $destHeight = $srcHeight;
1603
+    } elseif ($ratioWidth < $ratioHeight) {
1604
+        $destWidth = $srcWidth / $ratioHeight;
1605
+        $destHeight = $maxHeight;
1606
+    } else {
1607
+        $destWidth = $maxWidth;
1608
+        $destHeight = $srcHeight / $ratioWidth;
1609
+    }
1610
+
1611
+    return [
1612
+        (int) round($destWidth),
1613
+        (int) round($destHeight),
1614
+        max($ratioWidth, $ratioHeight)
1615
+    ];
1616 1616
 }
1617 1617
 
1618 1618
 /**
@@ -1632,25 +1632,25 @@  discard block
 block discarded – undo
1632 1632
  * @return array Liste [ largeur, hauteur, ratio de réduction ]
1633 1633
  **/
1634 1634
 function ratio_passe_partout(int $srcWidth, int $srcHeight, int $maxWidth, int $maxHeight): array {
1635
-	$ratioWidth = $srcWidth / $maxWidth;
1636
-	$ratioHeight = $srcHeight / $maxHeight;
1637
-
1638
-	if ($srcWidth <= $maxWidth && $srcHeight <= $maxHeight) {
1639
-		$destWidth = $srcWidth;
1640
-		$destHeight = $srcHeight;
1641
-	} elseif ($ratioWidth > $ratioHeight) {
1642
-		$destWidth = $srcWidth / $ratioHeight;
1643
-		$destHeight = $maxHeight;
1644
-	} else {
1645
-		$destWidth = $maxWidth;
1646
-		$destHeight = $srcHeight / $ratioWidth;
1647
-	}
1648
-
1649
-	return [
1650
-		(int) round($destWidth),
1651
-		(int) round($destHeight),
1652
-		min($ratioWidth, $ratioHeight)
1653
-	];
1635
+    $ratioWidth = $srcWidth / $maxWidth;
1636
+    $ratioHeight = $srcHeight / $maxHeight;
1637
+
1638
+    if ($srcWidth <= $maxWidth && $srcHeight <= $maxHeight) {
1639
+        $destWidth = $srcWidth;
1640
+        $destHeight = $srcHeight;
1641
+    } elseif ($ratioWidth > $ratioHeight) {
1642
+        $destWidth = $srcWidth / $ratioHeight;
1643
+        $destHeight = $maxHeight;
1644
+    } else {
1645
+        $destWidth = $maxWidth;
1646
+        $destHeight = $srcHeight / $ratioWidth;
1647
+    }
1648
+
1649
+    return [
1650
+        (int) round($destWidth),
1651
+        (int) round($destHeight),
1652
+        min($ratioWidth, $ratioHeight)
1653
+    ];
1654 1654
 }
1655 1655
 
1656 1656
 
@@ -1663,12 +1663,12 @@  discard block
 block discarded – undo
1663 1663
  * @return string
1664 1664
  */
1665 1665
 function process_image_svg_identite($image) {
1666
-	if ($image['creer']) {
1667
-		$source = $image['fichier'];
1668
-		_image_gd_output($source, $image);
1669
-	}
1666
+    if ($image['creer']) {
1667
+        $source = $image['fichier'];
1668
+        _image_gd_output($source, $image);
1669
+    }
1670 1670
 
1671
-	return _image_ecrire_tag($image, ['src' => $image['fichier_dest']]);
1671
+    return _image_ecrire_tag($image, ['src' => $image['fichier_dest']]);
1672 1672
 }
1673 1673
 
1674 1674
 
@@ -1701,102 +1701,102 @@  discard block
 block discarded – undo
1701 1701
  *     Code HTML de la balise img produite
1702 1702
  **/
1703 1703
 function process_image_reduire($fonction, $img, $taille, $taille_y, $force, $process = 'AUTO') {
1704
-	$image = false;
1705
-	if ($process == 'AUTO' && isset($GLOBALS['meta']['image_process'])) {
1706
-		$process = $GLOBALS['meta']['image_process'];
1707
-	}
1708
-	# determiner le format de sortie
1709
-	$format_sortie = false; // le choix par defaut sera bon
1710
-	if ($process === 'netpbm') {
1711
-		$format_sortie = 'jpg';
1712
-	} elseif ($process === 'gd2') {
1713
-		$image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}", $format_sortie, $fonction, false, _SVG_SUPPORTED);
1714
-		// on verifie que l'extension choisie est bonne (en principe oui)
1715
-		$gd_formats = formats_image_acceptables(true);
1716
-		if (
1717
-			is_array($image)
1718
-			&& (!in_array($image['format_dest'], $gd_formats) || !in_array($image['format_dest'], _image_extensions_acceptees_en_sortie()))
1719
-		) {
1720
-			$formats_sortie = $image['format_source'] == 'jpg' ? ['jpg', 'png', 'gif'] : ['png', 'jpg', 'gif'];
1721
-			// Choisir le format destination
1722
-			// - on sauve de preference en JPEG (meilleure compression)
1723
-			// - pour le GIF : les GD recentes peuvent le lire mais pas l'ecrire
1724
-			# bug : gd_formats contient la liste des fichiers qu'on sait *lire*,
1725
-			# pas *ecrire*
1726
-			$format_sortie = '';
1727
-			foreach ($formats_sortie as $fmt) {
1728
-				if (in_array($fmt, $gd_formats) && in_array($fmt, _image_extensions_acceptees_en_sortie())) {
1729
-					$format_sortie = $fmt;
1730
-					break;
1731
-				}
1732
-			}
1733
-			$image = false;
1734
-		}
1735
-	}
1736
-
1737
-	if (!is_array($image)) {
1738
-		$image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}", $format_sortie, $fonction, false, _SVG_SUPPORTED);
1739
-	}
1740
-
1741
-	if (!is_array($image) || !$image['largeur'] || !$image['hauteur']) {
1742
-		spip_log("image_reduire_src:pas de version locale de $img ou extension non prise en charge");
1743
-		// on peut resizer en mode html si on dispose des elements
1744
-		[$srcw, $srch] = taille_image($img);
1745
-		if ($srcw && $srch) {
1746
-			[$w, $h] = _image_ratio($srcw, $srch, $taille, $taille_y);
1747
-
1748
-			return _image_tag_changer_taille($img, $w, $h);
1749
-		}
1750
-		// la on n'a pas d'infos sur l'image source... on refile le truc a css
1751
-		// sous la forme style='max-width: NNpx;'
1752
-		return inserer_attribut(
1753
-			$img,
1754
-			'style',
1755
-			"max-width: {$taille}px;max-width: min(100%,{$taille}px); max-height: {$taille_y}px"
1756
-		);
1757
-	}
1758
-
1759
-	// si l'image est plus petite que la cible retourner une copie cachee de l'image
1760
-	if (($image['largeur'] <= $taille) && ($image['hauteur'] <= $taille_y)) {
1761
-		if ($image['creer']) {
1762
-			@copy($image['fichier'], $image['fichier_dest']);
1763
-		}
1764
-
1765
-		return _image_ecrire_tag($image, ['src' => $image['fichier_dest']]);
1766
-	}
1767
-
1768
-	if ($image['creer'] == false && !$force) {
1769
-		return _image_ecrire_tag(
1770
-			$image,
1771
-			['src' => $image['fichier_dest'], 'width' => $image['largeur_dest'], 'height' => $image['hauteur_dest']]
1772
-		);
1773
-	}
1774
-
1775
-	if (in_array($image['format_source'], _image_extensions_acceptees_en_entree())) {
1776
-		$destWidth = $image['largeur_dest'];
1777
-		$destHeight = $image['hauteur_dest'];
1778
-		$logo = $image['fichier'];
1779
-		$date = $image['date_src'];
1780
-		$preview = _image_creer_vignette($image, $taille, $taille_y, $process, $force);
1781
-
1782
-		if ($preview && $preview['fichier']) {
1783
-			$logo = $preview['fichier'];
1784
-			$destWidth = $preview['width'];
1785
-			$destHeight = $preview['height'];
1786
-			$date = $preview['date'];
1787
-		}
1788
-		// dans l'espace prive mettre un timestamp sur l'adresse
1789
-		// de l'image, de facon a tromper le cache du navigateur
1790
-		// quand on fait supprimer/reuploader un logo
1791
-		// (pas de filemtime si SAFE MODE)
1792
-		$date = test_espace_prive() ? ('?' . $date) : '';
1793
-
1794
-		return _image_ecrire_tag($image, ['src' => "$logo$date", 'width' => $destWidth, 'height' => $destHeight]);
1795
-	}
1796
-	else {
1797
-		# BMP, tiff ... les redacteurs osent tout!
1798
-		return $img;
1799
-	}
1704
+    $image = false;
1705
+    if ($process == 'AUTO' && isset($GLOBALS['meta']['image_process'])) {
1706
+        $process = $GLOBALS['meta']['image_process'];
1707
+    }
1708
+    # determiner le format de sortie
1709
+    $format_sortie = false; // le choix par defaut sera bon
1710
+    if ($process === 'netpbm') {
1711
+        $format_sortie = 'jpg';
1712
+    } elseif ($process === 'gd2') {
1713
+        $image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}", $format_sortie, $fonction, false, _SVG_SUPPORTED);
1714
+        // on verifie que l'extension choisie est bonne (en principe oui)
1715
+        $gd_formats = formats_image_acceptables(true);
1716
+        if (
1717
+            is_array($image)
1718
+            && (!in_array($image['format_dest'], $gd_formats) || !in_array($image['format_dest'], _image_extensions_acceptees_en_sortie()))
1719
+        ) {
1720
+            $formats_sortie = $image['format_source'] == 'jpg' ? ['jpg', 'png', 'gif'] : ['png', 'jpg', 'gif'];
1721
+            // Choisir le format destination
1722
+            // - on sauve de preference en JPEG (meilleure compression)
1723
+            // - pour le GIF : les GD recentes peuvent le lire mais pas l'ecrire
1724
+            # bug : gd_formats contient la liste des fichiers qu'on sait *lire*,
1725
+            # pas *ecrire*
1726
+            $format_sortie = '';
1727
+            foreach ($formats_sortie as $fmt) {
1728
+                if (in_array($fmt, $gd_formats) && in_array($fmt, _image_extensions_acceptees_en_sortie())) {
1729
+                    $format_sortie = $fmt;
1730
+                    break;
1731
+                }
1732
+            }
1733
+            $image = false;
1734
+        }
1735
+    }
1736
+
1737
+    if (!is_array($image)) {
1738
+        $image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}", $format_sortie, $fonction, false, _SVG_SUPPORTED);
1739
+    }
1740
+
1741
+    if (!is_array($image) || !$image['largeur'] || !$image['hauteur']) {
1742
+        spip_log("image_reduire_src:pas de version locale de $img ou extension non prise en charge");
1743
+        // on peut resizer en mode html si on dispose des elements
1744
+        [$srcw, $srch] = taille_image($img);
1745
+        if ($srcw && $srch) {
1746
+            [$w, $h] = _image_ratio($srcw, $srch, $taille, $taille_y);
1747
+
1748
+            return _image_tag_changer_taille($img, $w, $h);
1749
+        }
1750
+        // la on n'a pas d'infos sur l'image source... on refile le truc a css
1751
+        // sous la forme style='max-width: NNpx;'
1752
+        return inserer_attribut(
1753
+            $img,
1754
+            'style',
1755
+            "max-width: {$taille}px;max-width: min(100%,{$taille}px); max-height: {$taille_y}px"
1756
+        );
1757
+    }
1758
+
1759
+    // si l'image est plus petite que la cible retourner une copie cachee de l'image
1760
+    if (($image['largeur'] <= $taille) && ($image['hauteur'] <= $taille_y)) {
1761
+        if ($image['creer']) {
1762
+            @copy($image['fichier'], $image['fichier_dest']);
1763
+        }
1764
+
1765
+        return _image_ecrire_tag($image, ['src' => $image['fichier_dest']]);
1766
+    }
1767
+
1768
+    if ($image['creer'] == false && !$force) {
1769
+        return _image_ecrire_tag(
1770
+            $image,
1771
+            ['src' => $image['fichier_dest'], 'width' => $image['largeur_dest'], 'height' => $image['hauteur_dest']]
1772
+        );
1773
+    }
1774
+
1775
+    if (in_array($image['format_source'], _image_extensions_acceptees_en_entree())) {
1776
+        $destWidth = $image['largeur_dest'];
1777
+        $destHeight = $image['hauteur_dest'];
1778
+        $logo = $image['fichier'];
1779
+        $date = $image['date_src'];
1780
+        $preview = _image_creer_vignette($image, $taille, $taille_y, $process, $force);
1781
+
1782
+        if ($preview && $preview['fichier']) {
1783
+            $logo = $preview['fichier'];
1784
+            $destWidth = $preview['width'];
1785
+            $destHeight = $preview['height'];
1786
+            $date = $preview['date'];
1787
+        }
1788
+        // dans l'espace prive mettre un timestamp sur l'adresse
1789
+        // de l'image, de facon a tromper le cache du navigateur
1790
+        // quand on fait supprimer/reuploader un logo
1791
+        // (pas de filemtime si SAFE MODE)
1792
+        $date = test_espace_prive() ? ('?' . $date) : '';
1793
+
1794
+        return _image_ecrire_tag($image, ['src' => "$logo$date", 'width' => $destWidth, 'height' => $destHeight]);
1795
+    }
1796
+    else {
1797
+        # BMP, tiff ... les redacteurs osent tout!
1798
+        return $img;
1799
+    }
1800 1800
 }
1801 1801
 
1802 1802
 /**
@@ -1810,145 +1810,145 @@  discard block
 block discarded – undo
1810 1810
  * Class phpthumb_functions
1811 1811
  */
1812 1812
 class phpthumb_functions {
1813
-	/**
1814
-	 * Retourne la couleur d'un pixel dans une image
1815
-	 *
1816
-	 * @param GdImage $img
1817
-	 * @param int $x
1818
-	 * @param int $y
1819
-	 * @return array|bool
1820
-	 */
1821
-	public static function GetPixelColor(&$img, $x, $y) {
1822
-		if ($img instanceof \GdImage) {
1823
-			return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));
1824
-		}
1825
-		return false;
1826
-	}
1827
-
1828
-	/**
1829
-	 * Retourne un nombre dans une représentation en Little Endian
1830
-	 *
1831
-	 * @param int $number
1832
-	 * @param int $minbytes
1833
-	 * @return string
1834
-	 */
1835
-	public static function LittleEndian2String($number, $minbytes = 1) {
1836
-		$intstring = '';
1837
-		while ($number > 0) {
1838
-			$intstring .= chr($number & 255);
1839
-			$number >>= 8;
1840
-		}
1841
-
1842
-		return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
1843
-	}
1844
-
1845
-	/**
1846
-	 * Transforme une ressource GD en image au format ICO
1847
-	 *
1848
-	 * @param array $gd_image_array
1849
-	 *     Tableau de ressources d'images GD
1850
-	 * @return string
1851
-	 *     Image au format ICO
1852
-	 */
1853
-	public static function GD2ICOstring(&$gd_image_array) {
1854
-		foreach ($gd_image_array as $key => $gd_image) {
1855
-			$ImageWidths[$key] = ImageSX($gd_image);
1856
-			$ImageHeights[$key] = ImageSY($gd_image);
1857
-			$bpp[$key] = ImageIsTrueColor($gd_image) ? 32 : 24;
1858
-			$totalcolors[$key] = ImageColorsTotal($gd_image);
1859
-
1860
-			$icXOR[$key] = '';
1861
-			for ($y = $ImageHeights[$key] - 1; $y >= 0; $y--) {
1862
-				for ($x = 0; $x < $ImageWidths[$key]; $x++) {
1863
-					$argb = phpthumb_functions::GetPixelColor($gd_image, $x, $y);
1864
-					$a = round(255 * ((127 - $argb['alpha']) / 127));
1865
-					$r = $argb['red'];
1866
-					$g = $argb['green'];
1867
-					$b = $argb['blue'];
1868
-
1869
-					if ($bpp[$key] == 32) {
1870
-						$icXOR[$key] .= chr($b) . chr($g) . chr($r) . chr($a);
1871
-					} elseif ($bpp[$key] === 24) {
1872
-						$icXOR[$key] .= chr($b) . chr($g) . chr($r);
1873
-					}
1874
-
1875
-					if ($a < 128) {
1876
-						@$icANDmask[$key][$y] .= '1';
1877
-					} else {
1878
-						@$icANDmask[$key][$y] .= '0';
1879
-					}
1880
-				}
1881
-				// mask bits are 32-bit aligned per scanline
1882
-				while (strlen($icANDmask[$key][$y]) % 32) {
1883
-					$icANDmask[$key][$y] .= '0';
1884
-				}
1885
-			}
1886
-			$icAND[$key] = '';
1887
-			foreach ($icANDmask[$key] as $y => $scanlinemaskbits) {
1888
-				for ($i = 0; $i < strlen($scanlinemaskbits); $i += 8) {
1889
-					$icAND[$key] .= chr(bindec(str_pad(substr($scanlinemaskbits, $i, 8), 8, '0', STR_PAD_LEFT)));
1890
-				}
1891
-			}
1892
-		}
1893
-
1894
-		foreach (array_keys($gd_image_array) as $key) {
1895
-			$biSizeImage = $ImageWidths[$key] * $ImageHeights[$key] * ($bpp[$key] / 8);
1896
-
1897
-			// BITMAPINFOHEADER - 40 bytes
1898
-			$BitmapInfoHeader[$key] = '';
1899
-			$BitmapInfoHeader[$key] .= "\x28\x00\x00\x00";                // DWORD  biSize;
1900
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4);    // LONG   biWidth;
1901
-			// The biHeight member specifies the combined
1902
-			// height of the XOR and AND masks.
1903
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG   biHeight;
1904
-			$BitmapInfoHeader[$key] .= "\x01\x00";                    // WORD   biPlanes;
1905
-			$BitmapInfoHeader[$key] .= chr($bpp[$key]) . "\x00";              // wBitCount;
1906
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biCompression;
1907
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4);      // DWORD  biSizeImage;
1908
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // LONG   biXPelsPerMeter;
1909
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // LONG   biYPelsPerMeter;
1910
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biClrUsed;
1911
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biClrImportant;
1912
-		}
1913
-
1914
-
1915
-		$icondata = "\x00\x00";                    // idReserved;   // Reserved (must be 0)
1916
-		$icondata .= "\x01\x00";                    // idType;	   // Resource Type (1 for icons)
1917
-		$icondata .= phpthumb_functions::LittleEndian2String(count($gd_image_array), 2);  // idCount;	  // How many images?
1918
-
1919
-		$dwImageOffset = 6 + (count($gd_image_array) * 16);
1920
-		foreach (array_keys($gd_image_array) as $key) {
1921
-			// ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
1922
-
1923
-			$icondata .= chr($ImageWidths[$key]);           // bWidth;		  // Width, in pixels, of the image
1924
-			$icondata .= chr($ImageHeights[$key]);          // bHeight;		 // Height, in pixels, of the image
1925
-			$icondata .= chr($totalcolors[$key]);           // bColorCount;	 // Number of colors in image (0 if >=8bpp)
1926
-			$icondata .= "\x00";                    // bReserved;	   // Reserved ( must be 0)
1927
-
1928
-			$icondata .= "\x01\x00";                  // wPlanes;		 // Color Planes
1929
-			$icondata .= chr($bpp[$key]) . "\x00";            // wBitCount;	   // Bits per pixel
1930
-
1931
-			$dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);
1932
-			$icondata .= phpthumb_functions::LittleEndian2String(
1933
-				$dwBytesInRes,
1934
-				4
1935
-			);     // dwBytesInRes;	// How many bytes in this resource?
1936
-
1937
-			$icondata .= phpthumb_functions::LittleEndian2String(
1938
-				$dwImageOffset,
1939
-				4
1940
-			);    // dwImageOffset;   // Where in the file is this image?
1941
-			$dwImageOffset += strlen($BitmapInfoHeader[$key]);
1942
-			$dwImageOffset += strlen($icXOR[$key]);
1943
-			$dwImageOffset += strlen($icAND[$key]);
1944
-		}
1945
-
1946
-		foreach (array_keys($gd_image_array) as $key) {
1947
-			$icondata .= $BitmapInfoHeader[$key];
1948
-			$icondata .= $icXOR[$key];
1949
-			$icondata .= $icAND[$key];
1950
-		}
1951
-
1952
-		return $icondata;
1953
-	}
1813
+    /**
1814
+     * Retourne la couleur d'un pixel dans une image
1815
+     *
1816
+     * @param GdImage $img
1817
+     * @param int $x
1818
+     * @param int $y
1819
+     * @return array|bool
1820
+     */
1821
+    public static function GetPixelColor(&$img, $x, $y) {
1822
+        if ($img instanceof \GdImage) {
1823
+            return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));
1824
+        }
1825
+        return false;
1826
+    }
1827
+
1828
+    /**
1829
+     * Retourne un nombre dans une représentation en Little Endian
1830
+     *
1831
+     * @param int $number
1832
+     * @param int $minbytes
1833
+     * @return string
1834
+     */
1835
+    public static function LittleEndian2String($number, $minbytes = 1) {
1836
+        $intstring = '';
1837
+        while ($number > 0) {
1838
+            $intstring .= chr($number & 255);
1839
+            $number >>= 8;
1840
+        }
1841
+
1842
+        return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
1843
+    }
1844
+
1845
+    /**
1846
+     * Transforme une ressource GD en image au format ICO
1847
+     *
1848
+     * @param array $gd_image_array
1849
+     *     Tableau de ressources d'images GD
1850
+     * @return string
1851
+     *     Image au format ICO
1852
+     */
1853
+    public static function GD2ICOstring(&$gd_image_array) {
1854
+        foreach ($gd_image_array as $key => $gd_image) {
1855
+            $ImageWidths[$key] = ImageSX($gd_image);
1856
+            $ImageHeights[$key] = ImageSY($gd_image);
1857
+            $bpp[$key] = ImageIsTrueColor($gd_image) ? 32 : 24;
1858
+            $totalcolors[$key] = ImageColorsTotal($gd_image);
1859
+
1860
+            $icXOR[$key] = '';
1861
+            for ($y = $ImageHeights[$key] - 1; $y >= 0; $y--) {
1862
+                for ($x = 0; $x < $ImageWidths[$key]; $x++) {
1863
+                    $argb = phpthumb_functions::GetPixelColor($gd_image, $x, $y);
1864
+                    $a = round(255 * ((127 - $argb['alpha']) / 127));
1865
+                    $r = $argb['red'];
1866
+                    $g = $argb['green'];
1867
+                    $b = $argb['blue'];
1868
+
1869
+                    if ($bpp[$key] == 32) {
1870
+                        $icXOR[$key] .= chr($b) . chr($g) . chr($r) . chr($a);
1871
+                    } elseif ($bpp[$key] === 24) {
1872
+                        $icXOR[$key] .= chr($b) . chr($g) . chr($r);
1873
+                    }
1874
+
1875
+                    if ($a < 128) {
1876
+                        @$icANDmask[$key][$y] .= '1';
1877
+                    } else {
1878
+                        @$icANDmask[$key][$y] .= '0';
1879
+                    }
1880
+                }
1881
+                // mask bits are 32-bit aligned per scanline
1882
+                while (strlen($icANDmask[$key][$y]) % 32) {
1883
+                    $icANDmask[$key][$y] .= '0';
1884
+                }
1885
+            }
1886
+            $icAND[$key] = '';
1887
+            foreach ($icANDmask[$key] as $y => $scanlinemaskbits) {
1888
+                for ($i = 0; $i < strlen($scanlinemaskbits); $i += 8) {
1889
+                    $icAND[$key] .= chr(bindec(str_pad(substr($scanlinemaskbits, $i, 8), 8, '0', STR_PAD_LEFT)));
1890
+                }
1891
+            }
1892
+        }
1893
+
1894
+        foreach (array_keys($gd_image_array) as $key) {
1895
+            $biSizeImage = $ImageWidths[$key] * $ImageHeights[$key] * ($bpp[$key] / 8);
1896
+
1897
+            // BITMAPINFOHEADER - 40 bytes
1898
+            $BitmapInfoHeader[$key] = '';
1899
+            $BitmapInfoHeader[$key] .= "\x28\x00\x00\x00";                // DWORD  biSize;
1900
+            $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4);    // LONG   biWidth;
1901
+            // The biHeight member specifies the combined
1902
+            // height of the XOR and AND masks.
1903
+            $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG   biHeight;
1904
+            $BitmapInfoHeader[$key] .= "\x01\x00";                    // WORD   biPlanes;
1905
+            $BitmapInfoHeader[$key] .= chr($bpp[$key]) . "\x00";              // wBitCount;
1906
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biCompression;
1907
+            $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4);      // DWORD  biSizeImage;
1908
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // LONG   biXPelsPerMeter;
1909
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // LONG   biYPelsPerMeter;
1910
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biClrUsed;
1911
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biClrImportant;
1912
+        }
1913
+
1914
+
1915
+        $icondata = "\x00\x00";                    // idReserved;   // Reserved (must be 0)
1916
+        $icondata .= "\x01\x00";                    // idType;	   // Resource Type (1 for icons)
1917
+        $icondata .= phpthumb_functions::LittleEndian2String(count($gd_image_array), 2);  // idCount;	  // How many images?
1918
+
1919
+        $dwImageOffset = 6 + (count($gd_image_array) * 16);
1920
+        foreach (array_keys($gd_image_array) as $key) {
1921
+            // ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
1922
+
1923
+            $icondata .= chr($ImageWidths[$key]);           // bWidth;		  // Width, in pixels, of the image
1924
+            $icondata .= chr($ImageHeights[$key]);          // bHeight;		 // Height, in pixels, of the image
1925
+            $icondata .= chr($totalcolors[$key]);           // bColorCount;	 // Number of colors in image (0 if >=8bpp)
1926
+            $icondata .= "\x00";                    // bReserved;	   // Reserved ( must be 0)
1927
+
1928
+            $icondata .= "\x01\x00";                  // wPlanes;		 // Color Planes
1929
+            $icondata .= chr($bpp[$key]) . "\x00";            // wBitCount;	   // Bits per pixel
1930
+
1931
+            $dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);
1932
+            $icondata .= phpthumb_functions::LittleEndian2String(
1933
+                $dwBytesInRes,
1934
+                4
1935
+            );     // dwBytesInRes;	// How many bytes in this resource?
1936
+
1937
+            $icondata .= phpthumb_functions::LittleEndian2String(
1938
+                $dwImageOffset,
1939
+                4
1940
+            );    // dwImageOffset;   // Where in the file is this image?
1941
+            $dwImageOffset += strlen($BitmapInfoHeader[$key]);
1942
+            $dwImageOffset += strlen($icXOR[$key]);
1943
+            $dwImageOffset += strlen($icAND[$key]);
1944
+        }
1945
+
1946
+        foreach (array_keys($gd_image_array) as $key) {
1947
+            $icondata .= $BitmapInfoHeader[$key];
1948
+            $icondata .= $icXOR[$key];
1949
+            $icondata .= $icAND[$key];
1950
+        }
1951
+
1952
+        return $icondata;
1953
+    }
1954 1954
 }
Please login to merge, or discard this patch.
ecrire/public/assembler.php 2 patches
Indentation   +634 added lines, -634 removed lines patch added patch discarded remove patch
@@ -19,175 +19,175 @@  discard block
 block discarded – undo
19 19
  **/
20 20
 
21 21
 if (!defined('_ECRIRE_INC_VERSION')) {
22
-	return;
22
+    return;
23 23
 }
24 24
 
25 25
 // En cas de modification, il faut aussi actualiser la regexp de nettoyer_uri_var() dans inc/utils.php
26 26
 if (!defined('_CONTEXTE_IGNORE_VARIABLES')) {
27
-	define('_CONTEXTE_IGNORE_VARIABLES', '/(^var_|^PHPSESSID$|^fbclid$|^utm_)/');
27
+    define('_CONTEXTE_IGNORE_VARIABLES', '/(^var_|^PHPSESSID$|^fbclid$|^utm_)/');
28 28
 }
29 29
 
30 30
 function assembler($fond, string $connect = '') {
31 31
 
32
-	$chemin_cache = null;
33
-	$lastmodified = null;
34
-	$res = null;
35
-	// flag_preserver est modifie ici, et utilise en globale
36
-	// use_cache sert a informer le bouton d'admin pr savoir s'il met un *
37
-	// contexte est utilise en globale dans le formulaire d'admin
38
-
39
-	$GLOBALS['contexte'] = calculer_contexte();
40
-	$page = ['contexte_implicite' => calculer_contexte_implicite()];
41
-	$page['contexte_implicite']['cache'] = $fond . preg_replace(
42
-		',\.[a-zA-Z0-9]*$,',
43
-		'',
44
-		preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI'])
45
-	);
46
-	// Cette fonction est utilisee deux fois
47
-	$cacher = charger_fonction('cacher', 'public', true);
48
-	// Les quatre derniers parametres sont modifies par la fonction:
49
-	// emplacement, validite, et, s'il est valide, contenu & age
50
-	if ($cacher) {
51
-		$res = $cacher($GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, $page, $lastmodified);
52
-	} else {
53
-		$GLOBALS['use_cache'] = -1;
54
-	}
55
-	// Si un resultat est retourne, c'est un message d'impossibilite
56
-	if ($res) {
57
-		return ['texte' => $res];
58
-	}
59
-
60
-	if (!$chemin_cache || !$lastmodified) {
61
-		$lastmodified = time();
62
-	}
63
-
64
-	$headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD');
65
-	$calculer_page = true;
66
-
67
-	// Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client})
68
-	// une perennite valide a meme reponse qu'une requete HEAD (par defaut les
69
-	// pages sont dynamiques)
70
-	if (
71
-		isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
72
-		&& (!defined('_VAR_MODE') || !_VAR_MODE)
73
-		&& $chemin_cache && isset($page['entetes'])
74
-		&& isset($page['entetes']['Cache-Control'])
75
-		&& strstr($page['entetes']['Cache-Control'], 'max-age=')
76
-		&& !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/')
77
-	) {
78
-		$since = preg_replace(
79
-			'/;.*/',
80
-			'',
81
-			$_SERVER['HTTP_IF_MODIFIED_SINCE']
82
-		);
83
-		$since = str_replace('GMT', '', $since);
84
-		if (trim($since) == gmdate('D, d M Y H:i:s', $lastmodified)) {
85
-			$page['status'] = 304;
86
-			$headers_only = true;
87
-			$calculer_page = false;
88
-		}
89
-	}
90
-
91
-	// Si requete HEAD ou Last-modified compatible, ignorer le texte
92
-	// et pas de content-type (pour contrer le bouton admin de inc-public)
93
-	if (!$calculer_page) {
94
-		$page['texte'] = '';
95
-	} else {
96
-		// si la page est prise dans le cache
97
-		if (!$GLOBALS['use_cache']) {
98
-			// Informer les boutons d'admin du contexte
99
-			// (fourni par urls_decoder_url ci-dessous lors de la mise en cache)
100
-			$GLOBALS['contexte'] = $page['contexte'];
101
-
102
-			// vider les globales url propres qui ne doivent plus etre utilisees en cas
103
-			// d'inversion url => objet
104
-			// plus necessaire si on utilise bien la fonction urls_decoder_url
105
-			#unset($_SERVER['REDIRECT_url_propre']);
106
-			#unset($_ENV['url_propre']);
107
-		} else {
108
-			// Compat ascendante :
109
-			// 1. $contexte est global
110
-			// (a evacuer car urls_decoder_url gere ce probleme ?)
111
-			// et calculer la page
112
-			if (!test_espace_prive()) {
113
-				include_spip('inc/urls');
114
-				[$fond, $GLOBALS['contexte'], $url_redirect] = urls_decoder_url(
115
-					nettoyer_uri(),
116
-					$fond,
117
-					$GLOBALS['contexte'],
118
-					true
119
-				);
120
-			}
121
-			// squelette par defaut
122
-			if (!strlen($fond ?? '')) {
123
-				$fond = 'sommaire';
124
-			}
125
-
126
-			// produire la page : peut mettre a jour $lastmodified
127
-			$produire_page = charger_fonction('produire_page', 'public');
128
-			$page = $produire_page(
129
-				$fond,
130
-				$GLOBALS['contexte'],
131
-				$GLOBALS['use_cache'],
132
-				$chemin_cache,
133
-				null,
134
-				$page,
135
-				$lastmodified,
136
-				$connect
137
-			);
138
-			if ($page === '') {
139
-				$erreur = _T(
140
-					'info_erreur_squelette2',
141
-					['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES]
142
-				);
143
-				erreur_squelette($erreur);
144
-				// eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4
145
-				$page = ['texte' => '', 'erreur' => $erreur];
146
-			}
147
-		}
148
-
149
-		if ($page && $chemin_cache) {
150
-			$page['cache'] = $chemin_cache;
151
-		}
152
-
153
-		auto_content_type($page);
154
-
155
-		$GLOBALS['flag_preserver'] |= headers_sent();
156
-
157
-		// Definir les entetes si ce n'est fait
158
-		if (!$GLOBALS['flag_preserver']) {
159
-			// Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions
160
-			if (
161
-				trim($page['texte']) === ''
162
-				&& _VAR_MODE !== 'debug'
163
-				&& !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur
164
-			) {
165
-				$GLOBALS['contexte']['fond_erreur'] = $fond;
166
-				$page = message_page_indisponible($page, $GLOBALS['contexte']);
167
-			}
168
-			// pas de cache client en mode 'observation'
169
-			if (defined('_VAR_MODE') && _VAR_MODE) {
170
-				$page['entetes']['Cache-Control'] = 'no-cache,must-revalidate';
171
-				$page['entetes']['Pragma'] = 'no-cache';
172
-			}
173
-		}
174
-	}
175
-
176
-	// Entete Last-Modified:
177
-	// eviter d'etre incoherent en envoyant un lastmodified identique
178
-	// a celui qu'on a refuse d'honorer plus haut (cf. #655)
179
-	if (
180
-		$lastmodified && !isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && !isset($page['entetes']['Last-Modified'])
181
-	) {
182
-		$page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT';
183
-	}
184
-
185
-	// fermer la connexion apres les headers si requete HEAD
186
-	if ($headers_only) {
187
-		$page['entetes']['Connection'] = 'close';
188
-	}
189
-
190
-	return $page;
32
+    $chemin_cache = null;
33
+    $lastmodified = null;
34
+    $res = null;
35
+    // flag_preserver est modifie ici, et utilise en globale
36
+    // use_cache sert a informer le bouton d'admin pr savoir s'il met un *
37
+    // contexte est utilise en globale dans le formulaire d'admin
38
+
39
+    $GLOBALS['contexte'] = calculer_contexte();
40
+    $page = ['contexte_implicite' => calculer_contexte_implicite()];
41
+    $page['contexte_implicite']['cache'] = $fond . preg_replace(
42
+        ',\.[a-zA-Z0-9]*$,',
43
+        '',
44
+        preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI'])
45
+    );
46
+    // Cette fonction est utilisee deux fois
47
+    $cacher = charger_fonction('cacher', 'public', true);
48
+    // Les quatre derniers parametres sont modifies par la fonction:
49
+    // emplacement, validite, et, s'il est valide, contenu & age
50
+    if ($cacher) {
51
+        $res = $cacher($GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, $page, $lastmodified);
52
+    } else {
53
+        $GLOBALS['use_cache'] = -1;
54
+    }
55
+    // Si un resultat est retourne, c'est un message d'impossibilite
56
+    if ($res) {
57
+        return ['texte' => $res];
58
+    }
59
+
60
+    if (!$chemin_cache || !$lastmodified) {
61
+        $lastmodified = time();
62
+    }
63
+
64
+    $headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD');
65
+    $calculer_page = true;
66
+
67
+    // Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client})
68
+    // une perennite valide a meme reponse qu'une requete HEAD (par defaut les
69
+    // pages sont dynamiques)
70
+    if (
71
+        isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
72
+        && (!defined('_VAR_MODE') || !_VAR_MODE)
73
+        && $chemin_cache && isset($page['entetes'])
74
+        && isset($page['entetes']['Cache-Control'])
75
+        && strstr($page['entetes']['Cache-Control'], 'max-age=')
76
+        && !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/')
77
+    ) {
78
+        $since = preg_replace(
79
+            '/;.*/',
80
+            '',
81
+            $_SERVER['HTTP_IF_MODIFIED_SINCE']
82
+        );
83
+        $since = str_replace('GMT', '', $since);
84
+        if (trim($since) == gmdate('D, d M Y H:i:s', $lastmodified)) {
85
+            $page['status'] = 304;
86
+            $headers_only = true;
87
+            $calculer_page = false;
88
+        }
89
+    }
90
+
91
+    // Si requete HEAD ou Last-modified compatible, ignorer le texte
92
+    // et pas de content-type (pour contrer le bouton admin de inc-public)
93
+    if (!$calculer_page) {
94
+        $page['texte'] = '';
95
+    } else {
96
+        // si la page est prise dans le cache
97
+        if (!$GLOBALS['use_cache']) {
98
+            // Informer les boutons d'admin du contexte
99
+            // (fourni par urls_decoder_url ci-dessous lors de la mise en cache)
100
+            $GLOBALS['contexte'] = $page['contexte'];
101
+
102
+            // vider les globales url propres qui ne doivent plus etre utilisees en cas
103
+            // d'inversion url => objet
104
+            // plus necessaire si on utilise bien la fonction urls_decoder_url
105
+            #unset($_SERVER['REDIRECT_url_propre']);
106
+            #unset($_ENV['url_propre']);
107
+        } else {
108
+            // Compat ascendante :
109
+            // 1. $contexte est global
110
+            // (a evacuer car urls_decoder_url gere ce probleme ?)
111
+            // et calculer la page
112
+            if (!test_espace_prive()) {
113
+                include_spip('inc/urls');
114
+                [$fond, $GLOBALS['contexte'], $url_redirect] = urls_decoder_url(
115
+                    nettoyer_uri(),
116
+                    $fond,
117
+                    $GLOBALS['contexte'],
118
+                    true
119
+                );
120
+            }
121
+            // squelette par defaut
122
+            if (!strlen($fond ?? '')) {
123
+                $fond = 'sommaire';
124
+            }
125
+
126
+            // produire la page : peut mettre a jour $lastmodified
127
+            $produire_page = charger_fonction('produire_page', 'public');
128
+            $page = $produire_page(
129
+                $fond,
130
+                $GLOBALS['contexte'],
131
+                $GLOBALS['use_cache'],
132
+                $chemin_cache,
133
+                null,
134
+                $page,
135
+                $lastmodified,
136
+                $connect
137
+            );
138
+            if ($page === '') {
139
+                $erreur = _T(
140
+                    'info_erreur_squelette2',
141
+                    ['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES]
142
+                );
143
+                erreur_squelette($erreur);
144
+                // eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4
145
+                $page = ['texte' => '', 'erreur' => $erreur];
146
+            }
147
+        }
148
+
149
+        if ($page && $chemin_cache) {
150
+            $page['cache'] = $chemin_cache;
151
+        }
152
+
153
+        auto_content_type($page);
154
+
155
+        $GLOBALS['flag_preserver'] |= headers_sent();
156
+
157
+        // Definir les entetes si ce n'est fait
158
+        if (!$GLOBALS['flag_preserver']) {
159
+            // Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions
160
+            if (
161
+                trim($page['texte']) === ''
162
+                && _VAR_MODE !== 'debug'
163
+                && !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur
164
+            ) {
165
+                $GLOBALS['contexte']['fond_erreur'] = $fond;
166
+                $page = message_page_indisponible($page, $GLOBALS['contexte']);
167
+            }
168
+            // pas de cache client en mode 'observation'
169
+            if (defined('_VAR_MODE') && _VAR_MODE) {
170
+                $page['entetes']['Cache-Control'] = 'no-cache,must-revalidate';
171
+                $page['entetes']['Pragma'] = 'no-cache';
172
+            }
173
+        }
174
+    }
175
+
176
+    // Entete Last-Modified:
177
+    // eviter d'etre incoherent en envoyant un lastmodified identique
178
+    // a celui qu'on a refuse d'honorer plus haut (cf. #655)
179
+    if (
180
+        $lastmodified && !isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && !isset($page['entetes']['Last-Modified'])
181
+    ) {
182
+        $page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT';
183
+    }
184
+
185
+    // fermer la connexion apres les headers si requete HEAD
186
+    if ($headers_only) {
187
+        $page['entetes']['Connection'] = 'close';
188
+    }
189
+
190
+    return $page;
191 191
 }
192 192
 
193 193
 /**
@@ -204,19 +204,19 @@  discard block
 block discarded – undo
204 204
  */
205 205
 function calculer_contexte() {
206 206
 
207
-	$contexte = [];
208
-	foreach ($_GET as $var => $val) {
209
-		if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) {
210
-			$contexte[$var] = $val;
211
-		}
212
-	}
213
-	foreach ($_POST as $var => $val) {
214
-		if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) {
215
-			$contexte[$var] = $val;
216
-		}
217
-	}
218
-
219
-	return $contexte;
207
+    $contexte = [];
208
+    foreach ($_GET as $var => $val) {
209
+        if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) {
210
+            $contexte[$var] = $val;
211
+        }
212
+    }
213
+    foreach ($_POST as $var => $val) {
214
+        if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) {
215
+            $contexte[$var] = $val;
216
+        }
217
+    }
218
+
219
+    return $contexte;
220 220
 }
221 221
 
222 222
 /**
@@ -227,25 +227,25 @@  discard block
 block discarded – undo
227 227
  * @return array
228 228
  */
229 229
 function calculer_contexte_implicite() {
230
-	static $notes = null;
231
-	if (is_null($notes)) {
232
-		$notes = charger_fonction('notes', 'inc', true);
233
-	}
234
-	$contexte_implicite = [
235
-		'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ?
236
-		'host' => ($_SERVER['HTTP_HOST'] ?? null),
237
-		'https' => ($_SERVER['HTTPS'] ?? ''),
238
-		'espace' => test_espace_prive(),
239
-		'marqueur' => ($GLOBALS['marqueur'] ?? ''),
240
-		'marqueur_skel' => ($GLOBALS['marqueur_skel'] ?? ''),
241
-		'notes' => $notes ? $notes('', 'contexter_cache') : '',
242
-		'spip_version_code' => $GLOBALS['spip_version_code'],
243
-	];
244
-	if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
245
-		$contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST'];
246
-	}
247
-
248
-	return $contexte_implicite;
230
+    static $notes = null;
231
+    if (is_null($notes)) {
232
+        $notes = charger_fonction('notes', 'inc', true);
233
+    }
234
+    $contexte_implicite = [
235
+        'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ?
236
+        'host' => ($_SERVER['HTTP_HOST'] ?? null),
237
+        'https' => ($_SERVER['HTTPS'] ?? ''),
238
+        'espace' => test_espace_prive(),
239
+        'marqueur' => ($GLOBALS['marqueur'] ?? ''),
240
+        'marqueur_skel' => ($GLOBALS['marqueur_skel'] ?? ''),
241
+        'notes' => $notes ? $notes('', 'contexter_cache') : '',
242
+        'spip_version_code' => $GLOBALS['spip_version_code'],
243
+    ];
244
+    if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
245
+        $contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST'];
246
+    }
247
+
248
+    return $contexte_implicite;
249 249
 }
250 250
 
251 251
 //
@@ -254,56 +254,56 @@  discard block
 block discarded – undo
254 254
 
255 255
 function auto_content_type($page) {
256 256
 
257
-	if (!isset($GLOBALS['flag_preserver'])) {
258
-		$GLOBALS['flag_preserver'] = ($page && preg_match(
259
-			'/header\s*\(\s*.content\-type:/isx',
260
-			$page['texte']
261
-		) || (isset($page['entetes']['Content-Type'])));
262
-	}
257
+    if (!isset($GLOBALS['flag_preserver'])) {
258
+        $GLOBALS['flag_preserver'] = ($page && preg_match(
259
+            '/header\s*\(\s*.content\-type:/isx',
260
+            $page['texte']
261
+        ) || (isset($page['entetes']['Content-Type'])));
262
+    }
263 263
 }
264 264
 
265 265
 function inclure_page($fond, $contexte, string $connect = '') {
266
-	$use_cache = null;
267
-	$chemin_cache = null;
268
-	$lastinclude = null;
269
-	$res = null;
270
-	static $cacher, $produire_page;
271
-
272
-	// enlever le fond de contexte inclus car sinon il prend la main
273
-	// dans les sous inclusions -> boucle infinie d'inclusion identique
274
-	// (cette precaution n'est probablement plus utile)
275
-	unset($contexte['fond']);
276
-	$page = ['contexte_implicite' => calculer_contexte_implicite()];
277
-	$page['contexte_implicite']['cache'] = $fond;
278
-	if (is_null($cacher)) {
279
-		$cacher = charger_fonction('cacher', 'public', true);
280
-	}
281
-	// Les quatre derniers parametres sont modifies par la fonction:
282
-	// emplacement, validite, et, s'il est valide, contenu & age
283
-	if ($cacher) {
284
-		$res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude);
285
-	} else {
286
-		$use_cache = -1;
287
-	}
288
-
289
-	// $res = message d'erreur : on sort de la
290
-	if ($res) {
291
-		return ['texte' => $res];
292
-	}
293
-
294
-	// Si use_cache ne vaut pas 0, la page doit etre calculee
295
-	// produire la page : peut mettre a jour $lastinclude
296
-	// le contexte_cache envoye a cacher() a ete conserve et est passe a produire
297
-	if ($use_cache) {
298
-		if (is_null($produire_page)) {
299
-			$produire_page = charger_fonction('produire_page', 'public');
300
-		}
301
-		$page = $produire_page($fond, $contexte, $use_cache, $chemin_cache, $contexte, $page, $lastinclude, $connect);
302
-	}
303
-	// dans tous les cas, mettre a jour $GLOBALS['lastmodified']
304
-	$GLOBALS['lastmodified'] = max(($GLOBALS['lastmodified'] ?? 0), $lastinclude);
305
-
306
-	return $page;
266
+    $use_cache = null;
267
+    $chemin_cache = null;
268
+    $lastinclude = null;
269
+    $res = null;
270
+    static $cacher, $produire_page;
271
+
272
+    // enlever le fond de contexte inclus car sinon il prend la main
273
+    // dans les sous inclusions -> boucle infinie d'inclusion identique
274
+    // (cette precaution n'est probablement plus utile)
275
+    unset($contexte['fond']);
276
+    $page = ['contexte_implicite' => calculer_contexte_implicite()];
277
+    $page['contexte_implicite']['cache'] = $fond;
278
+    if (is_null($cacher)) {
279
+        $cacher = charger_fonction('cacher', 'public', true);
280
+    }
281
+    // Les quatre derniers parametres sont modifies par la fonction:
282
+    // emplacement, validite, et, s'il est valide, contenu & age
283
+    if ($cacher) {
284
+        $res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude);
285
+    } else {
286
+        $use_cache = -1;
287
+    }
288
+
289
+    // $res = message d'erreur : on sort de la
290
+    if ($res) {
291
+        return ['texte' => $res];
292
+    }
293
+
294
+    // Si use_cache ne vaut pas 0, la page doit etre calculee
295
+    // produire la page : peut mettre a jour $lastinclude
296
+    // le contexte_cache envoye a cacher() a ete conserve et est passe a produire
297
+    if ($use_cache) {
298
+        if (is_null($produire_page)) {
299
+            $produire_page = charger_fonction('produire_page', 'public');
300
+        }
301
+        $page = $produire_page($fond, $contexte, $use_cache, $chemin_cache, $contexte, $page, $lastinclude, $connect);
302
+    }
303
+    // dans tous les cas, mettre a jour $GLOBALS['lastmodified']
304
+    $GLOBALS['lastmodified'] = max(($GLOBALS['lastmodified'] ?? 0), $lastinclude);
305
+
306
+    return $page;
307 307
 }
308 308
 
309 309
 /**
@@ -321,41 +321,41 @@  discard block
 block discarded – undo
321 321
  * @return array
322 322
  */
323 323
 function public_produire_page_dist(
324
-	$fond,
325
-	$contexte,
326
-	$use_cache,
327
-	$chemin_cache,
328
-	$contexte_cache,
329
-	&$page,
330
-	&$lastinclude,
331
-	$connect = ''
324
+    $fond,
325
+    $contexte,
326
+    $use_cache,
327
+    $chemin_cache,
328
+    $contexte_cache,
329
+    &$page,
330
+    &$lastinclude,
331
+    $connect = ''
332 332
 ) {
333
-	static $parametrer, $cacher;
334
-	if (!$parametrer) {
335
-		$parametrer = charger_fonction('parametrer', 'public');
336
-	}
337
-	$page = $parametrer($fond, $contexte, $chemin_cache, $connect);
338
-	// et on l'enregistre sur le disque
339
-	if (
340
-		$chemin_cache
341
-		&& $use_cache > -1
342
-		&& is_array($page)
343
-		&& count($page)
344
-		&& isset($page['entetes']['X-Spip-Cache'])
345
-		&& $page['entetes']['X-Spip-Cache'] > 0
346
-	) {
347
-		if (is_null($cacher)) {
348
-			$cacher = charger_fonction('cacher', 'public', true);
349
-		}
350
-		$lastinclude = time();
351
-		if ($cacher) {
352
-			$cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude);
353
-		} else {
354
-			$use_cache = -1;
355
-		}
356
-	}
357
-
358
-	return $page;
333
+    static $parametrer, $cacher;
334
+    if (!$parametrer) {
335
+        $parametrer = charger_fonction('parametrer', 'public');
336
+    }
337
+    $page = $parametrer($fond, $contexte, $chemin_cache, $connect);
338
+    // et on l'enregistre sur le disque
339
+    if (
340
+        $chemin_cache
341
+        && $use_cache > -1
342
+        && is_array($page)
343
+        && count($page)
344
+        && isset($page['entetes']['X-Spip-Cache'])
345
+        && $page['entetes']['X-Spip-Cache'] > 0
346
+    ) {
347
+        if (is_null($cacher)) {
348
+            $cacher = charger_fonction('cacher', 'public', true);
349
+        }
350
+        $lastinclude = time();
351
+        if ($cacher) {
352
+            $cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude);
353
+        } else {
354
+            $use_cache = -1;
355
+        }
356
+    }
357
+
358
+    return $page;
359 359
 }
360 360
 
361 361
 // Fonction inseree par le compilateur dans le code compile.
@@ -369,14 +369,14 @@  discard block
 block discarded – undo
369 369
 // 4: langue
370 370
 
371 371
 function inserer_balise_dynamique($contexte_exec, $contexte_compil) {
372
-	arguments_balise_dyn_depuis_modele(null, 'reset');
373
-
374
-	if (!is_array($contexte_exec)) {
375
-		echo $contexte_exec;
376
-	} // message d'erreur etc
377
-	else {
378
-		inclure_balise_dynamique($contexte_exec, true, $contexte_compil);
379
-	}
372
+    arguments_balise_dyn_depuis_modele(null, 'reset');
373
+
374
+    if (!is_array($contexte_exec)) {
375
+        echo $contexte_exec;
376
+    } // message d'erreur etc
377
+    else {
378
+        inclure_balise_dynamique($contexte_exec, true, $contexte_compil);
379
+    }
380 380
 }
381 381
 
382 382
 /**
@@ -389,101 +389,101 @@  discard block
 block discarded – undo
389 389
  * @return string|void
390 390
  */
391 391
 function inclure_balise_dynamique($texte, $echo = true, $contexte_compil = []) {
392
-	if (is_array($texte)) {
393
-		[$fond, $delainc, $contexte_inclus] = $texte;
394
-
395
-		// delais a l'ancienne, c'est pratiquement mort
396
-		$d = $GLOBALS['delais'] ?? null;
397
-		$GLOBALS['delais'] = $delainc;
398
-
399
-		$page = recuperer_fond(
400
-			$fond,
401
-			$contexte_inclus,
402
-			['trim' => false, 'raw' => true, 'compil' => $contexte_compil]
403
-		);
404
-
405
-		$texte = $page['texte'];
406
-
407
-		$GLOBALS['delais'] = $d;
408
-		// Faire remonter les entetes
409
-		if (
410
-			isset($page['entetes'])
411
-			&& is_array($page['entetes'])
412
-		) {
413
-			// mais pas toutes
414
-			unset($page['entetes']['X-Spip-Cache']);
415
-			unset($page['entetes']['Content-Type']);
416
-			if (isset($GLOBALS['page']) && is_array($GLOBALS['page'])) {
417
-				if (!is_array($GLOBALS['page']['entetes'])) {
418
-					$GLOBALS['page']['entetes'] = [];
419
-				}
420
-				$GLOBALS['page']['entetes'] =
421
-					array_merge($GLOBALS['page']['entetes'], $page['entetes']);
422
-			}
423
-		}
424
-		// _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines
425
-		if (
426
-			isset($page['contexte']['_pipelines'])
427
-			&& is_array($page['contexte']['_pipelines'])
428
-			&& count($page['contexte']['_pipelines'])
429
-		) {
430
-			foreach ($page['contexte']['_pipelines'] as $pipe => $args) {
431
-				$args['contexte'] = $page['contexte'];
432
-				unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul
433
-				$texte = pipeline(
434
-					$pipe,
435
-					[
436
-						'data' => $texte,
437
-						'args' => $args
438
-					]
439
-				);
440
-			}
441
-		}
442
-	}
443
-
444
-	if (defined('_VAR_MODE') && _VAR_MODE == 'debug') {
445
-		// compatibilite : avant on donnait le numero de ligne ou rien.
446
-		$ligne = intval($contexte_compil[3] ?? $contexte_compil);
447
-		$GLOBALS['debug_objets']['resultat'][$ligne] = $texte;
448
-	}
449
-	if ($echo) {
450
-		echo $texte;
451
-	} else {
452
-		return $texte;
453
-	}
392
+    if (is_array($texte)) {
393
+        [$fond, $delainc, $contexte_inclus] = $texte;
394
+
395
+        // delais a l'ancienne, c'est pratiquement mort
396
+        $d = $GLOBALS['delais'] ?? null;
397
+        $GLOBALS['delais'] = $delainc;
398
+
399
+        $page = recuperer_fond(
400
+            $fond,
401
+            $contexte_inclus,
402
+            ['trim' => false, 'raw' => true, 'compil' => $contexte_compil]
403
+        );
404
+
405
+        $texte = $page['texte'];
406
+
407
+        $GLOBALS['delais'] = $d;
408
+        // Faire remonter les entetes
409
+        if (
410
+            isset($page['entetes'])
411
+            && is_array($page['entetes'])
412
+        ) {
413
+            // mais pas toutes
414
+            unset($page['entetes']['X-Spip-Cache']);
415
+            unset($page['entetes']['Content-Type']);
416
+            if (isset($GLOBALS['page']) && is_array($GLOBALS['page'])) {
417
+                if (!is_array($GLOBALS['page']['entetes'])) {
418
+                    $GLOBALS['page']['entetes'] = [];
419
+                }
420
+                $GLOBALS['page']['entetes'] =
421
+                    array_merge($GLOBALS['page']['entetes'], $page['entetes']);
422
+            }
423
+        }
424
+        // _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines
425
+        if (
426
+            isset($page['contexte']['_pipelines'])
427
+            && is_array($page['contexte']['_pipelines'])
428
+            && count($page['contexte']['_pipelines'])
429
+        ) {
430
+            foreach ($page['contexte']['_pipelines'] as $pipe => $args) {
431
+                $args['contexte'] = $page['contexte'];
432
+                unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul
433
+                $texte = pipeline(
434
+                    $pipe,
435
+                    [
436
+                        'data' => $texte,
437
+                        'args' => $args
438
+                    ]
439
+                );
440
+            }
441
+        }
442
+    }
443
+
444
+    if (defined('_VAR_MODE') && _VAR_MODE == 'debug') {
445
+        // compatibilite : avant on donnait le numero de ligne ou rien.
446
+        $ligne = intval($contexte_compil[3] ?? $contexte_compil);
447
+        $GLOBALS['debug_objets']['resultat'][$ligne] = $texte;
448
+    }
449
+    if ($echo) {
450
+        echo $texte;
451
+    } else {
452
+        return $texte;
453
+    }
454 454
 }
455 455
 
456 456
 function message_page_indisponible($page, $contexte) {
457
-	static $deja = false;
458
-	if ($deja) {
459
-		return 'erreur';
460
-	}
461
-	$codes = [
462
-		'404' => '404 Not Found',
463
-		'503' => '503 Service Unavailable',
464
-	];
465
-
466
-	$contexte['status'] = ($page !== false) ? '404' : '503';
467
-	$contexte['code'] = $codes[$contexte['status']];
468
-	$contexte['fond'] = '404'; // gere les 2 erreurs
469
-	if (!isset($contexte['lang'])) {
470
-		include_spip('inc/lang');
471
-		$contexte['lang'] = $GLOBALS['spip_lang'];
472
-	}
473
-
474
-	$deja = true;
475
-	// passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent
476
-	// ex restriction d'acces => 401
477
-	$contexte = pipeline('page_indisponible', $contexte);
478
-
479
-	// produire la page d'erreur
480
-	$page = inclure_page($contexte['fond'], $contexte);
481
-	if (!$page) {
482
-		$page = inclure_page('404', $contexte);
483
-	}
484
-	$page['status'] = $contexte['status'];
485
-
486
-	return $page;
457
+    static $deja = false;
458
+    if ($deja) {
459
+        return 'erreur';
460
+    }
461
+    $codes = [
462
+        '404' => '404 Not Found',
463
+        '503' => '503 Service Unavailable',
464
+    ];
465
+
466
+    $contexte['status'] = ($page !== false) ? '404' : '503';
467
+    $contexte['code'] = $codes[$contexte['status']];
468
+    $contexte['fond'] = '404'; // gere les 2 erreurs
469
+    if (!isset($contexte['lang'])) {
470
+        include_spip('inc/lang');
471
+        $contexte['lang'] = $GLOBALS['spip_lang'];
472
+    }
473
+
474
+    $deja = true;
475
+    // passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent
476
+    // ex restriction d'acces => 401
477
+    $contexte = pipeline('page_indisponible', $contexte);
478
+
479
+    // produire la page d'erreur
480
+    $page = inclure_page($contexte['fond'], $contexte);
481
+    if (!$page) {
482
+        $page = inclure_page('404', $contexte);
483
+    }
484
+    $page['status'] = $contexte['status'];
485
+
486
+    return $page;
487 487
 }
488 488
 
489 489
 /**
@@ -495,44 +495,44 @@  discard block
 block discarded – undo
495 495
  * @return mixed
496 496
  */
497 497
 function arguments_balise_dyn_depuis_modele($arg, $operation = 'set') {
498
-	static $balise_dyn_appellee_par_modele = null;
499
-	switch ($operation) {
500
-		case 'read':
501
-			return $balise_dyn_appellee_par_modele;
502
-		case 'reset':
503
-			$balise_dyn_appellee_par_modele = null;
504
-			return null;
505
-		case 'set':
506
-		default:
507
-			$balise_dyn_appellee_par_modele = $arg;
508
-			return $arg;
509
-	}
498
+    static $balise_dyn_appellee_par_modele = null;
499
+    switch ($operation) {
500
+        case 'read':
501
+            return $balise_dyn_appellee_par_modele;
502
+        case 'reset':
503
+            $balise_dyn_appellee_par_modele = null;
504
+            return null;
505
+        case 'set':
506
+        default:
507
+            $balise_dyn_appellee_par_modele = $arg;
508
+            return $arg;
509
+    }
510 510
 }
511 511
 
512 512
 // temporairement ici : a mettre dans le futur inc/modeles
513 513
 // creer_contexte_de_modele('left', 'autostart=true', ...) renvoie un array()
514 514
 function creer_contexte_de_modele($args) {
515
-	$contexte = [];
516
-	foreach ($args as $var => $val) {
517
-		if (is_int($var)) { // argument pas formate
518
-			if (in_array($val, ['left', 'right', 'center'])) {
519
-				$var = 'align';
520
-				$contexte[$var] = $val;
521
-			} else {
522
-				$args = explode('=', $val);
523
-				if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args
524
-				$contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1);
525
-				} else // notation abregee
526
-				{
527
-					$contexte[trim($val)] = trim($val);
528
-				}
529
-			}
530
-		} else {
531
-			$contexte[$var] = $val;
532
-		}
533
-	}
534
-
535
-	return $contexte;
515
+    $contexte = [];
516
+    foreach ($args as $var => $val) {
517
+        if (is_int($var)) { // argument pas formate
518
+            if (in_array($val, ['left', 'right', 'center'])) {
519
+                $var = 'align';
520
+                $contexte[$var] = $val;
521
+            } else {
522
+                $args = explode('=', $val);
523
+                if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args
524
+                $contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1);
525
+                } else // notation abregee
526
+                {
527
+                    $contexte[trim($val)] = trim($val);
528
+                }
529
+            }
530
+        } else {
531
+            $contexte[$var] = $val;
532
+        }
533
+    }
534
+
535
+    return $contexte;
536 536
 }
537 537
 
538 538
 /**
@@ -547,45 +547,45 @@  discard block
 block discarded – undo
547 547
  * @return string
548 548
  */
549 549
 function styliser_modele($modele, $id, $contexte = null) {
550
-	static $styliseurs = null;
551
-	if (is_null($styliseurs)) {
552
-		$tables_objet = lister_tables_objets_sql();
553
-		foreach ($tables_objet as $table => $desc) {
554
-			if (
555
-				isset($desc['modeles'])
556
-				&& $desc['modeles']
557
-				&& isset($desc['modeles_styliser'])
558
-				&& $desc['modeles_styliser']
559
-				&& function_exists($desc['modeles_styliser'])
560
-			) {
561
-				$primary = id_table_objet($table);
562
-				foreach ($desc['modeles'] as $m) {
563
-					$styliseurs[$m] = ['primary' => $primary, 'callback' => $desc['modeles_styliser']];
564
-				}
565
-			}
566
-		}
567
-	}
568
-
569
-	if (isset($styliseurs[$modele])) {
570
-		$styliseur = $styliseurs[$modele]['callback'];
571
-		$primary = $styliseurs[$modele]['primary'];
572
-		if (is_null($id) && $contexte) {
573
-			if (isset($contexte['id'])) {
574
-				$id = $contexte['id'];
575
-			} elseif (isset($contexte[$primary])) {
576
-				$id = $contexte[$primary];
577
-			}
578
-		}
579
-		if (is_null($id)) {
580
-			$msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]);
581
-			erreur_squelette($msg);
582
-			// on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant
583
-			$id = 0;
584
-		}
585
-		$modele = $styliseur($modele, $id);
586
-	}
587
-
588
-	return $modele;
550
+    static $styliseurs = null;
551
+    if (is_null($styliseurs)) {
552
+        $tables_objet = lister_tables_objets_sql();
553
+        foreach ($tables_objet as $table => $desc) {
554
+            if (
555
+                isset($desc['modeles'])
556
+                && $desc['modeles']
557
+                && isset($desc['modeles_styliser'])
558
+                && $desc['modeles_styliser']
559
+                && function_exists($desc['modeles_styliser'])
560
+            ) {
561
+                $primary = id_table_objet($table);
562
+                foreach ($desc['modeles'] as $m) {
563
+                    $styliseurs[$m] = ['primary' => $primary, 'callback' => $desc['modeles_styliser']];
564
+                }
565
+            }
566
+        }
567
+    }
568
+
569
+    if (isset($styliseurs[$modele])) {
570
+        $styliseur = $styliseurs[$modele]['callback'];
571
+        $primary = $styliseurs[$modele]['primary'];
572
+        if (is_null($id) && $contexte) {
573
+            if (isset($contexte['id'])) {
574
+                $id = $contexte['id'];
575
+            } elseif (isset($contexte[$primary])) {
576
+                $id = $contexte[$primary];
577
+            }
578
+        }
579
+        if (is_null($id)) {
580
+            $msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]);
581
+            erreur_squelette($msg);
582
+            // on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant
583
+            $id = 0;
584
+        }
585
+        $modele = $styliseur($modele, $id);
586
+    }
587
+
588
+    return $modele;
589 589
 }
590 590
 
591 591
 /**
@@ -600,102 +600,102 @@  discard block
 block discarded – undo
600 600
  */
601 601
 function inclure_modele($type, $id, $params, $lien, string $connect = '', $env = []) {
602 602
 
603
-	static $compteur;
604
-	if (++$compteur > 10) {
605
-		return '';
606
-	} # ne pas boucler indefiniment
607
-
608
-	$type = strtolower($type);
609
-	$type = styliser_modele($type, $id);
610
-
611
-	$fond = $class = '';
612
-
613
-	$params = array_filter(explode('|', $params));
614
-	if ($params) {
615
-		$soustype = current($params);
616
-		$soustype = strtolower(trim($soustype));
617
-		if (in_array($soustype, ['left', 'right', 'center', 'ajax'])) {
618
-			$soustype = next($params);
619
-			$soustype = strtolower($soustype);
620
-		}
621
-
622
-		if (preg_match(',^[a-z0-9_]+$,', $soustype)) {
623
-			if (!trouve_modele($fond = ($type . '_' . $soustype))) {
624
-				$fond = '';
625
-				$class = $soustype;
626
-			}
627
-			// enlever le sous type des params
628
-			$params = array_diff($params, [$soustype]);
629
-		}
630
-	}
631
-
632
-	// Si ca marche pas en precisant le sous-type, prendre le type
633
-	if (!$fond && !trouve_modele($fond = $type)) {
634
-		spip_log("Modele $type introuvable", _LOG_INFO_IMPORTANTE);
635
-		$compteur--;
636
-		return false;
637
-	}
638
-	$fond = 'modeles/' . $fond;
639
-	// Creer le contexte
640
-	$contexte = $env;
641
-	$contexte['dir_racine'] = _DIR_RACINE; # eviter de mixer un cache racine et un cache ecrire (meme si pour l'instant les modeles ne sont pas caches, le resultat etant different il faut que le contexte en tienne compte
642
-
643
-	// Le numero du modele est mis dans l'environnement
644
-	// d'une part sous l'identifiant "id"
645
-	// et d'autre part sous l'identifiant de la cle primaire
646
-	// par la fonction id_table_objet,
647
-	// (<article1> =>> article =>> id_article =>> id_article=1)
648
-	$_id = id_table_objet($type);
649
-	$contexte['id'] = $contexte[$_id] = $id;
650
-
651
-	if (isset($class)) {
652
-		$contexte['class'] = $class;
653
-	}
654
-
655
-	// Si un lien a ete passe en parametre, ex: [<modele1>->url] ou [<modele1|title_du_lien{hreflang}->url]
656
-	if ($lien) {
657
-		# un eventuel guillemet (") sera reechappe par #ENV
658
-		$contexte['lien'] = str_replace('&quot;', '"', $lien['href']);
659
-		$contexte['lien_class'] = $lien['class'];
660
-		$contexte['lien_mime'] = $lien['mime'];
661
-		$contexte['lien_title'] = $lien['title'];
662
-		$contexte['lien_hreflang'] = $lien['hreflang'];
663
-	}
664
-
665
-	// Traiter les parametres
666
-	// par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en>
667
-	$arg_list = creer_contexte_de_modele($params);
668
-	$contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args
669
-	$contexte = array_merge($contexte, $arg_list);
670
-
671
-	// Appliquer le modele avec le contexte
672
-	$retour = recuperer_fond($fond, $contexte, [], $connect);
673
-
674
-	// Regarder si le modele tient compte des liens (il *doit* alors indiquer
675
-	// spip_lien_ok dans les classes de son conteneur de premier niveau ;
676
-	// sinon, s'il y a un lien, on l'ajoute classiquement
677
-	if (
678
-		strstr(
679
-			' ' . ($classes = extraire_attribut($retour, 'class')) . ' ',
680
-			'spip_lien_ok'
681
-		)
682
-	) {
683
-		$retour = inserer_attribut(
684
-			$retour,
685
-			'class',
686
-			trim(str_replace(' spip_lien_ok ', ' ', " $classes "))
687
-		);
688
-	} else {
689
-		if ($lien) {
690
-			$retour = '<a href="' . $lien['href'] . '" class="' . $lien['class'] . '">' . $retour . '</a>';
691
-		}
692
-	}
693
-
694
-	$compteur--;
695
-
696
-	return (isset($arg_list['ajax']) && $arg_list['ajax'] == 'ajax')
697
-		? encoder_contexte_ajax($contexte, '', $retour)
698
-		: $retour;
603
+    static $compteur;
604
+    if (++$compteur > 10) {
605
+        return '';
606
+    } # ne pas boucler indefiniment
607
+
608
+    $type = strtolower($type);
609
+    $type = styliser_modele($type, $id);
610
+
611
+    $fond = $class = '';
612
+
613
+    $params = array_filter(explode('|', $params));
614
+    if ($params) {
615
+        $soustype = current($params);
616
+        $soustype = strtolower(trim($soustype));
617
+        if (in_array($soustype, ['left', 'right', 'center', 'ajax'])) {
618
+            $soustype = next($params);
619
+            $soustype = strtolower($soustype);
620
+        }
621
+
622
+        if (preg_match(',^[a-z0-9_]+$,', $soustype)) {
623
+            if (!trouve_modele($fond = ($type . '_' . $soustype))) {
624
+                $fond = '';
625
+                $class = $soustype;
626
+            }
627
+            // enlever le sous type des params
628
+            $params = array_diff($params, [$soustype]);
629
+        }
630
+    }
631
+
632
+    // Si ca marche pas en precisant le sous-type, prendre le type
633
+    if (!$fond && !trouve_modele($fond = $type)) {
634
+        spip_log("Modele $type introuvable", _LOG_INFO_IMPORTANTE);
635
+        $compteur--;
636
+        return false;
637
+    }
638
+    $fond = 'modeles/' . $fond;
639
+    // Creer le contexte
640
+    $contexte = $env;
641
+    $contexte['dir_racine'] = _DIR_RACINE; # eviter de mixer un cache racine et un cache ecrire (meme si pour l'instant les modeles ne sont pas caches, le resultat etant different il faut que le contexte en tienne compte
642
+
643
+    // Le numero du modele est mis dans l'environnement
644
+    // d'une part sous l'identifiant "id"
645
+    // et d'autre part sous l'identifiant de la cle primaire
646
+    // par la fonction id_table_objet,
647
+    // (<article1> =>> article =>> id_article =>> id_article=1)
648
+    $_id = id_table_objet($type);
649
+    $contexte['id'] = $contexte[$_id] = $id;
650
+
651
+    if (isset($class)) {
652
+        $contexte['class'] = $class;
653
+    }
654
+
655
+    // Si un lien a ete passe en parametre, ex: [<modele1>->url] ou [<modele1|title_du_lien{hreflang}->url]
656
+    if ($lien) {
657
+        # un eventuel guillemet (") sera reechappe par #ENV
658
+        $contexte['lien'] = str_replace('&quot;', '"', $lien['href']);
659
+        $contexte['lien_class'] = $lien['class'];
660
+        $contexte['lien_mime'] = $lien['mime'];
661
+        $contexte['lien_title'] = $lien['title'];
662
+        $contexte['lien_hreflang'] = $lien['hreflang'];
663
+    }
664
+
665
+    // Traiter les parametres
666
+    // par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en>
667
+    $arg_list = creer_contexte_de_modele($params);
668
+    $contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args
669
+    $contexte = array_merge($contexte, $arg_list);
670
+
671
+    // Appliquer le modele avec le contexte
672
+    $retour = recuperer_fond($fond, $contexte, [], $connect);
673
+
674
+    // Regarder si le modele tient compte des liens (il *doit* alors indiquer
675
+    // spip_lien_ok dans les classes de son conteneur de premier niveau ;
676
+    // sinon, s'il y a un lien, on l'ajoute classiquement
677
+    if (
678
+        strstr(
679
+            ' ' . ($classes = extraire_attribut($retour, 'class')) . ' ',
680
+            'spip_lien_ok'
681
+        )
682
+    ) {
683
+        $retour = inserer_attribut(
684
+            $retour,
685
+            'class',
686
+            trim(str_replace(' spip_lien_ok ', ' ', " $classes "))
687
+        );
688
+    } else {
689
+        if ($lien) {
690
+            $retour = '<a href="' . $lien['href'] . '" class="' . $lien['class'] . '">' . $retour . '</a>';
691
+        }
692
+    }
693
+
694
+    $compteur--;
695
+
696
+    return (isset($arg_list['ajax']) && $arg_list['ajax'] == 'ajax')
697
+        ? encoder_contexte_ajax($contexte, '', $retour)
698
+        : $retour;
699 699
 }
700 700
 
701 701
 // Un inclure_page qui marche aussi pour l'espace prive
@@ -704,99 +704,99 @@  discard block
 block discarded – undo
704 704
 // 	recuperer_fond($fond,$contexte,array('raw'=>true))
705 705
 function evaluer_fond($fond, $contexte = [], string $connect = '') {
706 706
 
707
-	$page = inclure_page($fond, $contexte, $connect);
708
-
709
-	if (!$page) {
710
-		return $page;
711
-	}
712
-	// eval $page et affecte $res
713
-	include _ROOT_RESTREINT . 'public/evaluer_page.php';
714
-
715
-	// Lever un drapeau (global) si le fond utilise #SESSION
716
-	// a destination de public/parametrer
717
-	// pour remonter vers les inclusions appelantes
718
-	// il faut bien lever ce drapeau apres avoir evalue le fond
719
-	// pour ne pas faire descendre le flag vers les inclusions appelees
720
-	if (
721
-		isset($page['invalideurs'])
722
-		&& isset($page['invalideurs']['session'])
723
-	) {
724
-		$GLOBALS['cache_utilise_session'] = $page['invalideurs']['session'];
725
-	}
726
-
727
-	return $page;
707
+    $page = inclure_page($fond, $contexte, $connect);
708
+
709
+    if (!$page) {
710
+        return $page;
711
+    }
712
+    // eval $page et affecte $res
713
+    include _ROOT_RESTREINT . 'public/evaluer_page.php';
714
+
715
+    // Lever un drapeau (global) si le fond utilise #SESSION
716
+    // a destination de public/parametrer
717
+    // pour remonter vers les inclusions appelantes
718
+    // il faut bien lever ce drapeau apres avoir evalue le fond
719
+    // pour ne pas faire descendre le flag vers les inclusions appelees
720
+    if (
721
+        isset($page['invalideurs'])
722
+        && isset($page['invalideurs']['session'])
723
+    ) {
724
+        $GLOBALS['cache_utilise_session'] = $page['invalideurs']['session'];
725
+    }
726
+
727
+    return $page;
728 728
 }
729 729
 
730 730
 
731 731
 function page_base_href(&$texte) {
732
-	static $set_html_base = null;
733
-	if (is_null($set_html_base)) {
734
-		if (!defined('_SET_HTML_BASE')) {
735
-			// si la profondeur est superieure a 1
736
-			// est que ce n'est pas une url page ni une url action
737
-			// activer par defaut
738
-			$set_html_base =
739
-				$GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2)
740
-				&& _request(_SPIP_PAGE) !== 'login'
741
-				&& !_request('action');
742
-		} else {
743
-			$set_html_base = _SET_HTML_BASE;
744
-		}
745
-	}
746
-
747
-	if (
748
-		$set_html_base
749
-		&& isset($GLOBALS['html'])
750
-		&& $GLOBALS['html']
751
-		&& $GLOBALS['profondeur_url'] > 0
752
-		&& ($poshead = strpos($texte, '</head>')) !== false
753
-	) {
754
-		$head = substr($texte, 0, $poshead);
755
-		$insert = false;
756
-		$href_base = false;
757
-		if (!str_contains($head, '<base')) {
758
-			$insert = true;
759
-		} else {
760
-			// si aucun <base ...> n'a de href il faut en inserer un
761
-			// sinon juste re-ecrire les ancres si besoin
762
-			$insert = true;
763
-			include_spip('inc/filtres');
764
-			$bases = extraire_balises($head, 'base');
765
-			foreach ($bases as $base) {
766
-				if ($href_base = extraire_attribut($base, 'href')) {
767
-					$insert = false;
768
-					break;
769
-				}
770
-			}
771
-		}
772
-
773
-		if ($insert) {
774
-			include_spip('inc/filtres_mini');
775
-			// ajouter un base qui reglera tous les liens relatifs
776
-			$href_base = url_absolue('./');
777
-			$base = "\n<base href=\"$href_base\" />";
778
-			if (($pos = strpos($head, '<head>')) !== false) {
779
-				$head = substr_replace($head, $base, $pos + 6, 0);
780
-			} elseif (preg_match(',<head[^>]*>,i', $head, $r)) {
781
-				$head = str_replace($r[0], $r[0] . $base, $head);
782
-			}
783
-			$texte = $head . substr($texte, $poshead);
784
-		}
785
-		if ($href_base) {
786
-			// gerer les ancres
787
-			$base = $_SERVER['REQUEST_URI'];
788
-			// pas de guillemets ni < dans l'URL qu'on insere dans le HTML
789
-			if (str_contains($base, "'") || str_contains($base, '"') || str_contains($base, '<')) {
790
-				$base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base);
791
-			}
792
-			if (str_contains($texte, "href='#")) {
793
-				$texte = str_replace("href='#", "href='$base#", $texte);
794
-			}
795
-			if (str_contains($texte, 'href="#')) {
796
-				$texte = str_replace('href="#', "href=\"$base#", $texte);
797
-			}
798
-		}
799
-	}
732
+    static $set_html_base = null;
733
+    if (is_null($set_html_base)) {
734
+        if (!defined('_SET_HTML_BASE')) {
735
+            // si la profondeur est superieure a 1
736
+            // est que ce n'est pas une url page ni une url action
737
+            // activer par defaut
738
+            $set_html_base =
739
+                $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2)
740
+                && _request(_SPIP_PAGE) !== 'login'
741
+                && !_request('action');
742
+        } else {
743
+            $set_html_base = _SET_HTML_BASE;
744
+        }
745
+    }
746
+
747
+    if (
748
+        $set_html_base
749
+        && isset($GLOBALS['html'])
750
+        && $GLOBALS['html']
751
+        && $GLOBALS['profondeur_url'] > 0
752
+        && ($poshead = strpos($texte, '</head>')) !== false
753
+    ) {
754
+        $head = substr($texte, 0, $poshead);
755
+        $insert = false;
756
+        $href_base = false;
757
+        if (!str_contains($head, '<base')) {
758
+            $insert = true;
759
+        } else {
760
+            // si aucun <base ...> n'a de href il faut en inserer un
761
+            // sinon juste re-ecrire les ancres si besoin
762
+            $insert = true;
763
+            include_spip('inc/filtres');
764
+            $bases = extraire_balises($head, 'base');
765
+            foreach ($bases as $base) {
766
+                if ($href_base = extraire_attribut($base, 'href')) {
767
+                    $insert = false;
768
+                    break;
769
+                }
770
+            }
771
+        }
772
+
773
+        if ($insert) {
774
+            include_spip('inc/filtres_mini');
775
+            // ajouter un base qui reglera tous les liens relatifs
776
+            $href_base = url_absolue('./');
777
+            $base = "\n<base href=\"$href_base\" />";
778
+            if (($pos = strpos($head, '<head>')) !== false) {
779
+                $head = substr_replace($head, $base, $pos + 6, 0);
780
+            } elseif (preg_match(',<head[^>]*>,i', $head, $r)) {
781
+                $head = str_replace($r[0], $r[0] . $base, $head);
782
+            }
783
+            $texte = $head . substr($texte, $poshead);
784
+        }
785
+        if ($href_base) {
786
+            // gerer les ancres
787
+            $base = $_SERVER['REQUEST_URI'];
788
+            // pas de guillemets ni < dans l'URL qu'on insere dans le HTML
789
+            if (str_contains($base, "'") || str_contains($base, '"') || str_contains($base, '<')) {
790
+                $base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base);
791
+            }
792
+            if (str_contains($texte, "href='#")) {
793
+                $texte = str_replace("href='#", "href='$base#", $texte);
794
+            }
795
+            if (str_contains($texte, 'href="#')) {
796
+                $texte = str_replace('href="#', "href=\"$base#", $texte);
797
+            }
798
+        }
799
+    }
800 800
 }
801 801
 
802 802
 
@@ -806,7 +806,7 @@  discard block
 block discarded – undo
806 806
  * Ceux spécifiques à SPIP commencent par X-Spip
807 807
  */
808 808
 function envoyer_entetes($entetes) {
809
-	foreach ($entetes as $k => $v) {
810
-		@header(strlen((string) $v) ? "$k: $v" : $k);
811
-	}
809
+    foreach ($entetes as $k => $v) {
810
+        @header(strlen((string) $v) ? "$k: $v" : $k);
811
+    }
812 812
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -38,7 +38,7 @@  discard block
 block discarded – undo
38 38
 
39 39
 	$GLOBALS['contexte'] = calculer_contexte();
40 40
 	$page = ['contexte_implicite' => calculer_contexte_implicite()];
41
-	$page['contexte_implicite']['cache'] = $fond . preg_replace(
41
+	$page['contexte_implicite']['cache'] = $fond.preg_replace(
42 42
 		',\.[a-zA-Z0-9]*$,',
43 43
 		'',
44 44
 		preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI'])
@@ -138,7 +138,7 @@  discard block
 block discarded – undo
138 138
 			if ($page === '') {
139 139
 				$erreur = _T(
140 140
 					'info_erreur_squelette2',
141
-					['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES]
141
+					['fichier' => spip_htmlspecialchars($fond).'.'._EXTENSION_SQUELETTES]
142 142
 				);
143 143
 				erreur_squelette($erreur);
144 144
 				// eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4
@@ -179,7 +179,7 @@  discard block
 block discarded – undo
179 179
 	if (
180 180
 		$lastmodified && !isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && !isset($page['entetes']['Last-Modified'])
181 181
 	) {
182
-		$page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT';
182
+		$page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified).' GMT';
183 183
 	}
184 184
 
185 185
 	// fermer la connexion apres les headers si requete HEAD
@@ -242,7 +242,7 @@  discard block
 block discarded – undo
242 242
 		'spip_version_code' => $GLOBALS['spip_version_code'],
243 243
 	];
244 244
 	if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
245
-		$contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST'];
245
+		$contexte_implicite['host'] .= '|'.$_SERVER['HTTP_X_FORWARDED_HOST'];
246 246
 	}
247 247
 
248 248
 	return $contexte_implicite;
@@ -577,7 +577,7 @@  discard block
 block discarded – undo
577 577
 			}
578 578
 		}
579 579
 		if (is_null($id)) {
580
-			$msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]);
580
+			$msg = "modeles/$modele : "._T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]);
581 581
 			erreur_squelette($msg);
582 582
 			// on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant
583 583
 			$id = 0;
@@ -620,7 +620,7 @@  discard block
 block discarded – undo
620 620
 		}
621 621
 
622 622
 		if (preg_match(',^[a-z0-9_]+$,', $soustype)) {
623
-			if (!trouve_modele($fond = ($type . '_' . $soustype))) {
623
+			if (!trouve_modele($fond = ($type.'_'.$soustype))) {
624 624
 				$fond = '';
625 625
 				$class = $soustype;
626 626
 			}
@@ -635,7 +635,7 @@  discard block
 block discarded – undo
635 635
 		$compteur--;
636 636
 		return false;
637 637
 	}
638
-	$fond = 'modeles/' . $fond;
638
+	$fond = 'modeles/'.$fond;
639 639
 	// Creer le contexte
640 640
 	$contexte = $env;
641 641
 	$contexte['dir_racine'] = _DIR_RACINE; # eviter de mixer un cache racine et un cache ecrire (meme si pour l'instant les modeles ne sont pas caches, le resultat etant different il faut que le contexte en tienne compte
@@ -676,7 +676,7 @@  discard block
 block discarded – undo
676 676
 	// sinon, s'il y a un lien, on l'ajoute classiquement
677 677
 	if (
678 678
 		strstr(
679
-			' ' . ($classes = extraire_attribut($retour, 'class')) . ' ',
679
+			' '.($classes = extraire_attribut($retour, 'class')).' ',
680 680
 			'spip_lien_ok'
681 681
 		)
682 682
 	) {
@@ -687,7 +687,7 @@  discard block
 block discarded – undo
687 687
 		);
688 688
 	} else {
689 689
 		if ($lien) {
690
-			$retour = '<a href="' . $lien['href'] . '" class="' . $lien['class'] . '">' . $retour . '</a>';
690
+			$retour = '<a href="'.$lien['href'].'" class="'.$lien['class'].'">'.$retour.'</a>';
691 691
 		}
692 692
 	}
693 693
 
@@ -710,7 +710,7 @@  discard block
 block discarded – undo
710 710
 		return $page;
711 711
 	}
712 712
 	// eval $page et affecte $res
713
-	include _ROOT_RESTREINT . 'public/evaluer_page.php';
713
+	include _ROOT_RESTREINT.'public/evaluer_page.php';
714 714
 
715 715
 	// Lever un drapeau (global) si le fond utilise #SESSION
716 716
 	// a destination de public/parametrer
@@ -778,16 +778,16 @@  discard block
 block discarded – undo
778 778
 			if (($pos = strpos($head, '<head>')) !== false) {
779 779
 				$head = substr_replace($head, $base, $pos + 6, 0);
780 780
 			} elseif (preg_match(',<head[^>]*>,i', $head, $r)) {
781
-				$head = str_replace($r[0], $r[0] . $base, $head);
781
+				$head = str_replace($r[0], $r[0].$base, $head);
782 782
 			}
783
-			$texte = $head . substr($texte, $poshead);
783
+			$texte = $head.substr($texte, $poshead);
784 784
 		}
785 785
 		if ($href_base) {
786 786
 			// gerer les ancres
787 787
 			$base = $_SERVER['REQUEST_URI'];
788 788
 			// pas de guillemets ni < dans l'URL qu'on insere dans le HTML
789 789
 			if (str_contains($base, "'") || str_contains($base, '"') || str_contains($base, '<')) {
790
-				$base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base);
790
+				$base = str_replace(["'", '"', '<'], ['%27', '%22', '%3C'], $base);
791 791
 			}
792 792
 			if (str_contains($texte, "href='#")) {
793 793
 				$texte = str_replace("href='#", "href='$base#", $texte);
Please login to merge, or discard this patch.
ecrire/lang/spip_pt_br.php 1 patch
Indentation   +672 added lines, -672 removed lines patch added patch discarded remove patch
@@ -5,577 +5,577 @@  discard block
 block discarded – undo
5 5
 
6 6
 return [
7 7
 
8
-	// A
9
-	'access_interface_graphique' => 'Voltar para a interface gráfica completa',
10
-	'access_mode_texte' => 'Exibir a interface textual simplificada',
11
-	'admin_debug' => 'depurar',
12
-	'admin_modifier_article' => 'Editar esta matéria',
13
-	'admin_modifier_auteur' => 'Editar este autor',
14
-	'admin_modifier_breve' => 'Editar esta nota',
15
-	'admin_modifier_mot' => 'Editar esta palavra-chave',
16
-	'admin_modifier_rubrique' => 'Editar esta seção',
17
-	'admin_recalculer' => 'Atualizar esta página',
18
-	'afficher_calendrier' => 'Exibir o calendário',
19
-	'afficher_trad' => 'exibir as traduções',
20
-	'alerte_maj_impossible' => '<b>Atenção!</b> A atualização da base de dados SQL para a versão @version@ não é possível, provavelmente por problema de direitos de edição na base de dados. Por favor, contate o seu provedor de hospedagem.',
21
-	'alerte_modif_info_concourante' => 'ATENÇÃO: Esta informação foi alterada por outra pessoa. O valor atual é:',
22
-	'analyse_xml' => 'Analisar XML',
23
-	'annuler' => 'Cancelar',
24
-	'antispam_champ_vide' => 'Por favor, deixe este campo vazio:',
25
-	'articles_recents' => 'Matérias mais recentes',
26
-	'attention_champ_mini_nb_caractères' => 'Atenção! Mínimo de @nb@ caracteres',
27
-	'avis_1_erreur_saisie' => 'Há um erro nos dados informados. Por favor, verifique.',
28
-	'avis_archive_incorrect' => 'a cópia de segurança não é um arquivo do SPIP',
29
-	'avis_archive_invalide' => 'a cópia de segurança não é válida',
30
-	'avis_attention' => 'ATENÇÃO!',
31
-	'avis_champ_incorrect_type_objet' => 'Nome de campo @name@ incorreto para objeto do tipo @type@',
32
-	'avis_colonne_inexistante' => 'A coluna @col@ não existe',
33
-	'avis_erreur' => 'Erro: ver abaixo',
34
-	'avis_erreur_connexion' => 'Erro de conexão',
35
-	'avis_erreur_cookie' => 'problema de cookie',
36
-	'avis_erreur_fonction_contexte' => 'Erro de programação. Esta função não deve ser chamada neste contexto.',
37
-	'avis_erreur_mysql' => 'Erro SQL',
38
-	'avis_erreur_sauvegarde' => 'Erro na cópia de segurança (@type@ @id_objet@) !',
39
-	'avis_erreur_visiteur' => 'Problema de acesso ao espaço privado',
40
-	'avis_nb_erreurs_saisie' => 'Há @nb@ erros nos dados informados. Por favor, verifique.',
8
+    // A
9
+    'access_interface_graphique' => 'Voltar para a interface gráfica completa',
10
+    'access_mode_texte' => 'Exibir a interface textual simplificada',
11
+    'admin_debug' => 'depurar',
12
+    'admin_modifier_article' => 'Editar esta matéria',
13
+    'admin_modifier_auteur' => 'Editar este autor',
14
+    'admin_modifier_breve' => 'Editar esta nota',
15
+    'admin_modifier_mot' => 'Editar esta palavra-chave',
16
+    'admin_modifier_rubrique' => 'Editar esta seção',
17
+    'admin_recalculer' => 'Atualizar esta página',
18
+    'afficher_calendrier' => 'Exibir o calendário',
19
+    'afficher_trad' => 'exibir as traduções',
20
+    'alerte_maj_impossible' => '<b>Atenção!</b> A atualização da base de dados SQL para a versão @version@ não é possível, provavelmente por problema de direitos de edição na base de dados. Por favor, contate o seu provedor de hospedagem.',
21
+    'alerte_modif_info_concourante' => 'ATENÇÃO: Esta informação foi alterada por outra pessoa. O valor atual é:',
22
+    'analyse_xml' => 'Analisar XML',
23
+    'annuler' => 'Cancelar',
24
+    'antispam_champ_vide' => 'Por favor, deixe este campo vazio:',
25
+    'articles_recents' => 'Matérias mais recentes',
26
+    'attention_champ_mini_nb_caractères' => 'Atenção! Mínimo de @nb@ caracteres',
27
+    'avis_1_erreur_saisie' => 'Há um erro nos dados informados. Por favor, verifique.',
28
+    'avis_archive_incorrect' => 'a cópia de segurança não é um arquivo do SPIP',
29
+    'avis_archive_invalide' => 'a cópia de segurança não é válida',
30
+    'avis_attention' => 'ATENÇÃO!',
31
+    'avis_champ_incorrect_type_objet' => 'Nome de campo @name@ incorreto para objeto do tipo @type@',
32
+    'avis_colonne_inexistante' => 'A coluna @col@ não existe',
33
+    'avis_erreur' => 'Erro: ver abaixo',
34
+    'avis_erreur_connexion' => 'Erro de conexão',
35
+    'avis_erreur_cookie' => 'problema de cookie',
36
+    'avis_erreur_fonction_contexte' => 'Erro de programação. Esta função não deve ser chamada neste contexto.',
37
+    'avis_erreur_mysql' => 'Erro SQL',
38
+    'avis_erreur_sauvegarde' => 'Erro na cópia de segurança (@type@ @id_objet@) !',
39
+    'avis_erreur_visiteur' => 'Problema de acesso ao espaço privado',
40
+    'avis_nb_erreurs_saisie' => 'Há @nb@ erros nos dados informados. Por favor, verifique.',
41 41
 
42
-	// B
43
-	'barre_a_accent_grave' => 'Inserir um A maiúsculo com acento grave',
44
-	'barre_aide' => 'utilize os atalhos tipográficos para enriquecer o seu layout',
45
-	'barre_e_accent_aigu' => 'Inserir um E maiúsculo com acento agudo',
46
-	'barre_eo' => 'Inserir um OE contraído',
47
-	'barre_eo_maj' => 'Inserir um OE contraído maiúsculo',
48
-	'barre_euro' => 'Inserir o símbolo € (euro)',
49
-	'barre_gras' => 'Escrever em {{negrito}}',
50
-	'barre_guillemets' => 'envolver em "aspas"',
51
-	'barre_guillemets_simples' => 'Envolver em ’plicas’',
52
-	'barre_intertitre' => 'Transformar em {{{entretítulo}}}',
53
-	'barre_italic' => 'Escrever em {itálico}',
54
-	'barre_lien' => 'Transformar em [link hipertexto->http://...]',
55
-	'barre_lien_input' => 'Informe o endereço do seu link (você pode informar um endereço web do tipo http://www.monsite/com ou simplesmente informar o número de uma matéria deste site.',
56
-	'barre_note' => 'Transformar em [[Nota de pé de página]]',
57
-	'barre_paragraphe' => 'Criar um parágrafo',
58
-	'barre_quote' => '<quote>Citar uma mensagem</quote>',
59
-	'bouton_changer' => 'Alterar',
60
-	'bouton_chercher' => 'Procurar',
61
-	'bouton_choisir' => 'Escolher',
62
-	'bouton_deplacer' => 'Deslocar',
63
-	'bouton_download' => 'Baixar',
64
-	'bouton_enregistrer' => 'Gravar',
65
-	'bouton_radio_desactiver_messagerie_interne' => 'Desativar o sistema interno de mensagens',
66
-	'bouton_radio_envoi_annonces' => 'Enviar os avisos editoriais',
67
-	'bouton_radio_non_envoi_annonces' => 'Não enviar os avisos',
68
-	'bouton_radio_non_envoi_liste_nouveautes' => 'Não enviar a lista de novidades',
69
-	'bouton_recharger_page' => 'atualizar esta página',
70
-	'bouton_telecharger' => 'Transferir',
71
-	'bouton_upload' => 'Upload',
72
-	'bouton_valider' => 'Validar',
42
+    // B
43
+    'barre_a_accent_grave' => 'Inserir um A maiúsculo com acento grave',
44
+    'barre_aide' => 'utilize os atalhos tipográficos para enriquecer o seu layout',
45
+    'barre_e_accent_aigu' => 'Inserir um E maiúsculo com acento agudo',
46
+    'barre_eo' => 'Inserir um OE contraído',
47
+    'barre_eo_maj' => 'Inserir um OE contraído maiúsculo',
48
+    'barre_euro' => 'Inserir o símbolo € (euro)',
49
+    'barre_gras' => 'Escrever em {{negrito}}',
50
+    'barre_guillemets' => 'envolver em "aspas"',
51
+    'barre_guillemets_simples' => 'Envolver em ’plicas’',
52
+    'barre_intertitre' => 'Transformar em {{{entretítulo}}}',
53
+    'barre_italic' => 'Escrever em {itálico}',
54
+    'barre_lien' => 'Transformar em [link hipertexto->http://...]',
55
+    'barre_lien_input' => 'Informe o endereço do seu link (você pode informar um endereço web do tipo http://www.monsite/com ou simplesmente informar o número de uma matéria deste site.',
56
+    'barre_note' => 'Transformar em [[Nota de pé de página]]',
57
+    'barre_paragraphe' => 'Criar um parágrafo',
58
+    'barre_quote' => '<quote>Citar uma mensagem</quote>',
59
+    'bouton_changer' => 'Alterar',
60
+    'bouton_chercher' => 'Procurar',
61
+    'bouton_choisir' => 'Escolher',
62
+    'bouton_deplacer' => 'Deslocar',
63
+    'bouton_download' => 'Baixar',
64
+    'bouton_enregistrer' => 'Gravar',
65
+    'bouton_radio_desactiver_messagerie_interne' => 'Desativar o sistema interno de mensagens',
66
+    'bouton_radio_envoi_annonces' => 'Enviar os avisos editoriais',
67
+    'bouton_radio_non_envoi_annonces' => 'Não enviar os avisos',
68
+    'bouton_radio_non_envoi_liste_nouveautes' => 'Não enviar a lista de novidades',
69
+    'bouton_recharger_page' => 'atualizar esta página',
70
+    'bouton_telecharger' => 'Transferir',
71
+    'bouton_upload' => 'Upload',
72
+    'bouton_valider' => 'Validar',
73 73
 
74
-	// C
75
-	'cal_apresmidi' => 'tarde',
76
-	'cal_jour_entier' => 'dia todo',
77
-	'cal_matin' => 'manhã',
78
-	'cal_par_jour' => 'calendário por dia',
79
-	'cal_par_mois' => 'calendário por mês',
80
-	'cal_par_semaine' => 'calendário por semana',
81
-	'choix_couleur_interface' => 'côr',
82
-	'choix_interface' => 'escolha da interface',
83
-	'colonne' => 'Coluna',
84
-	'confirm_changer_statut' => 'Atenção, você solicitou a alteração de status deste elemento. Deseja continuar?',
85
-	'correcte' => 'correta',
74
+    // C
75
+    'cal_apresmidi' => 'tarde',
76
+    'cal_jour_entier' => 'dia todo',
77
+    'cal_matin' => 'manhã',
78
+    'cal_par_jour' => 'calendário por dia',
79
+    'cal_par_mois' => 'calendário por mês',
80
+    'cal_par_semaine' => 'calendário por semana',
81
+    'choix_couleur_interface' => 'côr',
82
+    'choix_interface' => 'escolha da interface',
83
+    'colonne' => 'Coluna',
84
+    'confirm_changer_statut' => 'Atenção, você solicitou a alteração de status deste elemento. Deseja continuar?',
85
+    'correcte' => 'correta',
86 86
 
87
-	// D
88
-	'date_aujourdhui' => 'hoje',
89
-	'date_avant_jc' => 'a.C.',
90
-	'date_dans' => 'entre @delai@',
91
-	'date_de_mois_1' => '@j@ de @nommois@',
92
-	'date_de_mois_10' => '@j@ de @nommois@',
93
-	'date_de_mois_11' => '@j@ de @nommois@',
94
-	'date_de_mois_12' => '@j@ de @nommois@',
95
-	'date_de_mois_2' => '@j@ de @nommois@',
96
-	'date_de_mois_3' => '@j@ de @nommois@',
97
-	'date_de_mois_4' => '@j@ de @nommois@',
98
-	'date_de_mois_5' => '@j@ de @nommois@',
99
-	'date_de_mois_6' => '@j@ de @nommois@',
100
-	'date_de_mois_7' => '@j@ de @nommois@',
101
-	'date_de_mois_8' => '@j@ de @nommois@',
102
-	'date_de_mois_9' => '@j@ de @nommois@',
103
-	'date_demain' => 'amanhã',
104
-	'date_fmt_heures_minutes' => '@h@h@m@min',
105
-	'date_fmt_heures_minutes_court' => '@h@h@m@',
106
-	'date_fmt_jour' => '@nomjour@ @jour@',
107
-	'date_fmt_jour_heure' => '@jour@ - @heure@',
108
-	'date_fmt_jour_heure_debut_fin' => 'dia @jour@ de @heure_debut@ a @heure_fin@',
109
-	'date_fmt_jour_heure_debut_fin_abbr' => 'dia @dtstart@@jour@ de @heure_debut@@dtabbr@ a @dtstart@@heure_fin@@dtend@',
110
-	'date_fmt_jour_mois' => '@jour@ de @nommois@',
111
-	'date_fmt_jour_mois_annee' => '@jour@ de @nommois@ de @annee@',
112
-	'date_fmt_mois_annee' => '@nommois@ de @annee@',
113
-	'date_fmt_nomjour' => '@nomjour@ @date@',
114
-	'date_fmt_nomjour_date' => '@nomjour@ de @date@',
115
-	'date_fmt_periode' => 'De @date_debut@ a @date_fin@',
116
-	'date_fmt_periode_abbr' => 'De @dtart@@date_debut@@dtabbr@ a @dtend@@date_fin@@dtabbr@',
117
-	'date_fmt_periode_from' => 'De',
118
-	'date_fmt_periode_to' => 'para',
119
-	'date_fmt_saison_annee' => '@saison@ @annee@',
120
-	'date_heures' => 'horas',
121
-	'date_hier' => 'ontem',
122
-	'date_il_y_a' => 'há @delai@',
123
-	'date_jnum1' => '1º',
124
-	'date_jnum10' => '10',
125
-	'date_jnum11' => '11',
126
-	'date_jnum12' => '12',
127
-	'date_jnum13' => '13',
128
-	'date_jnum14' => '14',
129
-	'date_jnum15' => '15',
130
-	'date_jnum16' => '16',
131
-	'date_jnum17' => '17',
132
-	'date_jnum18' => '18',
133
-	'date_jnum19' => '19',
134
-	'date_jnum2' => '2',
135
-	'date_jnum20' => '20',
136
-	'date_jnum21' => '21',
137
-	'date_jnum22' => '22',
138
-	'date_jnum23' => '23',
139
-	'date_jnum24' => '24',
140
-	'date_jnum25' => '25',
141
-	'date_jnum26' => '26',
142
-	'date_jnum27' => '27',
143
-	'date_jnum28' => '28',
144
-	'date_jnum29' => '29',
145
-	'date_jnum3' => '3',
146
-	'date_jnum30' => '30',
147
-	'date_jnum31' => '31',
148
-	'date_jnum4' => '4',
149
-	'date_jnum5' => '5',
150
-	'date_jnum6' => '6',
151
-	'date_jnum7' => '7',
152
-	'date_jnum8' => '8',
153
-	'date_jnum9' => '9',
154
-	'date_jour_1' => 'domingo',
155
-	'date_jour_1_abbr' => 'dom.',
156
-	'date_jour_1_initiale' => 'd.',
157
-	'date_jour_2' => 'segunda-feira',
158
-	'date_jour_2_abbr' => 'seg.',
159
-	'date_jour_2_initiale' => 's.',
160
-	'date_jour_3' => 'terça-feira',
161
-	'date_jour_3_abbr' => 'ter.',
162
-	'date_jour_3_initiale' => 't.',
163
-	'date_jour_4' => 'quarta-feira',
164
-	'date_jour_4_abbr' => 'quar.',
165
-	'date_jour_4_initiale' => 'q.',
166
-	'date_jour_5' => 'quinta-feira',
167
-	'date_jour_5_abbr' => 'quin.',
168
-	'date_jour_5_initiale' => 'q.',
169
-	'date_jour_6' => 'sexta-feira',
170
-	'date_jour_6_abbr' => 'sex.',
171
-	'date_jour_6_initiale' => 's.',
172
-	'date_jour_7' => 'sábado',
173
-	'date_jour_7_abbr' => 'sáb.',
174
-	'date_jour_7_initiale' => 's.',
175
-	'date_jours' => 'dias',
176
-	'date_minutes' => 'minutos',
177
-	'date_mois' => 'meses',
178
-	'date_mois_1' => 'janeiro',
179
-	'date_mois_10' => 'outubro',
180
-	'date_mois_10_abbr' => 'out.',
181
-	'date_mois_11' => 'novembro',
182
-	'date_mois_11_abbr' => 'nov.',
183
-	'date_mois_12' => 'dezembro',
184
-	'date_mois_12_abbr' => 'dez.',
185
-	'date_mois_1_abbr' => 'jan.',
186
-	'date_mois_2' => 'fevereiro',
187
-	'date_mois_2_abbr' => 'fev.',
188
-	'date_mois_3' => 'março',
189
-	'date_mois_3_abbr' => 'mar.',
190
-	'date_mois_4' => 'abril',
191
-	'date_mois_4_abbr' => 'abr.',
192
-	'date_mois_5' => 'maio',
193
-	'date_mois_5_abbr' => 'mai.',
194
-	'date_mois_6' => 'junho',
195
-	'date_mois_6_abbr' => 'jun.',
196
-	'date_mois_7' => 'julho',
197
-	'date_mois_7_abbr' => 'jul.',
198
-	'date_mois_8' => 'agosto',
199
-	'date_mois_8_abbr' => 'ago.',
200
-	'date_mois_9' => 'setembro',
201
-	'date_mois_9_abbr' => 'set.',
202
-	'date_saison_1' => 'inverno',
203
-	'date_saison_2' => 'primavera',
204
-	'date_saison_3' => 'verão',
205
-	'date_saison_4' => 'outono',
206
-	'date_secondes' => 'segundos',
207
-	'date_semaines' => 'semanas',
208
-	'date_un_mois' => 'mês',
209
-	'date_une_heure' => 'hora',
210
-	'date_une_minute' => 'minuto',
211
-	'date_une_seconde' => 'segundo',
212
-	'date_une_semaine' => 'semana',
213
-	'dirs_commencer' => 'Para começar realmente a instalação',
214
-	'dirs_preliminaire' => 'Preliminar: <b>Configurar os direitos de acesso</b>',
215
-	'dirs_probleme_droits' => 'Problema com as permissões de acesso',
216
-	'dirs_repertoires_absents' => '<p><b>Os diretórios a seguir não foram encontrados:</b></p><ul>@bad_dirs@.</ul>
87
+    // D
88
+    'date_aujourdhui' => 'hoje',
89
+    'date_avant_jc' => 'a.C.',
90
+    'date_dans' => 'entre @delai@',
91
+    'date_de_mois_1' => '@j@ de @nommois@',
92
+    'date_de_mois_10' => '@j@ de @nommois@',
93
+    'date_de_mois_11' => '@j@ de @nommois@',
94
+    'date_de_mois_12' => '@j@ de @nommois@',
95
+    'date_de_mois_2' => '@j@ de @nommois@',
96
+    'date_de_mois_3' => '@j@ de @nommois@',
97
+    'date_de_mois_4' => '@j@ de @nommois@',
98
+    'date_de_mois_5' => '@j@ de @nommois@',
99
+    'date_de_mois_6' => '@j@ de @nommois@',
100
+    'date_de_mois_7' => '@j@ de @nommois@',
101
+    'date_de_mois_8' => '@j@ de @nommois@',
102
+    'date_de_mois_9' => '@j@ de @nommois@',
103
+    'date_demain' => 'amanhã',
104
+    'date_fmt_heures_minutes' => '@h@h@m@min',
105
+    'date_fmt_heures_minutes_court' => '@h@h@m@',
106
+    'date_fmt_jour' => '@nomjour@ @jour@',
107
+    'date_fmt_jour_heure' => '@jour@ - @heure@',
108
+    'date_fmt_jour_heure_debut_fin' => 'dia @jour@ de @heure_debut@ a @heure_fin@',
109
+    'date_fmt_jour_heure_debut_fin_abbr' => 'dia @dtstart@@jour@ de @heure_debut@@dtabbr@ a @dtstart@@heure_fin@@dtend@',
110
+    'date_fmt_jour_mois' => '@jour@ de @nommois@',
111
+    'date_fmt_jour_mois_annee' => '@jour@ de @nommois@ de @annee@',
112
+    'date_fmt_mois_annee' => '@nommois@ de @annee@',
113
+    'date_fmt_nomjour' => '@nomjour@ @date@',
114
+    'date_fmt_nomjour_date' => '@nomjour@ de @date@',
115
+    'date_fmt_periode' => 'De @date_debut@ a @date_fin@',
116
+    'date_fmt_periode_abbr' => 'De @dtart@@date_debut@@dtabbr@ a @dtend@@date_fin@@dtabbr@',
117
+    'date_fmt_periode_from' => 'De',
118
+    'date_fmt_periode_to' => 'para',
119
+    'date_fmt_saison_annee' => '@saison@ @annee@',
120
+    'date_heures' => 'horas',
121
+    'date_hier' => 'ontem',
122
+    'date_il_y_a' => 'há @delai@',
123
+    'date_jnum1' => '1º',
124
+    'date_jnum10' => '10',
125
+    'date_jnum11' => '11',
126
+    'date_jnum12' => '12',
127
+    'date_jnum13' => '13',
128
+    'date_jnum14' => '14',
129
+    'date_jnum15' => '15',
130
+    'date_jnum16' => '16',
131
+    'date_jnum17' => '17',
132
+    'date_jnum18' => '18',
133
+    'date_jnum19' => '19',
134
+    'date_jnum2' => '2',
135
+    'date_jnum20' => '20',
136
+    'date_jnum21' => '21',
137
+    'date_jnum22' => '22',
138
+    'date_jnum23' => '23',
139
+    'date_jnum24' => '24',
140
+    'date_jnum25' => '25',
141
+    'date_jnum26' => '26',
142
+    'date_jnum27' => '27',
143
+    'date_jnum28' => '28',
144
+    'date_jnum29' => '29',
145
+    'date_jnum3' => '3',
146
+    'date_jnum30' => '30',
147
+    'date_jnum31' => '31',
148
+    'date_jnum4' => '4',
149
+    'date_jnum5' => '5',
150
+    'date_jnum6' => '6',
151
+    'date_jnum7' => '7',
152
+    'date_jnum8' => '8',
153
+    'date_jnum9' => '9',
154
+    'date_jour_1' => 'domingo',
155
+    'date_jour_1_abbr' => 'dom.',
156
+    'date_jour_1_initiale' => 'd.',
157
+    'date_jour_2' => 'segunda-feira',
158
+    'date_jour_2_abbr' => 'seg.',
159
+    'date_jour_2_initiale' => 's.',
160
+    'date_jour_3' => 'terça-feira',
161
+    'date_jour_3_abbr' => 'ter.',
162
+    'date_jour_3_initiale' => 't.',
163
+    'date_jour_4' => 'quarta-feira',
164
+    'date_jour_4_abbr' => 'quar.',
165
+    'date_jour_4_initiale' => 'q.',
166
+    'date_jour_5' => 'quinta-feira',
167
+    'date_jour_5_abbr' => 'quin.',
168
+    'date_jour_5_initiale' => 'q.',
169
+    'date_jour_6' => 'sexta-feira',
170
+    'date_jour_6_abbr' => 'sex.',
171
+    'date_jour_6_initiale' => 's.',
172
+    'date_jour_7' => 'sábado',
173
+    'date_jour_7_abbr' => 'sáb.',
174
+    'date_jour_7_initiale' => 's.',
175
+    'date_jours' => 'dias',
176
+    'date_minutes' => 'minutos',
177
+    'date_mois' => 'meses',
178
+    'date_mois_1' => 'janeiro',
179
+    'date_mois_10' => 'outubro',
180
+    'date_mois_10_abbr' => 'out.',
181
+    'date_mois_11' => 'novembro',
182
+    'date_mois_11_abbr' => 'nov.',
183
+    'date_mois_12' => 'dezembro',
184
+    'date_mois_12_abbr' => 'dez.',
185
+    'date_mois_1_abbr' => 'jan.',
186
+    'date_mois_2' => 'fevereiro',
187
+    'date_mois_2_abbr' => 'fev.',
188
+    'date_mois_3' => 'março',
189
+    'date_mois_3_abbr' => 'mar.',
190
+    'date_mois_4' => 'abril',
191
+    'date_mois_4_abbr' => 'abr.',
192
+    'date_mois_5' => 'maio',
193
+    'date_mois_5_abbr' => 'mai.',
194
+    'date_mois_6' => 'junho',
195
+    'date_mois_6_abbr' => 'jun.',
196
+    'date_mois_7' => 'julho',
197
+    'date_mois_7_abbr' => 'jul.',
198
+    'date_mois_8' => 'agosto',
199
+    'date_mois_8_abbr' => 'ago.',
200
+    'date_mois_9' => 'setembro',
201
+    'date_mois_9_abbr' => 'set.',
202
+    'date_saison_1' => 'inverno',
203
+    'date_saison_2' => 'primavera',
204
+    'date_saison_3' => 'verão',
205
+    'date_saison_4' => 'outono',
206
+    'date_secondes' => 'segundos',
207
+    'date_semaines' => 'semanas',
208
+    'date_un_mois' => 'mês',
209
+    'date_une_heure' => 'hora',
210
+    'date_une_minute' => 'minuto',
211
+    'date_une_seconde' => 'segundo',
212
+    'date_une_semaine' => 'semana',
213
+    'dirs_commencer' => 'Para começar realmente a instalação',
214
+    'dirs_preliminaire' => 'Preliminar: <b>Configurar os direitos de acesso</b>',
215
+    'dirs_probleme_droits' => 'Problema com as permissões de acesso',
216
+    'dirs_repertoires_absents' => '<p><b>Os diretórios a seguir não foram encontrados:</b></p><ul>@bad_dirs@.</ul>
217 217
 <p>É provável que isto se deva a um problema de letras em maiúsculas e minúsculas.
218 218
 Verifique se as maiúsculas e minúsuculas destes diretórios coincidem exatamente com o que está sendo exibido abaixo; se este não for o caso, renomeie os diretórios com o seu programa de FTP de modo a corrigir o erro.
219 219
 <p>Uma vêz feita esta manipulação, você poderá ',
220
-	'dirs_repertoires_suivants' => '<p><b>Os diretórios a seguir não estão acessiveis para leitura:</b></p><ul>@bad_dirs@.</ul>
220
+    'dirs_repertoires_suivants' => '<p><b>Os diretórios a seguir não estão acessiveis para leitura:</b></p><ul>@bad_dirs@.</ul>
221 221
 <p>Para corrigir, utilize o seu programa de FTP para configurar os direitos de acesso de cada um destes diretórios. O procedimento está explicado em detalhes no guia de instalação.</p>
222 222
 <p>Uma vêz feita esta alteração, você poderá ',
223
-	'double_occurrence' => 'Ocorrência dupla de @balise@',
223
+    'double_occurrence' => 'Ocorrência dupla de @balise@',
224 224
 
225
-	// E
226
-	'en_cours' => 'em curso',
227
-	'envoi_via_le_site' => 'Envio pelo site',
228
-	'erreur' => 'Erro',
229
-	'erreur_balise_non_fermee' => 'Última tag em aberto:',
230
-	'erreur_technique_ajaxform' => 'Ooops. Um erro inesperado impediu o envio do formulário. Você pode tentar novamente.',
231
-	'erreur_technique_enregistrement_champs' => 'Um erro técnico impediu a gravação correta do campo @champs@.',
232
-	'erreur_technique_enregistrement_impossible' => 'Um erro técnico impediu a gravação.',
233
-	'erreur_texte' => 'erro(s)',
234
-	'etape' => 'Etapa',
225
+    // E
226
+    'en_cours' => 'em curso',
227
+    'envoi_via_le_site' => 'Envio pelo site',
228
+    'erreur' => 'Erro',
229
+    'erreur_balise_non_fermee' => 'Última tag em aberto:',
230
+    'erreur_technique_ajaxform' => 'Ooops. Um erro inesperado impediu o envio do formulário. Você pode tentar novamente.',
231
+    'erreur_technique_enregistrement_champs' => 'Um erro técnico impediu a gravação correta do campo @champs@.',
232
+    'erreur_technique_enregistrement_impossible' => 'Um erro técnico impediu a gravação.',
233
+    'erreur_texte' => 'erro(s)',
234
+    'etape' => 'Etapa',
235 235
 
236
-	// F
237
-	'fichier_introuvable' => 'Arquivo @fichier@ não encontrado.',
238
-	'fonction_introuvable' => 'Função @fonction@() não encontrada.',
239
-	'form_auteur_confirmation' => 'Confirme o seu endereço de e-mail',
240
-	'form_auteur_email_modifie' => 'O seu endereço de e-mail foi alterado.',
241
-	'form_auteur_envoi_mail_confirmation' => 'Uma mensagem de confirmação acabou de ser enviada para @email@. Você precisa entrar no endereço web mencionado na mensagem para validar o seu endereço de e-mail.',
242
-	'form_auteur_mail_confirmation' => 'Olá,
236
+    // F
237
+    'fichier_introuvable' => 'Arquivo @fichier@ não encontrado.',
238
+    'fonction_introuvable' => 'Função @fonction@() não encontrada.',
239
+    'form_auteur_confirmation' => 'Confirme o seu endereço de e-mail',
240
+    'form_auteur_email_modifie' => 'O seu endereço de e-mail foi alterado.',
241
+    'form_auteur_envoi_mail_confirmation' => 'Uma mensagem de confirmação acabou de ser enviada para @email@. Você precisa entrar no endereço web mencionado na mensagem para validar o seu endereço de e-mail.',
242
+    'form_auteur_mail_confirmation' => 'Olá,
243 243
 
244 244
 Você pediu para alterar o seu endereço de e-mail
245 245
 Para confirmar o seu novo endereço, basta acessar o endereço abaixo (cas contrário, a sua solicitação será ignorada):
246 246
 
247 247
     @url@
248 248
 ',
249
-	'form_deja_inscrit' => 'Você já está inscrito.',
250
-	'form_email_non_valide' => 'Seu endereço de e-mail não é válido.',
251
-	'form_forum_access_refuse' => 'Você não tem mais acesso a este site.',
252
-	'form_forum_bonjour' => 'Bom dia @nom@,',
253
-	'form_forum_confirmer_email' => 'Para confirmar o seu endereço de e-mail, clique neste link: @url_confirm@',
254
-	'form_forum_email_deja_enregistre' => 'Este endereço de e-mail já está cadastrado, você pode usar a sua senha habitual.',
255
-	'form_forum_identifiant_mail' => 'Seu novo login foi enviado por e-mail.',
256
-	'form_forum_identifiants' => 'Identificadores pessoais',
257
-	'form_forum_indiquer_nom_email' => 'Informe aqui o seu nome  endereço de e-mail. O seu identificador pessoal será enviado de imediato por correio eletrônico.',
258
-	'form_forum_login' => 'login:',
259
-	'form_forum_message_auto' => '(esta é uma mensagem automática)',
260
-	'form_forum_pass' => 'senha:',
261
-	'form_forum_probleme_mail' => 'Problema de e-mail: o identificador não pôde ser enviado.',
262
-	'form_forum_voici1' => 'Estes são os seus identificadores para que você possa participar da vida do site "@nom_site_spip@" (@adresse_site@):',
263
-	'form_forum_voici2' => 'Estes são os seus identificadores para que você possa propor matérias ao site "@nom_site_spip@" (@adresse_login@):',
264
-	'form_indiquer_email' => 'Por favor, informe o seu endereço de e-mail.',
265
-	'form_indiquer_nom' => 'Por favor, informe o seu nome.',
266
-	'form_indiquer_nom_site' => 'Por favor, informe o nome do seu site.',
267
-	'form_pet_deja_enregistre' => 'Este site já está cadastrado',
268
-	'form_pet_signature_pasprise' => 'Sua assinatura não foi computada.',
269
-	'form_prop_confirmer_envoi' => 'Confirmar o envio',
270
-	'form_prop_description' => 'Descrição / comentário',
271
-	'form_prop_enregistre' => 'Sua proposta foi cadastrada, ela aparecerá online após ser validada pelos responsáveis deste site.',
272
-	'form_prop_envoyer' => 'Enviar uma mensagem',
273
-	'form_prop_indiquer_email' => 'Por favor, indique um endereço de e-mail válido',
274
-	'form_prop_indiquer_nom_site' => 'Por favor, informe o nome do site.',
275
-	'form_prop_indiquer_sujet' => 'Por favor, informe um assunto',
276
-	'form_prop_message_envoye' => 'Mensagem enviada',
277
-	'form_prop_non_enregistre' => 'Sua proposta não foi cadastrada.',
278
-	'form_prop_sujet' => 'Assunto',
279
-	'form_prop_url_site' => 'Endereço URL do site',
280
-	'format_date_attendu' => 'Inserir uma data no formato dd/mm/aaaa.',
281
-	'format_date_incorrecte' => 'A data e o seu formato está incorreta',
282
-	'format_heure_attendu' => 'Inserir uma hora no formato hh:mm.',
283
-	'format_heure_incorrecte' => 'A hora e o seu formato está incorreta',
284
-	'forum_non_inscrit' => 'Você não está inscrito, ou o endereço ou a senha estão errados.',
285
-	'forum_par_auteur' => 'por @auteur@',
286
-	'forum_titre_erreur' => 'Erro...',
249
+    'form_deja_inscrit' => 'Você já está inscrito.',
250
+    'form_email_non_valide' => 'Seu endereço de e-mail não é válido.',
251
+    'form_forum_access_refuse' => 'Você não tem mais acesso a este site.',
252
+    'form_forum_bonjour' => 'Bom dia @nom@,',
253
+    'form_forum_confirmer_email' => 'Para confirmar o seu endereço de e-mail, clique neste link: @url_confirm@',
254
+    'form_forum_email_deja_enregistre' => 'Este endereço de e-mail já está cadastrado, você pode usar a sua senha habitual.',
255
+    'form_forum_identifiant_mail' => 'Seu novo login foi enviado por e-mail.',
256
+    'form_forum_identifiants' => 'Identificadores pessoais',
257
+    'form_forum_indiquer_nom_email' => 'Informe aqui o seu nome  endereço de e-mail. O seu identificador pessoal será enviado de imediato por correio eletrônico.',
258
+    'form_forum_login' => 'login:',
259
+    'form_forum_message_auto' => '(esta é uma mensagem automática)',
260
+    'form_forum_pass' => 'senha:',
261
+    'form_forum_probleme_mail' => 'Problema de e-mail: o identificador não pôde ser enviado.',
262
+    'form_forum_voici1' => 'Estes são os seus identificadores para que você possa participar da vida do site "@nom_site_spip@" (@adresse_site@):',
263
+    'form_forum_voici2' => 'Estes são os seus identificadores para que você possa propor matérias ao site "@nom_site_spip@" (@adresse_login@):',
264
+    'form_indiquer_email' => 'Por favor, informe o seu endereço de e-mail.',
265
+    'form_indiquer_nom' => 'Por favor, informe o seu nome.',
266
+    'form_indiquer_nom_site' => 'Por favor, informe o nome do seu site.',
267
+    'form_pet_deja_enregistre' => 'Este site já está cadastrado',
268
+    'form_pet_signature_pasprise' => 'Sua assinatura não foi computada.',
269
+    'form_prop_confirmer_envoi' => 'Confirmar o envio',
270
+    'form_prop_description' => 'Descrição / comentário',
271
+    'form_prop_enregistre' => 'Sua proposta foi cadastrada, ela aparecerá online após ser validada pelos responsáveis deste site.',
272
+    'form_prop_envoyer' => 'Enviar uma mensagem',
273
+    'form_prop_indiquer_email' => 'Por favor, indique um endereço de e-mail válido',
274
+    'form_prop_indiquer_nom_site' => 'Por favor, informe o nome do site.',
275
+    'form_prop_indiquer_sujet' => 'Por favor, informe um assunto',
276
+    'form_prop_message_envoye' => 'Mensagem enviada',
277
+    'form_prop_non_enregistre' => 'Sua proposta não foi cadastrada.',
278
+    'form_prop_sujet' => 'Assunto',
279
+    'form_prop_url_site' => 'Endereço URL do site',
280
+    'format_date_attendu' => 'Inserir uma data no formato dd/mm/aaaa.',
281
+    'format_date_incorrecte' => 'A data e o seu formato está incorreta',
282
+    'format_heure_attendu' => 'Inserir uma hora no formato hh:mm.',
283
+    'format_heure_incorrecte' => 'A hora e o seu formato está incorreta',
284
+    'forum_non_inscrit' => 'Você não está inscrito, ou o endereço ou a senha estão errados.',
285
+    'forum_par_auteur' => 'por @auteur@',
286
+    'forum_titre_erreur' => 'Erro...',
287 287
 
288
-	// I
289
-	'ical_texte_rss_articles' => 'O arquivo «backend» das matérias deste site encontra-se no endereço:',
290
-	'ical_texte_rss_articles2' => 'Você pode também obter os arquivos «backend» para as matérias de cada seção do site:',
291
-	'ical_texte_rss_breves' => 'Existe também um arquivo contendo as notas do site. Ao especificar um número de seção, você obterá unicamente as natos dessa seção.',
292
-	'icone_a_suivre' => 'Acompanhar',
293
-	'icone_admin_site' => 'Administração do site',
294
-	'icone_agenda' => 'Agenda',
295
-	'icone_aide_ligne' => 'Ajuda',
296
-	'icone_articles' => 'Matérias',
297
-	'icone_auteurs' => 'Autores',
298
-	'icone_brouteur' => 'Navegação rápida',
299
-	'icone_configuration_site' => 'Configuração',
300
-	'icone_configurer_site' => 'Configurar o seu site',
301
-	'icone_creer_nouvel_auteur' => 'Criar um novo autor',
302
-	'icone_creer_rubrique' => 'Criar uma seção',
303
-	'icone_creer_sous_rubrique' => 'Criar uma subseção',
304
-	'icone_deconnecter' => 'Desconectar-se',
305
-	'icone_discussions' => 'Discussões',
306
-	'icone_doc_rubrique' => 'Documentos das seções',
307
-	'icone_ecrire_article' => 'Escrever uma nova matéria',
308
-	'icone_edition_site' => 'Edição',
309
-	'icone_gestion_langues' => 'Gerenciamento de idiomas',
310
-	'icone_informations_personnelles' => 'Informações pessoais',
311
-	'icone_interface_complet' => 'interface completa',
312
-	'icone_interface_simple' => 'Interface simplificada',
313
-	'icone_maintenance_site' => 'Manutenção do site',
314
-	'icone_messagerie_personnelle' => 'Mensagens pessoais',
315
-	'icone_repartition_debut' => 'Exibir a repartição após o início',
316
-	'icone_rubriques' => 'Seções',
317
-	'icone_sauver_site' => 'Backup do site',
318
-	'icone_site_entier' => 'Todo o site',
319
-	'icone_sites_references' => 'Sites referenciados',
320
-	'icone_statistiques' => 'Estatísticas do site',
321
-	'icone_suivi_activite' => 'Acompanhar a vida do site',
322
-	'icone_suivi_actualite' => 'Evolução do site',
323
-	'icone_suivi_pettions' => 'Acompanhar / gerenciar as petições',
324
-	'icone_suivi_revisions' => 'Modificações das matérias',
325
-	'icone_supprimer_document' => 'Suprimir este documento',
326
-	'icone_supprimer_image' => 'Suprimir esta imagem',
327
-	'icone_tous_articles' => 'Todas as suas matérias',
328
-	'icone_tous_auteur' => 'Todos os autores',
329
-	'icone_tous_visiteur' => 'Todos os visitantes',
330
-	'icone_visiter_site' => 'Ver o site público',
331
-	'icone_voir_en_ligne' => 'Ver online',
332
-	'img_indisponible' => 'imagem indisponível',
333
-	'impossible' => 'impossível',
334
-	'info_a_suivre' => 'ACOMPANHAR»',
335
-	'info_acces_interdit' => 'Acesso interdito',
336
-	'info_acces_refuse' => 'Acesso recusado',
337
-	'info_action' => 'Ação: @action@',
338
-	'info_administrer_rubriques' => 'Você pode administrar esta seção e suas subseções',
339
-	'info_adresse_non_indiquee' => 'Você não informou o endereço a testar!',
340
-	'info_aide' => 'AJUDA:',
341
-	'info_ajouter_mot' => 'Incluir esta palavra',
342
-	'info_annonce' => 'AVISO',
343
-	'info_annonces_generales' => 'Avisos gerais:',
344
-	'info_article_propose' => 'Matéria proposta',
345
-	'info_article_publie' => 'Matéria publicada',
346
-	'info_article_redaction' => 'Matéria em fase de redação',
347
-	'info_article_refuse' => 'Matéria recusada',
348
-	'info_article_supprime' => 'Matéria suprimida',
349
-	'info_articles' => 'Matérias',
350
-	'info_articles_a_valider' => 'As matérias para validar',
351
-	'info_articles_nb' => '@nb@ matérias',
352
-	'info_articles_proposes' => 'Matérias propostas',
353
-	'info_articles_un' => '1 matéria',
354
-	'info_auteurs_nombre' => 'autor(es):',
355
-	'info_authentification_ftp' => 'Autenticação (por FTP).',
356
-	'info_breves_2' => 'notas',
357
-	'info_breves_nb' => '@nb@ notas',
358
-	'info_breves_un' => '1 nota',
359
-	'info_connexion_refusee' => 'Conexão recusada',
360
-	'info_contact_developpeur' => 'Por favor, contate um desenvolvedor.',
361
-	'info_contenance' => 'Este site contém:',
362
-	'info_contribution' => 'contribuições',
363
-	'info_copyright' => '@spip@ é um software livre distribuído @lien_gpl@.',
364
-	'info_copyright_doc' => 'Para mais informações, veja o site <a href="@spipnet@">@spipnet_affiche@</a>.',
365
-	'info_copyright_gpl' => 'sob licença GPL',
366
-	'info_cours_edition' => 'Em edição',
367
-	'info_creer_repertoire' => 'Por favor, crie um arquivo ou diretório com o nome:',
368
-	'info_creer_repertoire_2' => 'dentro do subdiretório <b>@repertoire@</b>, e depois:',
369
-	'info_creer_vignette' => 'criação automática do ícone',
370
-	'info_creerdansrubrique_non_autorise' => 'Você não tem permissão para criar um conteúdo nesta seção',
371
-	'info_deplier' => 'Expandir',
372
-	'info_descriptif_nombre' => 'descrição(ões):',
373
-	'info_description' => 'Resumo:',
374
-	'info_description_2' => 'Resumo:',
375
-	'info_dimension' => 'Dimensões:',
376
-	'info_documents_nb' => '@nb@ documentos',
377
-	'info_documents_un' => '1 documento',
378
-	'info_ecire_message_prive' => 'Escrever uma mensagem privada',
379
-	'info_email_invalide' => 'Endereço de e-mail inválido.',
380
-	'info_en_cours_validation' => 'Suas matérias em fase de redação',
381
-	'info_en_ligne' => 'Atualmente online:',
382
-	'info_envoyer_message_prive' => 'Enviar uma mensagem privada a este autor',
383
-	'info_erreur_requete' => 'Erro na requisição:',
384
-	'info_erreur_squelette2' => 'Nenhum template <b>@fichier@</b> está disponível...',
385
-	'info_erreur_systeme' => 'Erro do sistema (errno @errsys@)',
386
-	'info_erreur_systeme2' => 'É possível que não haja espaço livre em disco, ou que a base de dados esteja corrompida.<br />
288
+    // I
289
+    'ical_texte_rss_articles' => 'O arquivo «backend» das matérias deste site encontra-se no endereço:',
290
+    'ical_texte_rss_articles2' => 'Você pode também obter os arquivos «backend» para as matérias de cada seção do site:',
291
+    'ical_texte_rss_breves' => 'Existe também um arquivo contendo as notas do site. Ao especificar um número de seção, você obterá unicamente as natos dessa seção.',
292
+    'icone_a_suivre' => 'Acompanhar',
293
+    'icone_admin_site' => 'Administração do site',
294
+    'icone_agenda' => 'Agenda',
295
+    'icone_aide_ligne' => 'Ajuda',
296
+    'icone_articles' => 'Matérias',
297
+    'icone_auteurs' => 'Autores',
298
+    'icone_brouteur' => 'Navegação rápida',
299
+    'icone_configuration_site' => 'Configuração',
300
+    'icone_configurer_site' => 'Configurar o seu site',
301
+    'icone_creer_nouvel_auteur' => 'Criar um novo autor',
302
+    'icone_creer_rubrique' => 'Criar uma seção',
303
+    'icone_creer_sous_rubrique' => 'Criar uma subseção',
304
+    'icone_deconnecter' => 'Desconectar-se',
305
+    'icone_discussions' => 'Discussões',
306
+    'icone_doc_rubrique' => 'Documentos das seções',
307
+    'icone_ecrire_article' => 'Escrever uma nova matéria',
308
+    'icone_edition_site' => 'Edição',
309
+    'icone_gestion_langues' => 'Gerenciamento de idiomas',
310
+    'icone_informations_personnelles' => 'Informações pessoais',
311
+    'icone_interface_complet' => 'interface completa',
312
+    'icone_interface_simple' => 'Interface simplificada',
313
+    'icone_maintenance_site' => 'Manutenção do site',
314
+    'icone_messagerie_personnelle' => 'Mensagens pessoais',
315
+    'icone_repartition_debut' => 'Exibir a repartição após o início',
316
+    'icone_rubriques' => 'Seções',
317
+    'icone_sauver_site' => 'Backup do site',
318
+    'icone_site_entier' => 'Todo o site',
319
+    'icone_sites_references' => 'Sites referenciados',
320
+    'icone_statistiques' => 'Estatísticas do site',
321
+    'icone_suivi_activite' => 'Acompanhar a vida do site',
322
+    'icone_suivi_actualite' => 'Evolução do site',
323
+    'icone_suivi_pettions' => 'Acompanhar / gerenciar as petições',
324
+    'icone_suivi_revisions' => 'Modificações das matérias',
325
+    'icone_supprimer_document' => 'Suprimir este documento',
326
+    'icone_supprimer_image' => 'Suprimir esta imagem',
327
+    'icone_tous_articles' => 'Todas as suas matérias',
328
+    'icone_tous_auteur' => 'Todos os autores',
329
+    'icone_tous_visiteur' => 'Todos os visitantes',
330
+    'icone_visiter_site' => 'Ver o site público',
331
+    'icone_voir_en_ligne' => 'Ver online',
332
+    'img_indisponible' => 'imagem indisponível',
333
+    'impossible' => 'impossível',
334
+    'info_a_suivre' => 'ACOMPANHAR»',
335
+    'info_acces_interdit' => 'Acesso interdito',
336
+    'info_acces_refuse' => 'Acesso recusado',
337
+    'info_action' => 'Ação: @action@',
338
+    'info_administrer_rubriques' => 'Você pode administrar esta seção e suas subseções',
339
+    'info_adresse_non_indiquee' => 'Você não informou o endereço a testar!',
340
+    'info_aide' => 'AJUDA:',
341
+    'info_ajouter_mot' => 'Incluir esta palavra',
342
+    'info_annonce' => 'AVISO',
343
+    'info_annonces_generales' => 'Avisos gerais:',
344
+    'info_article_propose' => 'Matéria proposta',
345
+    'info_article_publie' => 'Matéria publicada',
346
+    'info_article_redaction' => 'Matéria em fase de redação',
347
+    'info_article_refuse' => 'Matéria recusada',
348
+    'info_article_supprime' => 'Matéria suprimida',
349
+    'info_articles' => 'Matérias',
350
+    'info_articles_a_valider' => 'As matérias para validar',
351
+    'info_articles_nb' => '@nb@ matérias',
352
+    'info_articles_proposes' => 'Matérias propostas',
353
+    'info_articles_un' => '1 matéria',
354
+    'info_auteurs_nombre' => 'autor(es):',
355
+    'info_authentification_ftp' => 'Autenticação (por FTP).',
356
+    'info_breves_2' => 'notas',
357
+    'info_breves_nb' => '@nb@ notas',
358
+    'info_breves_un' => '1 nota',
359
+    'info_connexion_refusee' => 'Conexão recusada',
360
+    'info_contact_developpeur' => 'Por favor, contate um desenvolvedor.',
361
+    'info_contenance' => 'Este site contém:',
362
+    'info_contribution' => 'contribuições',
363
+    'info_copyright' => '@spip@ é um software livre distribuído @lien_gpl@.',
364
+    'info_copyright_doc' => 'Para mais informações, veja o site <a href="@spipnet@">@spipnet_affiche@</a>.',
365
+    'info_copyright_gpl' => 'sob licença GPL',
366
+    'info_cours_edition' => 'Em edição',
367
+    'info_creer_repertoire' => 'Por favor, crie um arquivo ou diretório com o nome:',
368
+    'info_creer_repertoire_2' => 'dentro do subdiretório <b>@repertoire@</b>, e depois:',
369
+    'info_creer_vignette' => 'criação automática do ícone',
370
+    'info_creerdansrubrique_non_autorise' => 'Você não tem permissão para criar um conteúdo nesta seção',
371
+    'info_deplier' => 'Expandir',
372
+    'info_descriptif_nombre' => 'descrição(ões):',
373
+    'info_description' => 'Resumo:',
374
+    'info_description_2' => 'Resumo:',
375
+    'info_dimension' => 'Dimensões:',
376
+    'info_documents_nb' => '@nb@ documentos',
377
+    'info_documents_un' => '1 documento',
378
+    'info_ecire_message_prive' => 'Escrever uma mensagem privada',
379
+    'info_email_invalide' => 'Endereço de e-mail inválido.',
380
+    'info_en_cours_validation' => 'Suas matérias em fase de redação',
381
+    'info_en_ligne' => 'Atualmente online:',
382
+    'info_envoyer_message_prive' => 'Enviar uma mensagem privada a este autor',
383
+    'info_erreur_requete' => 'Erro na requisição:',
384
+    'info_erreur_squelette2' => 'Nenhum template <b>@fichier@</b> está disponível...',
385
+    'info_erreur_systeme' => 'Erro do sistema (errno @errsys@)',
386
+    'info_erreur_systeme2' => 'É possível que não haja espaço livre em disco, ou que a base de dados esteja corrompida.<br />
387 387
 <span style="color:red;">Tente <a href=\'@script@\'>reparar a base</a>, ou contate o seu serviço de hospedagem.</span>',
388
-	'info_fini' => 'Terminou!',
389
-	'info_format_image' => 'Formatos das imagens que podem ser utilizados para criar os ícones @gd_formats@.',
390
-	'info_format_non_defini' => 'formato não definido',
391
-	'info_grand_ecran' => 'Alta resolução',
392
-	'info_image_aide' => 'AJUDA',
393
-	'info_image_process_titre' => 'Método de criação dos ícones',
394
-	'info_impossible_lire_page' => '<b>Erro!</b> Impossível ler a página <tt><html>@test_proxy@</html></tt> via proxy',
395
-	'info_installation_systeme_publication' => 'Instalação do sistema de publicação...',
396
-	'info_installer_documents' => 'Você pode instalar automaticamente todos os documentos contídos no diretório @upload@.',
397
-	'info_installer_ftp' => 'Como administrador, você pode transferir (por FTP) arquivos para o diretório @upload@ para, em seguida, selecioná-los aqui diretamente.',
398
-	'info_installer_images' => 'Você pode transferir imagens nos formatos JPEG, GIF e PNG.',
399
-	'info_installer_images_dossier' => 'Transferir as imagens para o diretório @upload@ para poder selecioná-las aqui.',
400
-	'info_interface_complete' => 'interface completa',
401
-	'info_interface_simple' => 'Interface simplificada',
402
-	'info_joindre_document_article' => 'Você pode anexar a esta matéria documentos dos tipos a seguir',
403
-	'info_joindre_document_rubrique' => 'Você pode anexar a esta seção documentos dos tipos a seguir',
404
-	'info_joindre_documents_article' => 'Você pode anexar à sua matéria documentos dos tipos a seguir:',
405
-	'info_l_article' => 'a matéria',
406
-	'info_la_breve' => 'a nota',
407
-	'info_la_rubrique' => 'a seção',
408
-	'info_langue_principale' => 'Idioma principal do site',
409
-	'info_largeur_vignette' => '@largeur_vignette@ × @hauteur_vignette@ pixels',
410
-	'info_les_auteurs_1' => 'por @les_auteurs@',
411
-	'info_logo_format_interdit' => 'Apenas os ícones nos formatos @formats@ estão autorizados.',
412
-	'info_logo_max_poids' => 'Os ícones devem obrigatoriamente ter menos de @maxi@ (este arquivo tem @actuel@).',
413
-	'info_mail_fournisseur' => '[email protected]',
414
-	'info_message_2' => 'MENSAGEM',
415
-	'info_message_supprime' => 'MENSAGEM EXCLUÍDA',
416
-	'info_messages_nb' => '@nb@ mensagens',
417
-	'info_messages_un' => '1 mensagem',
418
-	'info_mise_en_ligne' => 'Data de publicação online:',
419
-	'info_modification_parametres_securite' => 'modificações dos parâmetros de segurança',
420
-	'info_mois_courant' => 'No mês corrente:',
421
-	'info_mot_cle_ajoute' => 'A palavra-chave a seguir foi associada a',
422
-	'info_multi_herit' => 'Idioma padrão',
423
-	'info_multi_langues_soulignees' => 'Os <u>idiomas sublinhados</u> dispõem de tradução total ou parcial dos textos da interface. Se você escolher esses idiomas, diversos elementos do site público (datas, formulários) são traduzidos automaticamente. Para os idiomas não sublinhados, estes elementos aparecerão no idioma principal do site.',
424
-	'info_multilinguisme' => 'Multilinguismo',
425
-	'info_nom_non_utilisateurs_connectes' => 'Seu nome não aparece na relação de usuários conectados.',
426
-	'info_nom_utilisateurs_connectes' => 'Seu nome aparecerá na relação de usuários conectados.',
427
-	'info_nombre_en_ligne' => 'Online neste momento:',
428
-	'info_non_resultat' => 'Nenhum resultados para "@cherche_mot@"',
429
-	'info_non_utilisation_messagerie' => 'Você não utiliza o sistema de mensagens deste site.',
430
-	'info_nouveau_message' => 'VOCÊ TEM UMA NOVA MENSAGEM',
431
-	'info_nouveaux_messages' => 'VOCÊ TEM @total_messages@ MENSAGENS NOVAS',
432
-	'info_numero_abbreviation' => 'N° ',
433
-	'info_obligatoire' => 'Esta informação é obrigatória',
434
-	'info_page_actuelle' => 'Página atual',
435
-	'info_pense_bete' => 'LEMBRETE',
436
-	'info_petit_ecran' => 'Baixa resolução',
437
-	'info_petition_close' => 'Petição fechada',
438
-	'info_pixels' => 'pixels',
439
-	'info_plusieurs_mots_trouves' => 'Várias palavras-chave encontradas para "@cherche_mot@":',
440
-	'info_portfolio_automatique' => 'Portfólio automático:',
441
-	'info_premier_resultat' => '[@debut_limit@ primeiros resultados de @total@]',
442
-	'info_premier_resultat_sur' => '[@debut_limit@ primeiros resultados de @total@]',
443
-	'info_propose_1' => '[@nom_site_spip@] Propõe: @titre@',
444
-	'info_propose_2' => 'Matéria proposta
388
+    'info_fini' => 'Terminou!',
389
+    'info_format_image' => 'Formatos das imagens que podem ser utilizados para criar os ícones @gd_formats@.',
390
+    'info_format_non_defini' => 'formato não definido',
391
+    'info_grand_ecran' => 'Alta resolução',
392
+    'info_image_aide' => 'AJUDA',
393
+    'info_image_process_titre' => 'Método de criação dos ícones',
394
+    'info_impossible_lire_page' => '<b>Erro!</b> Impossível ler a página <tt><html>@test_proxy@</html></tt> via proxy',
395
+    'info_installation_systeme_publication' => 'Instalação do sistema de publicação...',
396
+    'info_installer_documents' => 'Você pode instalar automaticamente todos os documentos contídos no diretório @upload@.',
397
+    'info_installer_ftp' => 'Como administrador, você pode transferir (por FTP) arquivos para o diretório @upload@ para, em seguida, selecioná-los aqui diretamente.',
398
+    'info_installer_images' => 'Você pode transferir imagens nos formatos JPEG, GIF e PNG.',
399
+    'info_installer_images_dossier' => 'Transferir as imagens para o diretório @upload@ para poder selecioná-las aqui.',
400
+    'info_interface_complete' => 'interface completa',
401
+    'info_interface_simple' => 'Interface simplificada',
402
+    'info_joindre_document_article' => 'Você pode anexar a esta matéria documentos dos tipos a seguir',
403
+    'info_joindre_document_rubrique' => 'Você pode anexar a esta seção documentos dos tipos a seguir',
404
+    'info_joindre_documents_article' => 'Você pode anexar à sua matéria documentos dos tipos a seguir:',
405
+    'info_l_article' => 'a matéria',
406
+    'info_la_breve' => 'a nota',
407
+    'info_la_rubrique' => 'a seção',
408
+    'info_langue_principale' => 'Idioma principal do site',
409
+    'info_largeur_vignette' => '@largeur_vignette@ × @hauteur_vignette@ pixels',
410
+    'info_les_auteurs_1' => 'por @les_auteurs@',
411
+    'info_logo_format_interdit' => 'Apenas os ícones nos formatos @formats@ estão autorizados.',
412
+    'info_logo_max_poids' => 'Os ícones devem obrigatoriamente ter menos de @maxi@ (este arquivo tem @actuel@).',
413
+    'info_mail_fournisseur' => '[email protected]',
414
+    'info_message_2' => 'MENSAGEM',
415
+    'info_message_supprime' => 'MENSAGEM EXCLUÍDA',
416
+    'info_messages_nb' => '@nb@ mensagens',
417
+    'info_messages_un' => '1 mensagem',
418
+    'info_mise_en_ligne' => 'Data de publicação online:',
419
+    'info_modification_parametres_securite' => 'modificações dos parâmetros de segurança',
420
+    'info_mois_courant' => 'No mês corrente:',
421
+    'info_mot_cle_ajoute' => 'A palavra-chave a seguir foi associada a',
422
+    'info_multi_herit' => 'Idioma padrão',
423
+    'info_multi_langues_soulignees' => 'Os <u>idiomas sublinhados</u> dispõem de tradução total ou parcial dos textos da interface. Se você escolher esses idiomas, diversos elementos do site público (datas, formulários) são traduzidos automaticamente. Para os idiomas não sublinhados, estes elementos aparecerão no idioma principal do site.',
424
+    'info_multilinguisme' => 'Multilinguismo',
425
+    'info_nom_non_utilisateurs_connectes' => 'Seu nome não aparece na relação de usuários conectados.',
426
+    'info_nom_utilisateurs_connectes' => 'Seu nome aparecerá na relação de usuários conectados.',
427
+    'info_nombre_en_ligne' => 'Online neste momento:',
428
+    'info_non_resultat' => 'Nenhum resultados para "@cherche_mot@"',
429
+    'info_non_utilisation_messagerie' => 'Você não utiliza o sistema de mensagens deste site.',
430
+    'info_nouveau_message' => 'VOCÊ TEM UMA NOVA MENSAGEM',
431
+    'info_nouveaux_messages' => 'VOCÊ TEM @total_messages@ MENSAGENS NOVAS',
432
+    'info_numero_abbreviation' => 'N° ',
433
+    'info_obligatoire' => 'Esta informação é obrigatória',
434
+    'info_page_actuelle' => 'Página atual',
435
+    'info_pense_bete' => 'LEMBRETE',
436
+    'info_petit_ecran' => 'Baixa resolução',
437
+    'info_petition_close' => 'Petição fechada',
438
+    'info_pixels' => 'pixels',
439
+    'info_plusieurs_mots_trouves' => 'Várias palavras-chave encontradas para "@cherche_mot@":',
440
+    'info_portfolio_automatique' => 'Portfólio automático:',
441
+    'info_premier_resultat' => '[@debut_limit@ primeiros resultados de @total@]',
442
+    'info_premier_resultat_sur' => '[@debut_limit@ primeiros resultados de @total@]',
443
+    'info_propose_1' => '[@nom_site_spip@] Propõe: @titre@',
444
+    'info_propose_2' => 'Matéria proposta
445 445
 ----------------',
446
-	'info_propose_3' => 'A matéria "@titre@" foi proposta para publicação.',
447
-	'info_propose_4' => 'Você está convidado a consultá-la e dar sua opinião',
448
-	'info_propose_5' => 'no fórum a ela anexado. Ela está disponível no endereço:',
449
-	'info_publie_01' => 'A matéria "@titre@" foi validada por @connect_nom@.',
450
-	'info_publie_1' => '[@nom_site_spip@] PUBLICADO: @titre@',
451
-	'info_publie_2' => 'Matéria publicada
446
+    'info_propose_3' => 'A matéria "@titre@" foi proposta para publicação.',
447
+    'info_propose_4' => 'Você está convidado a consultá-la e dar sua opinião',
448
+    'info_propose_5' => 'no fórum a ela anexado. Ela está disponível no endereço:',
449
+    'info_publie_01' => 'A matéria "@titre@" foi validada por @connect_nom@.',
450
+    'info_publie_1' => '[@nom_site_spip@] PUBLICADO: @titre@',
451
+    'info_publie_2' => 'Matéria publicada
452 452
 -----------------',
453
-	'info_rechercher' => 'Procurar',
454
-	'info_rechercher_02' => 'Procurar:',
455
-	'info_remplacer_vignette' => 'Substituir o ícone padrão por um logo personalizado:',
456
-	'info_rubriques_nb' => '@nb@ seções',
457
-	'info_rubriques_un' => '1 seção',
458
-	'info_sans_titre_2' => 'sem título',
459
-	'info_selectionner_fichier' => 'Você pode escolher um arquivo do diretório @upload@',
460
-	'info_selectionner_fichier_2' => 'Selecionar um arquivo:',
461
-	'info_sites_nb' => '@nb@ sites',
462
-	'info_sites_un' => '1 site',
463
-	'info_supprimer_vignette' => 'excluir o ícone',
464
-	'info_symbole_bleu' => 'O ícone <b>azul</b> indica um <b>lembrete</b>: ou seja, uma mensagem para seu uso pessoal.',
465
-	'info_symbole_jaune' => 'O ícone <b>amarelo</b> indica um  <b>anúncio para todos os redatores</b>: modificável por todos os administradores, e visível por todos os redatores.',
466
-	'info_symbole_vert' => 'O ícone <b>verde</b> indica as  <b>mensagens trocadas com outros usuários</b> do site.',
467
-	'info_telecharger_nouveau_logo' => 'Transferir um novo logo:',
468
-	'info_telecharger_ordinateur' => 'Tranferir do seu computador:',
469
-	'info_tous_resultats_enregistres' => '[todos os resultados são gravados]',
470
-	'info_tout_afficher' => 'Mostrar todas',
471
-	'info_travaux_texte' => 'Este site ainda não está configurado. Volte mais tarde...',
472
-	'info_travaux_titre' => 'Site em manutenção',
473
-	'info_trop_resultat' => 'Resultados de mais para "@cherche_mot@"; por favor, refine a busca.',
474
-	'info_utilisation_messagerie_interne' => 'Você usa o sistema interno de mensagens deste site.',
475
-	'info_valider_lien' => 'validar este link',
476
-	'info_verifier_image' => ', verifique se as suas imagens foram transferidas corretamente.',
477
-	'info_vignette_defaut' => 'Ícone padrão',
478
-	'info_vignette_personnalisee' => 'Ícone personalizado',
479
-	'info_visite' => 'visita:',
480
-	'info_vos_rendez_vous' => 'Seus encontros futuros',
481
-	'infos_vos_pense_bete' => 'Seus lembretes',
453
+    'info_rechercher' => 'Procurar',
454
+    'info_rechercher_02' => 'Procurar:',
455
+    'info_remplacer_vignette' => 'Substituir o ícone padrão por um logo personalizado:',
456
+    'info_rubriques_nb' => '@nb@ seções',
457
+    'info_rubriques_un' => '1 seção',
458
+    'info_sans_titre_2' => 'sem título',
459
+    'info_selectionner_fichier' => 'Você pode escolher um arquivo do diretório @upload@',
460
+    'info_selectionner_fichier_2' => 'Selecionar um arquivo:',
461
+    'info_sites_nb' => '@nb@ sites',
462
+    'info_sites_un' => '1 site',
463
+    'info_supprimer_vignette' => 'excluir o ícone',
464
+    'info_symbole_bleu' => 'O ícone <b>azul</b> indica um <b>lembrete</b>: ou seja, uma mensagem para seu uso pessoal.',
465
+    'info_symbole_jaune' => 'O ícone <b>amarelo</b> indica um  <b>anúncio para todos os redatores</b>: modificável por todos os administradores, e visível por todos os redatores.',
466
+    'info_symbole_vert' => 'O ícone <b>verde</b> indica as  <b>mensagens trocadas com outros usuários</b> do site.',
467
+    'info_telecharger_nouveau_logo' => 'Transferir um novo logo:',
468
+    'info_telecharger_ordinateur' => 'Tranferir do seu computador:',
469
+    'info_tous_resultats_enregistres' => '[todos os resultados são gravados]',
470
+    'info_tout_afficher' => 'Mostrar todas',
471
+    'info_travaux_texte' => 'Este site ainda não está configurado. Volte mais tarde...',
472
+    'info_travaux_titre' => 'Site em manutenção',
473
+    'info_trop_resultat' => 'Resultados de mais para "@cherche_mot@"; por favor, refine a busca.',
474
+    'info_utilisation_messagerie_interne' => 'Você usa o sistema interno de mensagens deste site.',
475
+    'info_valider_lien' => 'validar este link',
476
+    'info_verifier_image' => ', verifique se as suas imagens foram transferidas corretamente.',
477
+    'info_vignette_defaut' => 'Ícone padrão',
478
+    'info_vignette_personnalisee' => 'Ícone personalizado',
479
+    'info_visite' => 'visita:',
480
+    'info_vos_rendez_vous' => 'Seus encontros futuros',
481
+    'infos_vos_pense_bete' => 'Seus lembretes',
482 482
 
483
-	// L
484
-	'label_ajout_id_rapide' => 'Ajuda rápida',
485
-	'label_poids_fichier' => 'Tamanho',
486
-	'label_ponctuer' => '@label@:',
487
-	'lien_afficher_icones_seuls' => 'Exibir apenas os ícones',
488
-	'lien_afficher_texte_icones' => 'Exibir ícones e texto',
489
-	'lien_afficher_texte_seul' => 'Exibir apenas o texto',
490
-	'lien_aller_a_la_derniere_page' => 'Ir para a última página',
491
-	'lien_aller_a_la_page_nb' => 'Ir para a página @nb@',
492
-	'lien_aller_a_la_page_precedente' => 'Ir para a página anterior',
493
-	'lien_aller_a_la_page_suivante' => 'Ir para a página seguinte',
494
-	'lien_aller_a_la_premiere_page' => 'Ir para a primeira página',
495
-	'lien_liberer' => 'liberar',
496
-	'lien_liberer_tous' => 'liberar todas',
497
-	'lien_nouvea_pense_bete' => 'NOVO LEMBRETE',
498
-	'lien_nouveau_message' => 'NOVA MENSAGEM',
499
-	'lien_nouvelle_annonce' => 'NOVO ANÚNCIO',
500
-	'lien_petitions' => 'PETIÇÃO',
501
-	'lien_popularite' => 'popularidade: @popularite@%',
502
-	'lien_racine_site' => 'RAIZ DO SITE',
503
-	'lien_reessayer' => 'tente novamente',
504
-	'lien_repondre_message' => 'Responder a esta mensagem',
505
-	'lien_supprimer' => 'excluir',
506
-	'lien_tout_afficher' => 'Mostrar tudo',
507
-	'lien_visite_site' => 'visitar este site',
508
-	'lien_visites' => '@visites@ visitas',
509
-	'lien_voir_auteur' => 'Ver este autor',
510
-	'ligne' => 'Linha',
511
-	'login' => 'Conexão',
512
-	'login_acces_prive' => 'acesso ao espaço privado',
513
-	'login_autre_identifiant' => 'conectar-se com outra identificação',
514
-	'login_cookie_accepte' => 'Por favor, configure o seu navegador para aceitá-los (pelo menos para este site).',
515
-	'login_cookie_oblige' => 'Para você se identificar de modo seguro neste site, você precisa aceitar cookies.',
516
-	'login_deconnexion_ok' => 'Desconexão efetuada.',
517
-	'login_erreur_pass' => 'Erro de senha.',
518
-	'login_espace_prive' => 'espaço privado',
519
-	'login_identifiant_inconnu' => 'O identificador «@login@» não está cadastrado.',
520
-	'login_login' => 'Login:',
521
-	'login_login2' => 'Login',
522
-	'login_login_pass_incorrect' => '(Login ou senha incorreta.)',
523
-	'login_motpasseoublie' => 'esqueceu sua senha?',
524
-	'login_non_securise' => 'Atenção, este formulário não é seguro.
483
+    // L
484
+    'label_ajout_id_rapide' => 'Ajuda rápida',
485
+    'label_poids_fichier' => 'Tamanho',
486
+    'label_ponctuer' => '@label@:',
487
+    'lien_afficher_icones_seuls' => 'Exibir apenas os ícones',
488
+    'lien_afficher_texte_icones' => 'Exibir ícones e texto',
489
+    'lien_afficher_texte_seul' => 'Exibir apenas o texto',
490
+    'lien_aller_a_la_derniere_page' => 'Ir para a última página',
491
+    'lien_aller_a_la_page_nb' => 'Ir para a página @nb@',
492
+    'lien_aller_a_la_page_precedente' => 'Ir para a página anterior',
493
+    'lien_aller_a_la_page_suivante' => 'Ir para a página seguinte',
494
+    'lien_aller_a_la_premiere_page' => 'Ir para a primeira página',
495
+    'lien_liberer' => 'liberar',
496
+    'lien_liberer_tous' => 'liberar todas',
497
+    'lien_nouvea_pense_bete' => 'NOVO LEMBRETE',
498
+    'lien_nouveau_message' => 'NOVA MENSAGEM',
499
+    'lien_nouvelle_annonce' => 'NOVO ANÚNCIO',
500
+    'lien_petitions' => 'PETIÇÃO',
501
+    'lien_popularite' => 'popularidade: @popularite@%',
502
+    'lien_racine_site' => 'RAIZ DO SITE',
503
+    'lien_reessayer' => 'tente novamente',
504
+    'lien_repondre_message' => 'Responder a esta mensagem',
505
+    'lien_supprimer' => 'excluir',
506
+    'lien_tout_afficher' => 'Mostrar tudo',
507
+    'lien_visite_site' => 'visitar este site',
508
+    'lien_visites' => '@visites@ visitas',
509
+    'lien_voir_auteur' => 'Ver este autor',
510
+    'ligne' => 'Linha',
511
+    'login' => 'Conexão',
512
+    'login_acces_prive' => 'acesso ao espaço privado',
513
+    'login_autre_identifiant' => 'conectar-se com outra identificação',
514
+    'login_cookie_accepte' => 'Por favor, configure o seu navegador para aceitá-los (pelo menos para este site).',
515
+    'login_cookie_oblige' => 'Para você se identificar de modo seguro neste site, você precisa aceitar cookies.',
516
+    'login_deconnexion_ok' => 'Desconexão efetuada.',
517
+    'login_erreur_pass' => 'Erro de senha.',
518
+    'login_espace_prive' => 'espaço privado',
519
+    'login_identifiant_inconnu' => 'O identificador «@login@» não está cadastrado.',
520
+    'login_login' => 'Login:',
521
+    'login_login2' => 'Login',
522
+    'login_login_pass_incorrect' => '(Login ou senha incorreta.)',
523
+    'login_motpasseoublie' => 'esqueceu sua senha?',
524
+    'login_non_securise' => 'Atenção, este formulário não é seguro.
525 525
 Se você não quiser que a sua senha possa ser interceptada na rede, por favor ative o Javascript no seu navegador e',
526
-	'login_nouvelle_tentative' => 'Tentar novamente',
527
-	'login_par_ici' => 'VocÊ está registrado... por aqui...',
528
-	'login_pass2' => 'Senha:',
529
-	'login_preferez_refuser' => '<b>Se você prefere recusar os cookies</b>, um outro método de conexão (menos seguro) está disponível:',
530
-	'login_recharger' => 'atualizar esta página',
531
-	'login_rester_identifie' => 'Manter-se identificado',
532
-	'login_retour_public' => 'Voltar ao site público',
533
-	'login_retour_site' => 'Voltar ao site público',
534
-	'login_retoursitepublic' => 'voltar ao site público',
535
-	'login_sans_cookie' => 'Identificação sem cookie',
536
-	'login_securise' => 'Login seguro',
537
-	'login_sinscrire' => 'Cadastrar-se',
538
-	'login_test_navigateur' => 'testar navegador/reconexão',
539
-	'login_verifiez_navigateur' => '(Verifique sempre se o seu navegador não está memorizando a sua senha...)',
526
+    'login_nouvelle_tentative' => 'Tentar novamente',
527
+    'login_par_ici' => 'VocÊ está registrado... por aqui...',
528
+    'login_pass2' => 'Senha:',
529
+    'login_preferez_refuser' => '<b>Se você prefere recusar os cookies</b>, um outro método de conexão (menos seguro) está disponível:',
530
+    'login_recharger' => 'atualizar esta página',
531
+    'login_rester_identifie' => 'Manter-se identificado',
532
+    'login_retour_public' => 'Voltar ao site público',
533
+    'login_retour_site' => 'Voltar ao site público',
534
+    'login_retoursitepublic' => 'voltar ao site público',
535
+    'login_sans_cookie' => 'Identificação sem cookie',
536
+    'login_securise' => 'Login seguro',
537
+    'login_sinscrire' => 'Cadastrar-se',
538
+    'login_test_navigateur' => 'testar navegador/reconexão',
539
+    'login_verifiez_navigateur' => '(Verifique sempre se o seu navegador não está memorizando a sua senha...)',
540 540
 
541
-	// M
542
-	'masquer_colonne' => 'Ocultar esta coluna',
543
-	'masquer_trad' => 'esconder as traduções',
544
-	'message_nouveaux_identifiants_echec' => 'Impossível criar novos logins.',
545
-	'message_nouveaux_identifiants_echec_envoi' => 'Os novos logins de conexão não puderam ser enviados.',
546
-	'message_nouveaux_identifiants_ok' => 'Os novos logins de conexão foram enviados para @email@.',
547
-	'module_fichiers_langues' => 'Arquivos de idioma',
541
+    // M
542
+    'masquer_colonne' => 'Ocultar esta coluna',
543
+    'masquer_trad' => 'esconder as traduções',
544
+    'message_nouveaux_identifiants_echec' => 'Impossível criar novos logins.',
545
+    'message_nouveaux_identifiants_echec_envoi' => 'Os novos logins de conexão não puderam ser enviados.',
546
+    'message_nouveaux_identifiants_ok' => 'Os novos logins de conexão foram enviados para @email@.',
547
+    'module_fichiers_langues' => 'Arquivos de idioma',
548 548
 
549
-	// N
550
-	'navigateur_pas_redirige' => 'Se o seu navegador não o redirecionar, clique aqui para continuar.',
551
-	'numero' => 'Número',
549
+    // N
550
+    'navigateur_pas_redirige' => 'Se o seu navegador não o redirecionar, clique aqui para continuar.',
551
+    'numero' => 'Número',
552 552
 
553
-	// O
554
-	'occurence' => 'Ocorrência',
555
-	'onglet_affacer_base' => 'Apagar a base',
556
-	'onglet_auteur' => 'O autor',
557
-	'onglet_contenu_site' => 'Conteúdo do site',
558
-	'onglet_evolution_visite_mod' => 'Evolução',
559
-	'onglet_fonctions_avances' => 'Funções avançadas',
560
-	'onglet_informations_personnelles' => 'Informações pessoais',
561
-	'onglet_interactivite' => 'Interatividade',
562
-	'onglet_messagerie' => 'Sistema de mensagens',
563
-	'onglet_repartition_rubrique' => 'Repartição por seções',
564
-	'onglet_save_restaur_base' => 'Fazer cópia de segurança/restaurar a base',
565
-	'onglet_vider_cache' => 'Esvaziar o cache',
553
+    // O
554
+    'occurence' => 'Ocorrência',
555
+    'onglet_affacer_base' => 'Apagar a base',
556
+    'onglet_auteur' => 'O autor',
557
+    'onglet_contenu_site' => 'Conteúdo do site',
558
+    'onglet_evolution_visite_mod' => 'Evolução',
559
+    'onglet_fonctions_avances' => 'Funções avançadas',
560
+    'onglet_informations_personnelles' => 'Informações pessoais',
561
+    'onglet_interactivite' => 'Interatividade',
562
+    'onglet_messagerie' => 'Sistema de mensagens',
563
+    'onglet_repartition_rubrique' => 'Repartição por seções',
564
+    'onglet_save_restaur_base' => 'Fazer cópia de segurança/restaurar a base',
565
+    'onglet_vider_cache' => 'Esvaziar o cache',
566 566
 
567
-	// P
568
-	'pass_choix_pass' => 'Por favor, escolha a sua nova senha:',
569
-	'pass_erreur' => 'Erro',
570
-	'pass_erreur_acces_refuse' => '<b>Erro:</b> você não tem mais acesso a este site.',
571
-	'pass_erreur_code_inconnu' => '<b>Erro:</b> este login não corresponde a nenhum visitante com permissão de acesso a este site.',
572
-	'pass_erreur_non_enregistre' => '<b>Erro:</b> o e-mail <tt>@email_oubli@</tt> não está cadastrado neste site.',
573
-	'pass_erreur_non_valide' => '<b>Erro:</b> o e-mail <tt>@email_oubli@</tt> não é válido!',
574
-	'pass_erreur_probleme_technique' => '<b>Erro:</b> este e-mail não pôde ser enviado devido a um problema técnico.',
575
-	'pass_espace_prive_bla' => 'O espaço privado deste site é aberto aos visitantes, após inscrição. Uma vez cadastrado, você poderá consultar as matérias em fase de redação, propor a publicação de novas matérias e participar de todos os fóruns.',
576
-	'pass_forum_bla' => 'Você soliciou a participação num fórum reservado a visitantes registrados.',
577
-	'pass_indiquez_cidessous' => 'Informe abaixo o endereço de e-mail com o qual você se cadastrou anteriormente. Você receberá um e-mail lhe indicando os procedimentos a seguir para recuperar o seu acesso.',
578
-	'pass_mail_passcookie' => '(esta é uma mensagem automática)
567
+    // P
568
+    'pass_choix_pass' => 'Por favor, escolha a sua nova senha:',
569
+    'pass_erreur' => 'Erro',
570
+    'pass_erreur_acces_refuse' => '<b>Erro:</b> você não tem mais acesso a este site.',
571
+    'pass_erreur_code_inconnu' => '<b>Erro:</b> este login não corresponde a nenhum visitante com permissão de acesso a este site.',
572
+    'pass_erreur_non_enregistre' => '<b>Erro:</b> o e-mail <tt>@email_oubli@</tt> não está cadastrado neste site.',
573
+    'pass_erreur_non_valide' => '<b>Erro:</b> o e-mail <tt>@email_oubli@</tt> não é válido!',
574
+    'pass_erreur_probleme_technique' => '<b>Erro:</b> este e-mail não pôde ser enviado devido a um problema técnico.',
575
+    'pass_espace_prive_bla' => 'O espaço privado deste site é aberto aos visitantes, após inscrição. Uma vez cadastrado, você poderá consultar as matérias em fase de redação, propor a publicação de novas matérias e participar de todos os fóruns.',
576
+    'pass_forum_bla' => 'Você soliciou a participação num fórum reservado a visitantes registrados.',
577
+    'pass_indiquez_cidessous' => 'Informe abaixo o endereço de e-mail com o qual você se cadastrou anteriormente. Você receberá um e-mail lhe indicando os procedimentos a seguir para recuperar o seu acesso.',
578
+    'pass_mail_passcookie' => '(esta é uma mensagem automática)
579 579
 Para recuperar o seu acesso ao site
580 580
 @nom_site_spip@ (@adresse_site@)
581 581
 
@@ -587,140 +587,140 @@  discard block
 block discarded – undo
587 587
 e reconectar-se com o site.
588 588
 
589 589
 ',
590
-	'pass_mot_oublie' => 'Senha esquecida',
591
-	'pass_nouveau_enregistre' => 'Sua nova senha foi cadastrada.',
592
-	'pass_nouveau_pass' => 'Nova senha',
593
-	'pass_ok' => 'OK',
594
-	'pass_oubli_mot' => 'Esquecimento de senha',
595
-	'pass_procedure_changer' => 'Para alterar a sua senha, por favor informe o endereço de e-mail associado à sua conta.',
596
-	'pass_quitter_fenetre' => 'Fechar esta janela',
597
-	'pass_rappel_login' => 'Lembrete: seu login é «@login@».',
598
-	'pass_recevoir_mail' => 'Um link para redefinição da sua senha foi enviado para o seu endereço de e-mail (se ele for válido).',
599
-	'pass_retour_public' => 'Voltar para o site público',
600
-	'pass_rien_a_faire_ici' => 'Nada a fazer aqui.',
601
-	'pass_vousinscrire' => 'Cadastrar-se neste site',
602
-	'precedent' => 'precedente',
603
-	'previsualisation' => 'Visualização',
604
-	'previsualiser' => 'Visualizar',
590
+    'pass_mot_oublie' => 'Senha esquecida',
591
+    'pass_nouveau_enregistre' => 'Sua nova senha foi cadastrada.',
592
+    'pass_nouveau_pass' => 'Nova senha',
593
+    'pass_ok' => 'OK',
594
+    'pass_oubli_mot' => 'Esquecimento de senha',
595
+    'pass_procedure_changer' => 'Para alterar a sua senha, por favor informe o endereço de e-mail associado à sua conta.',
596
+    'pass_quitter_fenetre' => 'Fechar esta janela',
597
+    'pass_rappel_login' => 'Lembrete: seu login é «@login@».',
598
+    'pass_recevoir_mail' => 'Um link para redefinição da sua senha foi enviado para o seu endereço de e-mail (se ele for válido).',
599
+    'pass_retour_public' => 'Voltar para o site público',
600
+    'pass_rien_a_faire_ici' => 'Nada a fazer aqui.',
601
+    'pass_vousinscrire' => 'Cadastrar-se neste site',
602
+    'precedent' => 'precedente',
603
+    'previsualisation' => 'Visualização',
604
+    'previsualiser' => 'Visualizar',
605 605
 
606
-	// R
607
-	'retour' => 'Voltar',
606
+    // R
607
+    'retour' => 'Voltar',
608 608
 
609
-	// S
610
-	'spip_conforme_dtd' => 'O SPIP considera este documento de acordo com o seu DOCTYPE:',
611
-	'squelette' => 'template',
612
-	'squelette_inclus_ligne' => 'template incluído, linha',
613
-	'squelette_ligne' => 'template, linha',
614
-	'stats_visites_et_popularite' => '@visites@ visitas; popularidade: @popularite@',
615
-	'suivant' => 'seguinte',
609
+    // S
610
+    'spip_conforme_dtd' => 'O SPIP considera este documento de acordo com o seu DOCTYPE:',
611
+    'squelette' => 'template',
612
+    'squelette_inclus_ligne' => 'template incluído, linha',
613
+    'squelette_ligne' => 'template, linha',
614
+    'stats_visites_et_popularite' => '@visites@ visitas; popularidade: @popularite@',
615
+    'suivant' => 'seguinte',
616 616
 
617
-	// T
618
-	'taille_go' => '@taille@ GB',
619
-	'taille_go_bi' => '@taille@ GB',
620
-	'taille_ko' => '@taille@ KB',
621
-	'taille_ko_bi' => '@taille@ kB',
622
-	'taille_mo' => '@taille@ MB',
623
-	'taille_mo_bi' => '@taille@ MB',
624
-	'taille_octets' => ' @taille@ bytes',
625
-	'taille_octets_bi' => ' @taille@ bytes',
626
-	'texte_actualite_site_1' => 'Quando você estiver mais familiarizado com a interface, clique em «',
627
-	'texte_actualite_site_2' => 'interface completa',
628
-	'texte_actualite_site_3' => '» para abrir mais possibilidades.',
629
-	'texte_creation_automatique_vignette' => 'A criação automática de ícones de visualização está ativada neste site. Se você transferir por este formulário imagens no(s) formato(s) @gd_formats@, elas serão acompanhadas de um ícone com o tamanho máximo de @taille_preview@ pixels.',
630
-	'texte_documents_associes' => 'Os documentos a seguir estão associados à matéria,
617
+    // T
618
+    'taille_go' => '@taille@ GB',
619
+    'taille_go_bi' => '@taille@ GB',
620
+    'taille_ko' => '@taille@ KB',
621
+    'taille_ko_bi' => '@taille@ kB',
622
+    'taille_mo' => '@taille@ MB',
623
+    'taille_mo_bi' => '@taille@ MB',
624
+    'taille_octets' => ' @taille@ bytes',
625
+    'taille_octets_bi' => ' @taille@ bytes',
626
+    'texte_actualite_site_1' => 'Quando você estiver mais familiarizado com a interface, clique em «',
627
+    'texte_actualite_site_2' => 'interface completa',
628
+    'texte_actualite_site_3' => '» para abrir mais possibilidades.',
629
+    'texte_creation_automatique_vignette' => 'A criação automática de ícones de visualização está ativada neste site. Se você transferir por este formulário imagens no(s) formato(s) @gd_formats@, elas serão acompanhadas de um ícone com o tamanho máximo de @taille_preview@ pixels.',
630
+    'texte_documents_associes' => 'Os documentos a seguir estão associados à matéria,
631 631
 mas eles não foram inseridos diretamente. Dependendo da elaboração dos templates do site público, eles podem aparecer como documentos anexados.',
632
-	'texte_erreur_mise_niveau_base' => 'Erro da base de dados durante a atualização.
632
+    'texte_erreur_mise_niveau_base' => 'Erro da base de dados durante a atualização.
633 633
 A imagem <b>@fichier@</b> não passou (matéria @id_article@).
634 634
 Anote esta referência, tente novamente a atualização e, finalmente, verifique se as imagens aparecem nas matérias.',
635
-	'texte_erreur_visiteur' => 'Você tentou acessar o espaço restrito com um login que não tem a permissão necessária.',
636
-	'texte_inc_auth_1' => 'Você se identificou com o login <b>@auth_login@</b>, mas ele não consta (mais) na base.
635
+    'texte_erreur_visiteur' => 'Você tentou acessar o espaço restrito com um login que não tem a permissão necessária.',
636
+    'texte_inc_auth_1' => 'Você se identificou com o login <b>@auth_login@</b>, mas ele não consta (mais) na base.
637 637
 Tente se',
638
-	'texte_inc_auth_2' => 'reconectar',
639
-	'texte_inc_auth_3' => ', após ter eventualmente saído e reiniciado o seu navegador.',
640
-	'texte_inc_config' => 'As modificações efetuadas nestas páginas influem consideravelmente no funcionamento do seu site. É recomendável não intervir enquanto você não estiver familiarizado com o funcionamento do sistema SPIP.<br /><br /><b>Geralmente, é fortemente aconselhável deixar a carga destas páginas para o webmaster principal do seu site.</b>',
641
-	'texte_inc_meta_1' => 'O sistema encontrou um erro durante a escrita do arquivo <code>@fichier@</code>. Como administrador do site, queira por favor,',
642
-	'texte_inc_meta_2' => 'Verificar os direitos de escrita',
643
-	'texte_inc_meta_3' => 'no diretório <code>@repertoire@</code>.',
644
-	'texte_statut_en_cours_redaction' => 'em fase de redação',
645
-	'texte_statut_poubelle' => 'na lixeira',
646
-	'texte_statut_propose_evaluation' => 'proposto para avaliação',
647
-	'texte_statut_publie' => 'publicado online',
648
-	'texte_statut_refuse' => 'recusado',
649
-	'titre_ajouter_mot_cle' => 'INCLUIR UMA PALAVRA-CHAVE:',
650
-	'titre_cadre_raccourcis' => 'ATALHOS:',
651
-	'titre_changer_couleur_interface' => 'Alterar a côr da interface',
652
-	'titre_image_admin_article' => 'Você pode administrar esta matéria',
653
-	'titre_image_administrateur' => 'Administrador',
654
-	'titre_image_aide' => 'Ajuda sobre este elemento',
655
-	'titre_image_auteur_supprime' => 'Autor excluído',
656
-	'titre_image_redacteur' => 'Redator sem acesso',
657
-	'titre_image_redacteur_02' => 'Redator',
658
-	'titre_image_selecteur' => 'Ver a lista',
659
-	'titre_image_visiteur' => 'Visitante',
660
-	'titre_joindre_document' => 'INCLUIR UM DOCUMENTO',
661
-	'titre_mots_cles' => 'PALAVRAS-CHAVE',
662
-	'titre_probleme_technique' => 'Atenção: um problema técnico (servidor SQL) impede o acesso a esta parte do site. Agradecemos sua compreensão.',
663
-	'titre_publier_document' => 'PUBLICAR UM DOCUMENTO NESTA SEÇÃO',
664
-	'titre_signatures_attente' => 'Assinaturas aguardando validação',
665
-	'titre_signatures_confirmees' => 'Assinaturas confirmadas',
666
-	'titre_statistiques' => 'Estatísticas do site',
667
-	'titre_titre_document' => 'Título do documento:',
668
-	'todo' => 'breve',
669
-	'trad_definir_reference' => 'Escolher "@titre@" como referência das traduções',
670
-	'trad_reference' => '(matéria das traduções)',
638
+    'texte_inc_auth_2' => 'reconectar',
639
+    'texte_inc_auth_3' => ', após ter eventualmente saído e reiniciado o seu navegador.',
640
+    'texte_inc_config' => 'As modificações efetuadas nestas páginas influem consideravelmente no funcionamento do seu site. É recomendável não intervir enquanto você não estiver familiarizado com o funcionamento do sistema SPIP.<br /><br /><b>Geralmente, é fortemente aconselhável deixar a carga destas páginas para o webmaster principal do seu site.</b>',
641
+    'texte_inc_meta_1' => 'O sistema encontrou um erro durante a escrita do arquivo <code>@fichier@</code>. Como administrador do site, queira por favor,',
642
+    'texte_inc_meta_2' => 'Verificar os direitos de escrita',
643
+    'texte_inc_meta_3' => 'no diretório <code>@repertoire@</code>.',
644
+    'texte_statut_en_cours_redaction' => 'em fase de redação',
645
+    'texte_statut_poubelle' => 'na lixeira',
646
+    'texte_statut_propose_evaluation' => 'proposto para avaliação',
647
+    'texte_statut_publie' => 'publicado online',
648
+    'texte_statut_refuse' => 'recusado',
649
+    'titre_ajouter_mot_cle' => 'INCLUIR UMA PALAVRA-CHAVE:',
650
+    'titre_cadre_raccourcis' => 'ATALHOS:',
651
+    'titre_changer_couleur_interface' => 'Alterar a côr da interface',
652
+    'titre_image_admin_article' => 'Você pode administrar esta matéria',
653
+    'titre_image_administrateur' => 'Administrador',
654
+    'titre_image_aide' => 'Ajuda sobre este elemento',
655
+    'titre_image_auteur_supprime' => 'Autor excluído',
656
+    'titre_image_redacteur' => 'Redator sem acesso',
657
+    'titre_image_redacteur_02' => 'Redator',
658
+    'titre_image_selecteur' => 'Ver a lista',
659
+    'titre_image_visiteur' => 'Visitante',
660
+    'titre_joindre_document' => 'INCLUIR UM DOCUMENTO',
661
+    'titre_mots_cles' => 'PALAVRAS-CHAVE',
662
+    'titre_probleme_technique' => 'Atenção: um problema técnico (servidor SQL) impede o acesso a esta parte do site. Agradecemos sua compreensão.',
663
+    'titre_publier_document' => 'PUBLICAR UM DOCUMENTO NESTA SEÇÃO',
664
+    'titre_signatures_attente' => 'Assinaturas aguardando validação',
665
+    'titre_signatures_confirmees' => 'Assinaturas confirmadas',
666
+    'titre_statistiques' => 'Estatísticas do site',
667
+    'titre_titre_document' => 'Título do documento:',
668
+    'todo' => 'breve',
669
+    'trad_definir_reference' => 'Escolher "@titre@" como referência das traduções',
670
+    'trad_reference' => '(matéria das traduções)',
671 671
 
672
-	// U
673
-	'upload_limit' => 'Este arquivo é grande demais para o servidor; o tamanho máximo autorizado para <i>upload</i> é de @max@.',
672
+    // U
673
+    'upload_limit' => 'Este arquivo é grande demais para o servidor; o tamanho máximo autorizado para <i>upload</i> é de @max@.',
674 674
 
675
-	// Z
676
-	'zbug_balise_b_aval' => ': tag B colocada após BOUCLE',
677
-	'zbug_balise_inexistante' => 'Tag @balise@ mal declarada para @from@',
678
-	'zbug_balise_sans_argument' => 'Falta um arqumento na tag @balise@',
679
-	'zbug_boucle' => 'laço',
680
-	'zbug_boucle_recursive_undef' => 'Laço recursivo não definido: @nom@',
681
-	'zbug_calcul' => 'cálculo',
682
-	'zbug_champ_hors_boucle' => 'Campo @champ@ fora do laço',
683
-	'zbug_champ_hors_critere' => 'Campo @champ@ fora do critério @critere@',
684
-	'zbug_champ_hors_motif' => 'Campo @champ@ fora de um contexto @motif@',
685
-	'zbug_code' => 'código',
686
-	'zbug_critere_inconnu' => 'Critério @critere@ desconhecido',
687
-	'zbug_critere_sur_table_sans_cle_primaire' => '{@critere@} em uma tabela sem chave primária atômica',
688
-	'zbug_distant_interdit' => 'Externa interdita',
689
-	'zbug_doublon_table_sans_cle_primaire' => 'Duplicação em tabela sem chave primária atômica',
690
-	'zbug_doublon_table_sans_index' => 'Doublons em uma tabela sem index',
691
-	'zbug_erreur_boucle_double' => 'Dupla definição do laço @id@',
692
-	'zbug_erreur_boucle_fermant' => 'Laço @id@ não fechado',
693
-	'zbug_erreur_boucle_syntaxe' => 'Sintaxe do laço @id@ está incorreta',
694
-	'zbug_erreur_compilation' => 'Erro de compilação',
695
-	'zbug_erreur_execution_page' => 'Erro de execução',
696
-	'zbug_erreur_filtre' => 'Filtro @filtre@ não definido',
697
-	'zbug_erreur_filtre_nbarg_min' => 'Filtro @filtre@: falta(m) @nb@ argumento(s)',
698
-	'zbug_erreur_meme_parent' => 'O critério {meme_parent} aplica-se exclusivamente aos laços (FORUMS) ou (RUBRIQUES)',
699
-	'zbug_erreur_squelette' => 'Erro(s) no template',
700
-	'zbug_hors_compilation' => 'Fora de Compilação',
701
-	'zbug_info_erreur_squelette' => 'Erro no site',
702
-	'zbug_inversion_ordre_inexistant' => 'Inversão de uma ordem inexistente',
703
-	'zbug_pagination_sans_critere' => 'Tag #PAGINATION sem critério {pagination} ou usada dentro de uma boucle recursiva',
704
-	'zbug_parametres_inclus_incorrects' => 'Parâmetro de inclusão incorreto: @param@',
705
-	'zbug_profile' => 'Tempo de processamento: @time@',
706
-	'zbug_resultat' => 'resultado',
707
-	'zbug_serveur_indefini' => 'Sevidor SQL não definido',
708
-	'zbug_statistiques' => 'Estatísticas das requisições SQL classificadas por duração',
709
-	'zbug_table_inconnue' => 'Tabela SQL «@table@» desconhecida',
710
-	'zxml_connus_attributs' => 'atributos conhecidos',
711
-	'zxml_de' => 'de',
712
-	'zxml_inconnu_attribut' => 'atributo desconhecido',
713
-	'zxml_inconnu_balise' => 'tag desconhecida',
714
-	'zxml_inconnu_entite' => 'entidade desconhecida',
715
-	'zxml_inconnu_id' => 'ID desconhecida',
716
-	'zxml_mais_de' => 'mas de',
717
-	'zxml_non_conforme' => 'não está de acordo com o motivo',
718
-	'zxml_non_fils' => 'não é filho de',
719
-	'zxml_nonvide_balise' => 'tag não vazia',
720
-	'zxml_obligatoire_attribut' => 'atributo obrigatório mas ausente em',
721
-	'zxml_succession_fils_incorrecte' => 'sucessão de filhos incorreta',
722
-	'zxml_survoler' => 'sobrepor para ver os corretos',
723
-	'zxml_valeur_attribut' => 'valor do atributo',
724
-	'zxml_vide_balise' => 'tag vazia',
725
-	'zxml_vu' => 'previsualização',
675
+    // Z
676
+    'zbug_balise_b_aval' => ': tag B colocada após BOUCLE',
677
+    'zbug_balise_inexistante' => 'Tag @balise@ mal declarada para @from@',
678
+    'zbug_balise_sans_argument' => 'Falta um arqumento na tag @balise@',
679
+    'zbug_boucle' => 'laço',
680
+    'zbug_boucle_recursive_undef' => 'Laço recursivo não definido: @nom@',
681
+    'zbug_calcul' => 'cálculo',
682
+    'zbug_champ_hors_boucle' => 'Campo @champ@ fora do laço',
683
+    'zbug_champ_hors_critere' => 'Campo @champ@ fora do critério @critere@',
684
+    'zbug_champ_hors_motif' => 'Campo @champ@ fora de um contexto @motif@',
685
+    'zbug_code' => 'código',
686
+    'zbug_critere_inconnu' => 'Critério @critere@ desconhecido',
687
+    'zbug_critere_sur_table_sans_cle_primaire' => '{@critere@} em uma tabela sem chave primária atômica',
688
+    'zbug_distant_interdit' => 'Externa interdita',
689
+    'zbug_doublon_table_sans_cle_primaire' => 'Duplicação em tabela sem chave primária atômica',
690
+    'zbug_doublon_table_sans_index' => 'Doublons em uma tabela sem index',
691
+    'zbug_erreur_boucle_double' => 'Dupla definição do laço @id@',
692
+    'zbug_erreur_boucle_fermant' => 'Laço @id@ não fechado',
693
+    'zbug_erreur_boucle_syntaxe' => 'Sintaxe do laço @id@ está incorreta',
694
+    'zbug_erreur_compilation' => 'Erro de compilação',
695
+    'zbug_erreur_execution_page' => 'Erro de execução',
696
+    'zbug_erreur_filtre' => 'Filtro @filtre@ não definido',
697
+    'zbug_erreur_filtre_nbarg_min' => 'Filtro @filtre@: falta(m) @nb@ argumento(s)',
698
+    'zbug_erreur_meme_parent' => 'O critério {meme_parent} aplica-se exclusivamente aos laços (FORUMS) ou (RUBRIQUES)',
699
+    'zbug_erreur_squelette' => 'Erro(s) no template',
700
+    'zbug_hors_compilation' => 'Fora de Compilação',
701
+    'zbug_info_erreur_squelette' => 'Erro no site',
702
+    'zbug_inversion_ordre_inexistant' => 'Inversão de uma ordem inexistente',
703
+    'zbug_pagination_sans_critere' => 'Tag #PAGINATION sem critério {pagination} ou usada dentro de uma boucle recursiva',
704
+    'zbug_parametres_inclus_incorrects' => 'Parâmetro de inclusão incorreto: @param@',
705
+    'zbug_profile' => 'Tempo de processamento: @time@',
706
+    'zbug_resultat' => 'resultado',
707
+    'zbug_serveur_indefini' => 'Sevidor SQL não definido',
708
+    'zbug_statistiques' => 'Estatísticas das requisições SQL classificadas por duração',
709
+    'zbug_table_inconnue' => 'Tabela SQL «@table@» desconhecida',
710
+    'zxml_connus_attributs' => 'atributos conhecidos',
711
+    'zxml_de' => 'de',
712
+    'zxml_inconnu_attribut' => 'atributo desconhecido',
713
+    'zxml_inconnu_balise' => 'tag desconhecida',
714
+    'zxml_inconnu_entite' => 'entidade desconhecida',
715
+    'zxml_inconnu_id' => 'ID desconhecida',
716
+    'zxml_mais_de' => 'mas de',
717
+    'zxml_non_conforme' => 'não está de acordo com o motivo',
718
+    'zxml_non_fils' => 'não é filho de',
719
+    'zxml_nonvide_balise' => 'tag não vazia',
720
+    'zxml_obligatoire_attribut' => 'atributo obrigatório mas ausente em',
721
+    'zxml_succession_fils_incorrecte' => 'sucessão de filhos incorreta',
722
+    'zxml_survoler' => 'sobrepor para ver os corretos',
723
+    'zxml_valeur_attribut' => 'valor do atributo',
724
+    'zxml_vide_balise' => 'tag vazia',
725
+    'zxml_vu' => 'previsualização',
726 726
 ];
Please login to merge, or discard this patch.
ecrire/lang/ecrire_pt_br.php 1 patch
Indentation   +843 added lines, -843 removed lines patch added patch discarded remove patch
@@ -5,879 +5,879 @@
 block discarded – undo
5 5
 
6 6
 return [
7 7
 
8
-	// A
9
-	'activer_plugin' => 'Ativar o plugin',
10
-	'affichage' => 'Exibição',
11
-	'aide_non_disponible' => 'Esta parte da ajuda online ainda não está disponível neste idioma.',
12
-	'annuler_recherche' => 'Cancelar a busca',
13
-	'auteur' => 'Autor:',
14
-	'avis_acces_interdit' => 'Acesso negado.',
15
-	'avis_acces_interdit_prive' => 'Você não está autorizado a acessar a página <b>@exec@</b>.',
16
-	'avis_article_modifie' => 'Atenção, @nom_auteur_modif@ editou esta matéria há @date_diff@ minutos',
17
-	'avis_aucun_resultat' => 'Nenhum resultado.',
18
-	'avis_base_inaccessible' => 'Não foi possível conectar com a base de dados @base@.',
19
-	'avis_chemin_invalide_1' => 'O caminho que você escolheu',
20
-	'avis_chemin_invalide_2' => 'não parece válido. Por favor, volte à página anterior e verifique as informações fornecidas.',
21
-	'avis_connexion_echec_1' => 'A conexão com a base de dados falhou.',
22
-	'avis_connexion_echec_2' => 'Volte à página anterior e verifique as informações que você forneceu.',
23
-	'avis_connexion_echec_3' => '<b>N.B.</b> Em diversos servidores, você precisa <b>solicitar</b> a ativação do seu acesso à base de dados antes de poder utilizá-la. Se você não consegue se conectar, verifique se você efetuou esse pedido.',
24
-	'avis_connexion_erreur_creer_base' => 'Não foi possível criar a base de dados.',
25
-	'avis_connexion_erreur_fichier_cle_manquant_1' => 'A instalação deve ser realizada por um webmaster com um backup das chaves e sua senha.',
26
-	'avis_connexion_erreur_fichier_cle_manquant_2' => 'A instalação deve ser feita por um webmaster com um backup das chaves',
27
-	'avis_connexion_erreur_nom_base' => 'O nome da base só pode conter letras, números e traços',
28
-	'avis_connexion_ldap_echec_1' => 'A conexão ao servidor LDAP falhou.',
29
-	'avis_connexion_ldap_echec_2' => 'Volte à página anterior e verifique as informações que você forneceu.',
30
-	'avis_connexion_ldap_echec_3' => 'Opcionalmente, não use o suporte LDAP para importar os usuários.',
31
-	'avis_deplacement_rubrique' => 'Atenção! Esta seção contém @contient_breves@ nota@scb@: se você a transferir, por favor, marque este quadrado.',
32
-	'avis_erreur_connexion_mysql' => 'Erro de conexão SQL',
33
-	'avis_erreur_creation_compte' => 'Erro durante a inicialização da conta',
34
-	'avis_espace_interdit' => '<b>Área interdita</b> <div>O SPIP já está instalado.</div>',
35
-	'avis_lecture_noms_bases_1' => 'O programa de instalação não pôde ler os nomes das bases de dados instaladas.',
36
-	'avis_lecture_noms_bases_2' => 'Ou nenhuma base de dados esta disponível, ou a função que permite listar as bases foi desativada por razões de segurança (o que é o caso de diversos provedores de hospedagem).',
37
-	'avis_lecture_noms_bases_3' => 'No segundo caso, é provável que uma base de dados com o nome do seu login possa ser utilizada:',
38
-	'avis_non_acces_page' => 'Você não tem acesso a esta página.',
39
-	'avis_operation_echec' => 'A operação falhou.',
40
-	'avis_operation_impossible' => 'Operação impossível',
41
-	'avis_suppression_base' => 'ATENÇÃO, a supressão dos dados é irreversível',
8
+    // A
9
+    'activer_plugin' => 'Ativar o plugin',
10
+    'affichage' => 'Exibição',
11
+    'aide_non_disponible' => 'Esta parte da ajuda online ainda não está disponível neste idioma.',
12
+    'annuler_recherche' => 'Cancelar a busca',
13
+    'auteur' => 'Autor:',
14
+    'avis_acces_interdit' => 'Acesso negado.',
15
+    'avis_acces_interdit_prive' => 'Você não está autorizado a acessar a página <b>@exec@</b>.',
16
+    'avis_article_modifie' => 'Atenção, @nom_auteur_modif@ editou esta matéria há @date_diff@ minutos',
17
+    'avis_aucun_resultat' => 'Nenhum resultado.',
18
+    'avis_base_inaccessible' => 'Não foi possível conectar com a base de dados @base@.',
19
+    'avis_chemin_invalide_1' => 'O caminho que você escolheu',
20
+    'avis_chemin_invalide_2' => 'não parece válido. Por favor, volte à página anterior e verifique as informações fornecidas.',
21
+    'avis_connexion_echec_1' => 'A conexão com a base de dados falhou.',
22
+    'avis_connexion_echec_2' => 'Volte à página anterior e verifique as informações que você forneceu.',
23
+    'avis_connexion_echec_3' => '<b>N.B.</b> Em diversos servidores, você precisa <b>solicitar</b> a ativação do seu acesso à base de dados antes de poder utilizá-la. Se você não consegue se conectar, verifique se você efetuou esse pedido.',
24
+    'avis_connexion_erreur_creer_base' => 'Não foi possível criar a base de dados.',
25
+    'avis_connexion_erreur_fichier_cle_manquant_1' => 'A instalação deve ser realizada por um webmaster com um backup das chaves e sua senha.',
26
+    'avis_connexion_erreur_fichier_cle_manquant_2' => 'A instalação deve ser feita por um webmaster com um backup das chaves',
27
+    'avis_connexion_erreur_nom_base' => 'O nome da base só pode conter letras, números e traços',
28
+    'avis_connexion_ldap_echec_1' => 'A conexão ao servidor LDAP falhou.',
29
+    'avis_connexion_ldap_echec_2' => 'Volte à página anterior e verifique as informações que você forneceu.',
30
+    'avis_connexion_ldap_echec_3' => 'Opcionalmente, não use o suporte LDAP para importar os usuários.',
31
+    'avis_deplacement_rubrique' => 'Atenção! Esta seção contém @contient_breves@ nota@scb@: se você a transferir, por favor, marque este quadrado.',
32
+    'avis_erreur_connexion_mysql' => 'Erro de conexão SQL',
33
+    'avis_erreur_creation_compte' => 'Erro durante a inicialização da conta',
34
+    'avis_espace_interdit' => '<b>Área interdita</b> <div>O SPIP já está instalado.</div>',
35
+    'avis_lecture_noms_bases_1' => 'O programa de instalação não pôde ler os nomes das bases de dados instaladas.',
36
+    'avis_lecture_noms_bases_2' => 'Ou nenhuma base de dados esta disponível, ou a função que permite listar as bases foi desativada por razões de segurança (o que é o caso de diversos provedores de hospedagem).',
37
+    'avis_lecture_noms_bases_3' => 'No segundo caso, é provável que uma base de dados com o nome do seu login possa ser utilizada:',
38
+    'avis_non_acces_page' => 'Você não tem acesso a esta página.',
39
+    'avis_operation_echec' => 'A operação falhou.',
40
+    'avis_operation_impossible' => 'Operação impossível',
41
+    'avis_suppression_base' => 'ATENÇÃO, a supressão dos dados é irreversível',
42 42
 
43
-	// B
44
-	'bouton_acces_ldap' => 'Incluir o acesso ao LDAP',
45
-	'bouton_ajouter' => 'Incluir',
46
-	'bouton_annuler' => 'Anular',
47
-	'bouton_cache_activer' => 'Reativar o cache',
48
-	'bouton_cache_desactiver' => 'Desativar temporariamente o cache',
49
-	'bouton_demande_publication' => 'Solicitar a publicação desta matéria',
50
-	'bouton_desactive_tout' => 'Desativar tudo',
51
-	'bouton_desinstaller' => 'Desinstalar',
52
-	'bouton_effacer_tout' => 'Apagar TUDO',
53
-	'bouton_envoyer_message' => 'Mensagem definitiva: enviar',
54
-	'bouton_fermer' => 'Fechar',
55
-	'bouton_mettre_a_jour_base' => 'Atualizar a base de dados',
56
-	'bouton_modifier' => 'Alterar',
57
-	'bouton_radio_afficher' => 'Exibir',
58
-	'bouton_radio_apparaitre_liste_redacteurs_connectes' => 'Exibir nas listas de redatores conectados',
59
-	'bouton_radio_envoi_annonces_adresse' => 'Enviar os avisos para o endereço:',
60
-	'bouton_radio_envoi_liste_nouveautes' => 'Enviar a lista de novidades',
61
-	'bouton_radio_non_apparaitre_liste_redacteurs_connectes' => 'Não exibir na lista de redatores',
62
-	'bouton_radio_non_envoi_annonces_editoriales' => 'Não enviar os avisos editoriais',
63
-	'bouton_redirection' => 'REDIRECIONAMENTO',
64
-	'bouton_reinitialiser_aux_valeurs_par_defaut' => 'Reiniciar aos valores padrão',
65
-	'bouton_relancer_inscription' => 'Reiniciar o registro',
66
-	'bouton_relancer_inscriptions' => 'Reiniciar os registros',
67
-	'bouton_relancer_installation' => 'Reiniciar a instalação',
68
-	'bouton_reset_password' => 'Criar uma nova senha e enviá-la por e-mail',
69
-	'bouton_suivant' => 'Avançar',
70
-	'bouton_tenter_recuperation' => 'Tentar uma reparação',
71
-	'bouton_test_proxy' => 'Testar o proxy',
72
-	'bouton_vider_cache' => 'Limpar o cache',
43
+    // B
44
+    'bouton_acces_ldap' => 'Incluir o acesso ao LDAP',
45
+    'bouton_ajouter' => 'Incluir',
46
+    'bouton_annuler' => 'Anular',
47
+    'bouton_cache_activer' => 'Reativar o cache',
48
+    'bouton_cache_desactiver' => 'Desativar temporariamente o cache',
49
+    'bouton_demande_publication' => 'Solicitar a publicação desta matéria',
50
+    'bouton_desactive_tout' => 'Desativar tudo',
51
+    'bouton_desinstaller' => 'Desinstalar',
52
+    'bouton_effacer_tout' => 'Apagar TUDO',
53
+    'bouton_envoyer_message' => 'Mensagem definitiva: enviar',
54
+    'bouton_fermer' => 'Fechar',
55
+    'bouton_mettre_a_jour_base' => 'Atualizar a base de dados',
56
+    'bouton_modifier' => 'Alterar',
57
+    'bouton_radio_afficher' => 'Exibir',
58
+    'bouton_radio_apparaitre_liste_redacteurs_connectes' => 'Exibir nas listas de redatores conectados',
59
+    'bouton_radio_envoi_annonces_adresse' => 'Enviar os avisos para o endereço:',
60
+    'bouton_radio_envoi_liste_nouveautes' => 'Enviar a lista de novidades',
61
+    'bouton_radio_non_apparaitre_liste_redacteurs_connectes' => 'Não exibir na lista de redatores',
62
+    'bouton_radio_non_envoi_annonces_editoriales' => 'Não enviar os avisos editoriais',
63
+    'bouton_redirection' => 'REDIRECIONAMENTO',
64
+    'bouton_reinitialiser_aux_valeurs_par_defaut' => 'Reiniciar aos valores padrão',
65
+    'bouton_relancer_inscription' => 'Reiniciar o registro',
66
+    'bouton_relancer_inscriptions' => 'Reiniciar os registros',
67
+    'bouton_relancer_installation' => 'Reiniciar a instalação',
68
+    'bouton_reset_password' => 'Criar uma nova senha e enviá-la por e-mail',
69
+    'bouton_suivant' => 'Avançar',
70
+    'bouton_tenter_recuperation' => 'Tentar uma reparação',
71
+    'bouton_test_proxy' => 'Testar o proxy',
72
+    'bouton_vider_cache' => 'Limpar o cache',
73 73
 
74
-	// C
75
-	'cache_modifiable_webmestre' => 'Este parâmetro é modificável pelo webmaster do site.',
76
-	'calendrier_synchro' => 'Se você usa um programa de agenda compatível com <b>iCal</b>, você pode sincronizá-lo com as informações deste site.',
77
-	'config_activer_champs' => 'Ativar os campos a seguir',
78
-	'config_choix_base_sup' => 'indicar uma base neste servidor',
79
-	'config_erreur_base_sup' => 'O SPIP não tem acesso à lista de bases acessíveis',
80
-	'config_info_base_sup' => 'Se você tiver outras bases de dados para serem consultadas via SPIP, em seu servidor SQL ou em outro, o formulário abaixo permite configurá-las. Se você deixar determinados campos em branco, os dados de conexão da base principal serão utilizados.',
81
-	'config_info_base_sup_disponibles' => 'Bases suplementares já consultáveis:',
82
-	'config_info_enregistree' => 'A nova configuração foi gravada',
83
-	'config_info_logos' => 'Cada elemento do site pode ter um ícone, bem como um ícone de «mouseOver»',
84
-	'config_info_logos_utiliser' => 'Usar os ícones',
85
-	'config_info_logos_utiliser_non' => 'Não usar o ícones',
86
-	'config_info_logos_utiliser_survol' => 'Usar os ícones de mouseOver',
87
-	'config_info_logos_utiliser_survol_non' => 'Não usar os ícones de mouseOver',
88
-	'config_info_redirection' => 'Ao ativar esta opção, você poderá criar matérias virtuais, meras referências a matérias publicadas em outros sites ou fora do SPIP.',
89
-	'config_redirection' => 'Matérias virtuais',
90
-	'config_titre_base_sup' => 'Configuração de uma base suplementar',
91
-	'config_titre_base_sup_choix' => 'Escolha uma base suplementar',
92
-	'connexion_ldap' => 'Conexão:',
93
-	'creer_et_associer_un_auteur' => 'Criar e vincular um autor',
74
+    // C
75
+    'cache_modifiable_webmestre' => 'Este parâmetro é modificável pelo webmaster do site.',
76
+    'calendrier_synchro' => 'Se você usa um programa de agenda compatível com <b>iCal</b>, você pode sincronizá-lo com as informações deste site.',
77
+    'config_activer_champs' => 'Ativar os campos a seguir',
78
+    'config_choix_base_sup' => 'indicar uma base neste servidor',
79
+    'config_erreur_base_sup' => 'O SPIP não tem acesso à lista de bases acessíveis',
80
+    'config_info_base_sup' => 'Se você tiver outras bases de dados para serem consultadas via SPIP, em seu servidor SQL ou em outro, o formulário abaixo permite configurá-las. Se você deixar determinados campos em branco, os dados de conexão da base principal serão utilizados.',
81
+    'config_info_base_sup_disponibles' => 'Bases suplementares já consultáveis:',
82
+    'config_info_enregistree' => 'A nova configuração foi gravada',
83
+    'config_info_logos' => 'Cada elemento do site pode ter um ícone, bem como um ícone de «mouseOver»',
84
+    'config_info_logos_utiliser' => 'Usar os ícones',
85
+    'config_info_logos_utiliser_non' => 'Não usar o ícones',
86
+    'config_info_logos_utiliser_survol' => 'Usar os ícones de mouseOver',
87
+    'config_info_logos_utiliser_survol_non' => 'Não usar os ícones de mouseOver',
88
+    'config_info_redirection' => 'Ao ativar esta opção, você poderá criar matérias virtuais, meras referências a matérias publicadas em outros sites ou fora do SPIP.',
89
+    'config_redirection' => 'Matérias virtuais',
90
+    'config_titre_base_sup' => 'Configuração de uma base suplementar',
91
+    'config_titre_base_sup_choix' => 'Escolha uma base suplementar',
92
+    'connexion_ldap' => 'Conexão:',
93
+    'creer_et_associer_un_auteur' => 'Criar e vincular um autor',
94 94
 
95
-	// D
96
-	'date_mot_heures' => 'horas',
95
+    // D
96
+    'date_mot_heures' => 'horas',
97 97
 
98
-	// E
99
-	'ecran_connexion_couleur_principale' => 'Cor principal',
100
-	'ecran_connexion_image_fond' => 'Imagem de fundo',
101
-	'ecran_connexion_image_fond_explication' => 'Usar uma imagem (formato JPEG, 1920x1080 pixels)',
102
-	'ecran_connexion_image_revenir_couleur_defaut' => 'Reverter para a cor padrão',
103
-	'ecran_connexion_titre' => 'Tela de conexão',
104
-	'ecran_securite' => ' + tela de segurança @version@',
105
-	'email' => 'e-mail',
106
-	'email_2' => 'e-mail:',
107
-	'en_savoir_plus' => 'Saiba mais',
108
-	'entree_adresse_annuaire' => 'Endereço do catálogo',
109
-	'entree_adresse_email' => 'Seu endereço de e-mail',
110
-	'entree_adresse_email_2' => 'Endereço de e-mail',
111
-	'entree_base_donnee_1' => 'Endereço da base de dados',
112
-	'entree_base_donnee_2' => '(Frequentemente este endereço corresponde ao do seu site, às vezes ele corresponde ao nome «localhost», algumas vezes ele pode ser deixado completamente em branco.)',
113
-	'entree_biographie' => 'Biografia curta em poucas palavras.',
114
-	'entree_chemin_acces' => '<b>Informe</b> o caminho de acesso:',
115
-	'entree_cle_pgp' => 'Sua chave PGP',
116
-	'entree_cle_pgp_2' => 'Chave PGP',
117
-	'entree_contenu_rubrique' => '(Conteúdo da seção em poucas palavras.)',
118
-	'entree_identifiants_connexion' => 'Seus dados de conexão...',
119
-	'entree_identifiants_connexion_2' => 'Dados de conexão',
120
-	'entree_informations_connexion_ldap' => 'Informe neste formulário os dados de conexão ao seu catálogo LDAP.
98
+    // E
99
+    'ecran_connexion_couleur_principale' => 'Cor principal',
100
+    'ecran_connexion_image_fond' => 'Imagem de fundo',
101
+    'ecran_connexion_image_fond_explication' => 'Usar uma imagem (formato JPEG, 1920x1080 pixels)',
102
+    'ecran_connexion_image_revenir_couleur_defaut' => 'Reverter para a cor padrão',
103
+    'ecran_connexion_titre' => 'Tela de conexão',
104
+    'ecran_securite' => ' + tela de segurança @version@',
105
+    'email' => 'e-mail',
106
+    'email_2' => 'e-mail:',
107
+    'en_savoir_plus' => 'Saiba mais',
108
+    'entree_adresse_annuaire' => 'Endereço do catálogo',
109
+    'entree_adresse_email' => 'Seu endereço de e-mail',
110
+    'entree_adresse_email_2' => 'Endereço de e-mail',
111
+    'entree_base_donnee_1' => 'Endereço da base de dados',
112
+    'entree_base_donnee_2' => '(Frequentemente este endereço corresponde ao do seu site, às vezes ele corresponde ao nome «localhost», algumas vezes ele pode ser deixado completamente em branco.)',
113
+    'entree_biographie' => 'Biografia curta em poucas palavras.',
114
+    'entree_chemin_acces' => '<b>Informe</b> o caminho de acesso:',
115
+    'entree_cle_pgp' => 'Sua chave PGP',
116
+    'entree_cle_pgp_2' => 'Chave PGP',
117
+    'entree_contenu_rubrique' => '(Conteúdo da seção em poucas palavras.)',
118
+    'entree_identifiants_connexion' => 'Seus dados de conexão...',
119
+    'entree_identifiants_connexion_2' => 'Dados de conexão',
120
+    'entree_informations_connexion_ldap' => 'Informe neste formulário os dados de conexão ao seu catálogo LDAP.
121 121
 Estas informações deverão ser fornecidas pelo administrador do sistema ou da rede.',
122
-	'entree_infos_perso' => 'Quem é você?',
123
-	'entree_infos_perso_2' => 'Quem é o autor?',
124
-	'entree_interieur_rubrique' => 'No interior da seção:',
125
-	'entree_liens_sites' => '<b>Link hipertexto</b> (referência, site a visitar...)',
126
-	'entree_login' => 'Seu login',
127
-	'entree_login_connexion_1' => 'O login de conexão',
128
-	'entree_login_connexion_2' => '(Frequentemente corresponde ao seu login para acesso por FTP; às vezes pode ser deixado em branco)',
129
-	'entree_mot_passe' => 'Sua senha',
130
-	'entree_mot_passe_1' => 'A senha de conexão',
131
-	'entree_mot_passe_2' => '(Frequentemente corresponde à sua senha para acesso por FTP; às vezes pode ser deixado em branco)',
132
-	'entree_nom_fichier' => 'Por favor, informe o nome do arquivo @texte_compresse@:',
133
-	'entree_nom_pseudo' => 'Seu nome ou apelido',
134
-	'entree_nom_pseudo_1' => '(Seu nome ou apelido)',
135
-	'entree_nom_pseudo_2' => 'Nome ou apelido',
136
-	'entree_nom_site' => 'O nome do seu site',
137
-	'entree_nom_site_2' => 'Nome do site do autor',
138
-	'entree_nouveau_passe' => 'Nova senha',
139
-	'entree_passe_ldap' => 'Senha',
140
-	'entree_port_annuaire' => 'O número da porta do catálogo',
141
-	'entree_signature' => 'Assinatura',
142
-	'entree_titre_obligatoire' => '<b>Título</b> [Obrigatório]<br />',
143
-	'entree_url' => 'O endereço (URL) do seu site',
144
-	'entree_url_2' => 'Endereço (URL) do site',
145
-	'erreur_connect_deja_existant' => 'Já existe um servidor com esse nome',
146
-	'erreur_contenu_suspect' => 'Texto escapado',
147
-	'erreur_email_deja_existant' => 'Esse endereço de email já está em uso.',
148
-	'erreur_nom_connect_incorrect' => 'Este nome de servidor não é autorizado',
149
-	'erreur_plugin_attribut_balise_manquant' => 'Atributo @attribut@ faltando no tag @balise@.',
150
-	'erreur_plugin_desinstalation_echouee' => 'A desinstalação do plugin falhou. No entanto, você pode desativá-lo.',
151
-	'erreur_plugin_fichier_absent' => 'Arquivo ausente',
152
-	'erreur_plugin_fichier_def_absent' => 'Arquivo de definição ausente',
153
-	'erreur_plugin_nom_fonction_interdit' => 'Nome de função não permitido',
154
-	'erreur_plugin_nom_manquant' => 'Nome do plugin ausente',
155
-	'erreur_plugin_prefix_manquant' => 'Área de nomeação do plugin não definida',
156
-	'erreur_plugin_tag_plugin_absent' => '&lt;plugin&gt; ausente no arquivo de definição',
157
-	'erreur_plugin_version_manquant' => 'Versão do plugin ausente',
158
-	'erreur_type_fichier' => 'Tipo de arquivo incorreto',
122
+    'entree_infos_perso' => 'Quem é você?',
123
+    'entree_infos_perso_2' => 'Quem é o autor?',
124
+    'entree_interieur_rubrique' => 'No interior da seção:',
125
+    'entree_liens_sites' => '<b>Link hipertexto</b> (referência, site a visitar...)',
126
+    'entree_login' => 'Seu login',
127
+    'entree_login_connexion_1' => 'O login de conexão',
128
+    'entree_login_connexion_2' => '(Frequentemente corresponde ao seu login para acesso por FTP; às vezes pode ser deixado em branco)',
129
+    'entree_mot_passe' => 'Sua senha',
130
+    'entree_mot_passe_1' => 'A senha de conexão',
131
+    'entree_mot_passe_2' => '(Frequentemente corresponde à sua senha para acesso por FTP; às vezes pode ser deixado em branco)',
132
+    'entree_nom_fichier' => 'Por favor, informe o nome do arquivo @texte_compresse@:',
133
+    'entree_nom_pseudo' => 'Seu nome ou apelido',
134
+    'entree_nom_pseudo_1' => '(Seu nome ou apelido)',
135
+    'entree_nom_pseudo_2' => 'Nome ou apelido',
136
+    'entree_nom_site' => 'O nome do seu site',
137
+    'entree_nom_site_2' => 'Nome do site do autor',
138
+    'entree_nouveau_passe' => 'Nova senha',
139
+    'entree_passe_ldap' => 'Senha',
140
+    'entree_port_annuaire' => 'O número da porta do catálogo',
141
+    'entree_signature' => 'Assinatura',
142
+    'entree_titre_obligatoire' => '<b>Título</b> [Obrigatório]<br />',
143
+    'entree_url' => 'O endereço (URL) do seu site',
144
+    'entree_url_2' => 'Endereço (URL) do site',
145
+    'erreur_connect_deja_existant' => 'Já existe um servidor com esse nome',
146
+    'erreur_contenu_suspect' => 'Texto escapado',
147
+    'erreur_email_deja_existant' => 'Esse endereço de email já está em uso.',
148
+    'erreur_nom_connect_incorrect' => 'Este nome de servidor não é autorizado',
149
+    'erreur_plugin_attribut_balise_manquant' => 'Atributo @attribut@ faltando no tag @balise@.',
150
+    'erreur_plugin_desinstalation_echouee' => 'A desinstalação do plugin falhou. No entanto, você pode desativá-lo.',
151
+    'erreur_plugin_fichier_absent' => 'Arquivo ausente',
152
+    'erreur_plugin_fichier_def_absent' => 'Arquivo de definição ausente',
153
+    'erreur_plugin_nom_fonction_interdit' => 'Nome de função não permitido',
154
+    'erreur_plugin_nom_manquant' => 'Nome do plugin ausente',
155
+    'erreur_plugin_prefix_manquant' => 'Área de nomeação do plugin não definida',
156
+    'erreur_plugin_tag_plugin_absent' => '&lt;plugin&gt; ausente no arquivo de definição',
157
+    'erreur_plugin_version_manquant' => 'Versão do plugin ausente',
158
+    'erreur_type_fichier' => 'Tipo de arquivo incorreto',
159 159
 
160
-	// H
161
-	'htaccess_a_simuler' => 'Aviso: a configuração do seu servidor HTTP não leva em conta os arquivos @htaccess@. Para poder garantir um bom nível de segurança, é preciso que você altere esta configuração, ou que as constantes @constantes@ (definíveis no arquivo mes_options.php) tenham como valor os diretórios abaixo de @document_root@.',
162
-	'htaccess_inoperant' => 'htaccess inoperante',
160
+    // H
161
+    'htaccess_a_simuler' => 'Aviso: a configuração do seu servidor HTTP não leva em conta os arquivos @htaccess@. Para poder garantir um bom nível de segurança, é preciso que você altere esta configuração, ou que as constantes @constantes@ (definíveis no arquivo mes_options.php) tenham como valor os diretórios abaixo de @document_root@.',
162
+    'htaccess_inoperant' => 'htaccess inoperante',
163 163
 
164
-	// I
165
-	'ical_info1' => 'Esta página apresenta diversos métodos para se manter a par da atividade deste site.',
166
-	'ical_info2' => 'Para mais informações sobre todas estas técnicas, não deixe de consultar <a href="@spipnet@">a documentação do SPIP</a>.',
167
-	'ical_info_calendrier' => 'Dois calendários estão à sua disposição. O primeiro é um mapa do site anunciando todas as matérias publicadas. O segundo contém os avisos editoriais bem como suas últimas mensagens privadas: ele lhe é reservado graças a uma chave pessoal, que você pode alterar a qualquer momento ao renovar a sua senha.',
168
-	'ical_methode_http' => 'Transferência',
169
-	'ical_methode_webcal' => 'Sincronização (webcal://)',
170
-	'ical_texte_prive' => 'Este calendário, de uso estritamente pessoal, o informa sobre a atividade editorial privada deste site (tarefas e encontros pessoais, matérias e notas propostas...).',
171
-	'ical_texte_public' => 'Este calendário permite-lhe acompanhar a atividade pública deste site (matérias e notas publicadas).',
172
-	'ical_texte_rss' => 'Você pode sindicar as novidades deste site em qualquer leitor de arquivos em formato XML/RSS (Rich Site Summary). É também o formato que permite ao SPIP ler as novidades publicadas em outros sites que utilizem um formato de troca de informações compatível (sites sindicados).',
173
-	'ical_titre_js' => 'Javascript',
174
-	'ical_titre_mailing' => 'Mailing-list',
175
-	'ical_titre_rss' => 'Arquivos de sindicação',
176
-	'icone_accueil' => 'Página Inicial',
177
-	'icone_activer_cookie' => 'Ativar o coockie de correspondência',
178
-	'icone_activite' => 'Atividade',
179
-	'icone_admin_plugin' => 'Gerenciamento dos plugins',
180
-	'icone_administration' => 'Manutenção',
181
-	'icone_afficher_auteurs' => 'Exibir os autores',
182
-	'icone_afficher_visiteurs' => 'Exibir os visitantes',
183
-	'icone_arret_discussion' => 'Não participar mais desta discussão',
184
-	'icone_calendrier' => 'Calendário',
185
-	'icone_configuration' => 'Configuração',
186
-	'icone_creer_auteur' => 'Criar um novo autor e vinculá-lo a esta matéria',
187
-	'icone_creer_mot_cle' => 'Criar uma nova palavra-chave e vinculá-la a esta matéria',
188
-	'icone_creer_rubrique_2' => 'Criar uma nova seção',
189
-	'icone_developpement' => 'Desenvolvimento',
190
-	'icone_edition' => 'Edição',
191
-	'icone_ma_langue' => 'Meu idioma',
192
-	'icone_mes_infos' => 'Minhas informações',
193
-	'icone_mes_preferences' => 'Minhas preferências',
194
-	'icone_modifier_article' => 'Editar esta matéria',
195
-	'icone_modifier_rubrique' => 'Editar esta seção',
196
-	'icone_publication' => 'Publicação',
197
-	'icone_relancer_signataire' => 'Reconfirmar o assinante',
198
-	'icone_retour' => 'Voltar',
199
-	'icone_retour_article' => 'Voltar para a matéria',
200
-	'icone_squelette' => 'Templates',
201
-	'icone_suivi_publication' => 'Acompanhamento da publicação',
202
-	'icone_supprimer_cookie' => 'Excluir o cookie de correspondência',
203
-	'icone_supprimer_rubrique' => 'Excluir esta seção',
204
-	'icone_supprimer_signature' => 'Excluir esta assinatura',
205
-	'icone_valider_signature' => 'Validar esta assinatura',
206
-	'image_administrer_rubrique' => 'Você pode administrar esta seção',
207
-	'impossible_modifier_login_auteur' => 'Não foi possível alterar o login.',
208
-	'impossible_modifier_pass_auteur' => 'Não foi possível alterar a senha.',
209
-	'info_1_article' => '1 matéria',
210
-	'info_1_auteur' => '1 autor',
211
-	'info_1_message' => '1 mensagem',
212
-	'info_1_mot_cle' => '1 palavra-chave',
213
-	'info_1_rubrique' => '1 seção',
214
-	'info_1_visiteur' => '1 visitante',
215
-	'info_activer_cookie' => 'Você pode ativar um <b>cookie de correspondência</b>, que lhe permitirá passar facilmente do site público para o site privado.',
216
-	'info_activer_menu_developpement' => 'Exibir o menu Desenvolvimento',
217
-	'info_admin_etre_webmestre' => 'Me conceder direitos de webmaster',
218
-	'info_admin_je_suis_webmestre' => 'Eu sou <b>webmaster</b>',
219
-	'info_admin_statuer_webmestre' => 'Dar a este administrador os direitos de webmaster',
220
-	'info_admin_webmestre' => 'Este administrador é <b>webmaster</b>',
221
-	'info_administrateur' => 'Administrador',
222
-	'info_administrateur_1' => 'Administrador',
223
-	'info_administrateur_2' => 'do site (<i>use com cuidado</i>)',
224
-	'info_administrateur_site_01' => 'Se você é administrador do site, por favor,',
225
-	'info_administrateur_site_02' => 'clique neste link',
226
-	'info_administrateurs' => 'Administradores',
227
-	'info_administrer_rubrique' => 'Você pode administrar esta seção',
228
-	'info_adresse' => 'no endereço:',
229
-	'info_adresse_desinscription' => 'Endereço da desinscrição:',
230
-	'info_adresse_inscription' => 'Endereço de inscrição:',
231
-	'info_adresse_url' => 'Endereço (URL) do site público',
232
-	'info_afficher_par_nb' => 'Exibir por',
233
-	'info_aide_en_ligne' => 'Ajuda online SPIP',
234
-	'info_ajout_image' => 'Assim que você incluir imagens e documentos anexados a uma matéria, o SPIP pode criar para você, automaticamente, ícones (miniaturas) das imagens inseridas. Isto permite, por exemplo, criar automaticamente uma galeria ou um portfólio.',
235
-	'info_ajouter_rubrique' => 'Incluir outra seção para administrar:',
236
-	'info_annonce_nouveautes' => 'Aviso das novidades',
237
-	'info_article' => 'matéria',
238
-	'info_article_2' => 'matérias',
239
-	'info_article_a_paraitre' => 'As matérias pós-datadas para exibição',
240
-	'info_articles_02' => 'matérias',
241
-	'info_articles_2' => 'Matérias',
242
-	'info_articles_auteur' => 'As matérias deste autor',
243
-	'info_articles_miens' => 'Minhas matérias',
244
-	'info_articles_tous' => 'Todas as matérias',
245
-	'info_articles_trouves' => 'Matérias encontradas',
246
-	'info_attente_validation' => 'Suas matérias aguardando validação',
247
-	'info_aucun_article' => 'Nenhuma matéria',
248
-	'info_aucun_auteur' => 'Nenhum autor',
249
-	'info_aucun_message' => 'Nenhuma mensagem',
250
-	'info_aucun_rubrique' => 'Nenhuma seção',
251
-	'info_aujourdhui' => 'Hoje:',
252
-	'info_auteur_gere_rubriques' => 'Este autor gerencia as seções a seguir:',
253
-	'info_auteur_gere_toutes_rubriques' => 'Este autor gerencia <b>todas as seções</b>',
254
-	'info_auteur_gere_toutes_rubriques_2' => 'Eu gerencio <b>todas as seções</b>',
255
-	'info_auteurs' => 'Os autores',
256
-	'info_auteurs_par_tri' => 'Autores@partri@',
257
-	'info_auteurs_trouves' => 'Autores encontrados',
258
-	'info_authentification_externe' => 'Autenticação externa',
259
-	'info_avertissement' => 'Aviso',
260
-	'info_barre_outils' => 'com sua barra de ferramentas?',
261
-	'info_base_installee' => 'A estrutura da sua base de dados foi instalada.',
262
-	'info_bio' => 'Biografia',
263
-	'info_cache_desactive' => 'O cache está temporariamente desativado.',
264
-	'info_chapeau' => 'Introdução',
265
-	'info_chapeau_2' => 'Introdução:',
266
-	'info_chemin_acces_1' => 'Opções: <b>Caminho de acesso no diretório</b>',
267
-	'info_chemin_acces_2' => 'A partir daqui, você deverá configurar o caminho de acesso às informações do diretório. Esta informação é indispensávelpara ler os perfis dos usuários no diretório.',
268
-	'info_chemin_acces_annuaire' => 'Opções: <b>Caminho de acesso no diretório</b>',
269
-	'info_choix_base' => 'Terceiro passo:',
270
-	'info_classement_1' => '<sup><u>o</u></sup> em @liste@',
271
-	'info_classement_2' => '<sup><u>a</u></sup> em @liste@',
272
-	'info_code_acces' => 'Não se esqueça dos seus dados de conexão!',
273
-	'info_config_suivi' => 'Se este endereço corresponde a uma mailing-list, você pode informar abaixo o endereço onde os participantes do site podem se inscrever. Este endereço pode ser um URL (por exemplo a página de inscrição na lista pela Web), ou um endereço de e-mail dotado de um assunto específico (par exemple: <tt>@adresse_suivi@?subject=subscribe</tt>):',
274
-	'info_config_suivi_explication' => 'Voce pode assinar a  mailing-list deste site. Você irá receber por e-mail, os avisos de matérias e notas propostos para publicação.',
275
-	'info_confirmer_passe' => 'Confirmar a nova senha:',
276
-	'info_conflit_edition_avis_non_sauvegarde' => 'Atenção os campos a seguir foram alterados por terceiros. As suas modificações nestes campos não foram, por isso, gravadas.',
277
-	'info_conflit_edition_differences' => 'Diferenças:',
278
-	'info_conflit_edition_version_enregistree' => 'A versão gravada:',
279
-	'info_conflit_edition_votre_version' => 'A sua versão:',
280
-	'info_connexion_base' => 'Teste de conexão com a base',
281
-	'info_connexion_base_donnee' => 'Conexão à sua base de dados',
282
-	'info_connexion_ldap_ok' => '<b>A conexão LDAP foi efetuada.</b><p>Você pode passar para o próximo passo.</p>',
283
-	'info_connexion_mysql' => 'Sua conexão SQL',
284
-	'info_connexion_ok' => 'A conexão foi obtida.',
285
-	'info_contact' => 'Contato',
286
-	'info_contenu_articles' => 'Conteúdo das matérias',
287
-	'info_contributions' => 'Contribuições',
288
-	'info_creation_paragraphe' => 'Para criar parágrafos, basta deixar linhas em branco.',
289
-	'info_creation_rubrique' => 'Antes de poder escrever matérias, você deve criar, pelo menos, uma seção.<br />',
290
-	'info_creation_tables' => 'Criação das tabelas da base',
291
-	'info_creer_base' => '<b>Criar</b> uma nova base de dados:',
292
-	'info_dans_rubrique' => 'Na seção:',
293
-	'info_date_publication_anterieure' => 'Data de redação anterior:',
294
-	'info_date_referencement' => 'DATA DE REFERENCIAMENTO DESTE SITE:',
295
-	'info_derniere_etape' => 'Terminou!',
296
-	'info_descriptif' => 'Descrição:',
297
-	'info_desinstaller_plugin' => 'exclui os dados e desativa o plugin',
298
-	'info_discussion_cours' => 'Discussões em andamento',
299
-	'info_ecrire_article' => 'Antes de poder escrever matérias, você precisa criar pelo menos uma seção.',
300
-	'info_email_envoi' => 'Endereço de e-mail de envio (opcional)',
301
-	'info_email_envoi_txt' => 'Informe aqui o endereço a ser utilizado para enviar os e-mails (por padrão, o endereço de destino será usado como endereço de envio):',
302
-	'info_email_webmestre' => 'Endereço de e-mail do webmaster',
303
-	'info_envoi_email_automatique' => 'Envio automático de e-mails',
304
-	'info_envoyer_maintenant' => 'Enviar agora',
305
-	'info_etape_suivante' => 'Avançar para a próxima etapa',
306
-	'info_etape_suivante_1' => 'Você pode passar para a próxima etapa.',
307
-	'info_etape_suivante_2' => 'Você pode passar para a próxima etapa.',
308
-	'info_exceptions_proxy' => 'Exceções para o proxy',
309
-	'info_exportation_base' => 'exportação da base para @archive@',
310
-	'info_facilite_suivi_activite' => 'Para facilitar o acompanhamento da atividade editorial do site, o SPIP pode avisar por e-mail, por exemplo para uma mailing-list de redatores, os avisos dos pedidos de publicação e das validações das matérias. Informe um ou mais endereços, separados por vírgula.',
311
-	'info_fichiers_authent' => 'Arquivos de autenticação «.htpasswd»',
312
-	'info_forums_abo_invites' => 'O seu site comporta fóruns por assinatura; os visitantes são convidados a se registrar no site público.',
313
-	'info_gauche_admin_tech' => '<b>Esta página é acessível apenas aos responsáveis pelo site.</b><p>Ela dá acesso às diferentes funções de manutenção técnica. Algumas dessas funções possuem um processo específico de autenticação que exige acesso FTP ao website.</p>',
314
-	'info_gauche_admin_vider' => '<b>Esta página é acessível apenas aos responsáveis pelo site.</b><p> Ela dá acesso às diferentes funções de manutenção técnica. Algumas dessas funções possuem um processo específico de autenticação que exige acesso FTP ao website.</p>',
315
-	'info_gauche_auteurs' => 'Aqui, você encontra todos os autores do site.
164
+    // I
165
+    'ical_info1' => 'Esta página apresenta diversos métodos para se manter a par da atividade deste site.',
166
+    'ical_info2' => 'Para mais informações sobre todas estas técnicas, não deixe de consultar <a href="@spipnet@">a documentação do SPIP</a>.',
167
+    'ical_info_calendrier' => 'Dois calendários estão à sua disposição. O primeiro é um mapa do site anunciando todas as matérias publicadas. O segundo contém os avisos editoriais bem como suas últimas mensagens privadas: ele lhe é reservado graças a uma chave pessoal, que você pode alterar a qualquer momento ao renovar a sua senha.',
168
+    'ical_methode_http' => 'Transferência',
169
+    'ical_methode_webcal' => 'Sincronização (webcal://)',
170
+    'ical_texte_prive' => 'Este calendário, de uso estritamente pessoal, o informa sobre a atividade editorial privada deste site (tarefas e encontros pessoais, matérias e notas propostas...).',
171
+    'ical_texte_public' => 'Este calendário permite-lhe acompanhar a atividade pública deste site (matérias e notas publicadas).',
172
+    'ical_texte_rss' => 'Você pode sindicar as novidades deste site em qualquer leitor de arquivos em formato XML/RSS (Rich Site Summary). É também o formato que permite ao SPIP ler as novidades publicadas em outros sites que utilizem um formato de troca de informações compatível (sites sindicados).',
173
+    'ical_titre_js' => 'Javascript',
174
+    'ical_titre_mailing' => 'Mailing-list',
175
+    'ical_titre_rss' => 'Arquivos de sindicação',
176
+    'icone_accueil' => 'Página Inicial',
177
+    'icone_activer_cookie' => 'Ativar o coockie de correspondência',
178
+    'icone_activite' => 'Atividade',
179
+    'icone_admin_plugin' => 'Gerenciamento dos plugins',
180
+    'icone_administration' => 'Manutenção',
181
+    'icone_afficher_auteurs' => 'Exibir os autores',
182
+    'icone_afficher_visiteurs' => 'Exibir os visitantes',
183
+    'icone_arret_discussion' => 'Não participar mais desta discussão',
184
+    'icone_calendrier' => 'Calendário',
185
+    'icone_configuration' => 'Configuração',
186
+    'icone_creer_auteur' => 'Criar um novo autor e vinculá-lo a esta matéria',
187
+    'icone_creer_mot_cle' => 'Criar uma nova palavra-chave e vinculá-la a esta matéria',
188
+    'icone_creer_rubrique_2' => 'Criar uma nova seção',
189
+    'icone_developpement' => 'Desenvolvimento',
190
+    'icone_edition' => 'Edição',
191
+    'icone_ma_langue' => 'Meu idioma',
192
+    'icone_mes_infos' => 'Minhas informações',
193
+    'icone_mes_preferences' => 'Minhas preferências',
194
+    'icone_modifier_article' => 'Editar esta matéria',
195
+    'icone_modifier_rubrique' => 'Editar esta seção',
196
+    'icone_publication' => 'Publicação',
197
+    'icone_relancer_signataire' => 'Reconfirmar o assinante',
198
+    'icone_retour' => 'Voltar',
199
+    'icone_retour_article' => 'Voltar para a matéria',
200
+    'icone_squelette' => 'Templates',
201
+    'icone_suivi_publication' => 'Acompanhamento da publicação',
202
+    'icone_supprimer_cookie' => 'Excluir o cookie de correspondência',
203
+    'icone_supprimer_rubrique' => 'Excluir esta seção',
204
+    'icone_supprimer_signature' => 'Excluir esta assinatura',
205
+    'icone_valider_signature' => 'Validar esta assinatura',
206
+    'image_administrer_rubrique' => 'Você pode administrar esta seção',
207
+    'impossible_modifier_login_auteur' => 'Não foi possível alterar o login.',
208
+    'impossible_modifier_pass_auteur' => 'Não foi possível alterar a senha.',
209
+    'info_1_article' => '1 matéria',
210
+    'info_1_auteur' => '1 autor',
211
+    'info_1_message' => '1 mensagem',
212
+    'info_1_mot_cle' => '1 palavra-chave',
213
+    'info_1_rubrique' => '1 seção',
214
+    'info_1_visiteur' => '1 visitante',
215
+    'info_activer_cookie' => 'Você pode ativar um <b>cookie de correspondência</b>, que lhe permitirá passar facilmente do site público para o site privado.',
216
+    'info_activer_menu_developpement' => 'Exibir o menu Desenvolvimento',
217
+    'info_admin_etre_webmestre' => 'Me conceder direitos de webmaster',
218
+    'info_admin_je_suis_webmestre' => 'Eu sou <b>webmaster</b>',
219
+    'info_admin_statuer_webmestre' => 'Dar a este administrador os direitos de webmaster',
220
+    'info_admin_webmestre' => 'Este administrador é <b>webmaster</b>',
221
+    'info_administrateur' => 'Administrador',
222
+    'info_administrateur_1' => 'Administrador',
223
+    'info_administrateur_2' => 'do site (<i>use com cuidado</i>)',
224
+    'info_administrateur_site_01' => 'Se você é administrador do site, por favor,',
225
+    'info_administrateur_site_02' => 'clique neste link',
226
+    'info_administrateurs' => 'Administradores',
227
+    'info_administrer_rubrique' => 'Você pode administrar esta seção',
228
+    'info_adresse' => 'no endereço:',
229
+    'info_adresse_desinscription' => 'Endereço da desinscrição:',
230
+    'info_adresse_inscription' => 'Endereço de inscrição:',
231
+    'info_adresse_url' => 'Endereço (URL) do site público',
232
+    'info_afficher_par_nb' => 'Exibir por',
233
+    'info_aide_en_ligne' => 'Ajuda online SPIP',
234
+    'info_ajout_image' => 'Assim que você incluir imagens e documentos anexados a uma matéria, o SPIP pode criar para você, automaticamente, ícones (miniaturas) das imagens inseridas. Isto permite, por exemplo, criar automaticamente uma galeria ou um portfólio.',
235
+    'info_ajouter_rubrique' => 'Incluir outra seção para administrar:',
236
+    'info_annonce_nouveautes' => 'Aviso das novidades',
237
+    'info_article' => 'matéria',
238
+    'info_article_2' => 'matérias',
239
+    'info_article_a_paraitre' => 'As matérias pós-datadas para exibição',
240
+    'info_articles_02' => 'matérias',
241
+    'info_articles_2' => 'Matérias',
242
+    'info_articles_auteur' => 'As matérias deste autor',
243
+    'info_articles_miens' => 'Minhas matérias',
244
+    'info_articles_tous' => 'Todas as matérias',
245
+    'info_articles_trouves' => 'Matérias encontradas',
246
+    'info_attente_validation' => 'Suas matérias aguardando validação',
247
+    'info_aucun_article' => 'Nenhuma matéria',
248
+    'info_aucun_auteur' => 'Nenhum autor',
249
+    'info_aucun_message' => 'Nenhuma mensagem',
250
+    'info_aucun_rubrique' => 'Nenhuma seção',
251
+    'info_aujourdhui' => 'Hoje:',
252
+    'info_auteur_gere_rubriques' => 'Este autor gerencia as seções a seguir:',
253
+    'info_auteur_gere_toutes_rubriques' => 'Este autor gerencia <b>todas as seções</b>',
254
+    'info_auteur_gere_toutes_rubriques_2' => 'Eu gerencio <b>todas as seções</b>',
255
+    'info_auteurs' => 'Os autores',
256
+    'info_auteurs_par_tri' => 'Autores@partri@',
257
+    'info_auteurs_trouves' => 'Autores encontrados',
258
+    'info_authentification_externe' => 'Autenticação externa',
259
+    'info_avertissement' => 'Aviso',
260
+    'info_barre_outils' => 'com sua barra de ferramentas?',
261
+    'info_base_installee' => 'A estrutura da sua base de dados foi instalada.',
262
+    'info_bio' => 'Biografia',
263
+    'info_cache_desactive' => 'O cache está temporariamente desativado.',
264
+    'info_chapeau' => 'Introdução',
265
+    'info_chapeau_2' => 'Introdução:',
266
+    'info_chemin_acces_1' => 'Opções: <b>Caminho de acesso no diretório</b>',
267
+    'info_chemin_acces_2' => 'A partir daqui, você deverá configurar o caminho de acesso às informações do diretório. Esta informação é indispensávelpara ler os perfis dos usuários no diretório.',
268
+    'info_chemin_acces_annuaire' => 'Opções: <b>Caminho de acesso no diretório</b>',
269
+    'info_choix_base' => 'Terceiro passo:',
270
+    'info_classement_1' => '<sup><u>o</u></sup> em @liste@',
271
+    'info_classement_2' => '<sup><u>a</u></sup> em @liste@',
272
+    'info_code_acces' => 'Não se esqueça dos seus dados de conexão!',
273
+    'info_config_suivi' => 'Se este endereço corresponde a uma mailing-list, você pode informar abaixo o endereço onde os participantes do site podem se inscrever. Este endereço pode ser um URL (por exemplo a página de inscrição na lista pela Web), ou um endereço de e-mail dotado de um assunto específico (par exemple: <tt>@adresse_suivi@?subject=subscribe</tt>):',
274
+    'info_config_suivi_explication' => 'Voce pode assinar a  mailing-list deste site. Você irá receber por e-mail, os avisos de matérias e notas propostos para publicação.',
275
+    'info_confirmer_passe' => 'Confirmar a nova senha:',
276
+    'info_conflit_edition_avis_non_sauvegarde' => 'Atenção os campos a seguir foram alterados por terceiros. As suas modificações nestes campos não foram, por isso, gravadas.',
277
+    'info_conflit_edition_differences' => 'Diferenças:',
278
+    'info_conflit_edition_version_enregistree' => 'A versão gravada:',
279
+    'info_conflit_edition_votre_version' => 'A sua versão:',
280
+    'info_connexion_base' => 'Teste de conexão com a base',
281
+    'info_connexion_base_donnee' => 'Conexão à sua base de dados',
282
+    'info_connexion_ldap_ok' => '<b>A conexão LDAP foi efetuada.</b><p>Você pode passar para o próximo passo.</p>',
283
+    'info_connexion_mysql' => 'Sua conexão SQL',
284
+    'info_connexion_ok' => 'A conexão foi obtida.',
285
+    'info_contact' => 'Contato',
286
+    'info_contenu_articles' => 'Conteúdo das matérias',
287
+    'info_contributions' => 'Contribuições',
288
+    'info_creation_paragraphe' => 'Para criar parágrafos, basta deixar linhas em branco.',
289
+    'info_creation_rubrique' => 'Antes de poder escrever matérias, você deve criar, pelo menos, uma seção.<br />',
290
+    'info_creation_tables' => 'Criação das tabelas da base',
291
+    'info_creer_base' => '<b>Criar</b> uma nova base de dados:',
292
+    'info_dans_rubrique' => 'Na seção:',
293
+    'info_date_publication_anterieure' => 'Data de redação anterior:',
294
+    'info_date_referencement' => 'DATA DE REFERENCIAMENTO DESTE SITE:',
295
+    'info_derniere_etape' => 'Terminou!',
296
+    'info_descriptif' => 'Descrição:',
297
+    'info_desinstaller_plugin' => 'exclui os dados e desativa o plugin',
298
+    'info_discussion_cours' => 'Discussões em andamento',
299
+    'info_ecrire_article' => 'Antes de poder escrever matérias, você precisa criar pelo menos uma seção.',
300
+    'info_email_envoi' => 'Endereço de e-mail de envio (opcional)',
301
+    'info_email_envoi_txt' => 'Informe aqui o endereço a ser utilizado para enviar os e-mails (por padrão, o endereço de destino será usado como endereço de envio):',
302
+    'info_email_webmestre' => 'Endereço de e-mail do webmaster',
303
+    'info_envoi_email_automatique' => 'Envio automático de e-mails',
304
+    'info_envoyer_maintenant' => 'Enviar agora',
305
+    'info_etape_suivante' => 'Avançar para a próxima etapa',
306
+    'info_etape_suivante_1' => 'Você pode passar para a próxima etapa.',
307
+    'info_etape_suivante_2' => 'Você pode passar para a próxima etapa.',
308
+    'info_exceptions_proxy' => 'Exceções para o proxy',
309
+    'info_exportation_base' => 'exportação da base para @archive@',
310
+    'info_facilite_suivi_activite' => 'Para facilitar o acompanhamento da atividade editorial do site, o SPIP pode avisar por e-mail, por exemplo para uma mailing-list de redatores, os avisos dos pedidos de publicação e das validações das matérias. Informe um ou mais endereços, separados por vírgula.',
311
+    'info_fichiers_authent' => 'Arquivos de autenticação «.htpasswd»',
312
+    'info_forums_abo_invites' => 'O seu site comporta fóruns por assinatura; os visitantes são convidados a se registrar no site público.',
313
+    'info_gauche_admin_tech' => '<b>Esta página é acessível apenas aos responsáveis pelo site.</b><p>Ela dá acesso às diferentes funções de manutenção técnica. Algumas dessas funções possuem um processo específico de autenticação que exige acesso FTP ao website.</p>',
314
+    'info_gauche_admin_vider' => '<b>Esta página é acessível apenas aos responsáveis pelo site.</b><p> Ela dá acesso às diferentes funções de manutenção técnica. Algumas dessas funções possuem um processo específico de autenticação que exige acesso FTP ao website.</p>',
315
+    'info_gauche_auteurs' => 'Aqui, você encontra todos os autores do site.
316 316
 Os status dos autores é indicado pela côr dos ícones (administrador = verde; redator = amarelo).',
317
-	'info_gauche_auteurs_exterieurs' => 'Os autores externos, sem acesso ao site, são indicados por um ícone azul;
317
+    'info_gauche_auteurs_exterieurs' => 'Os autores externos, sem acesso ao site, são indicados por um ícone azul;
318 318
 os autores excluídos por um ícone cinza.',
319
-	'info_gauche_messagerie' => 'O sistema interno de mensagens permite a troca de mensagens entre redatores, a criação de lembretes (para seu uso pessoal) ou exibir anúncios na página de entrada da área privada (se você for administrador).',
320
-	'info_gauche_statistiques_referers' => 'Esta página apresenta a lista dos  <i>referers</i>, ou seja, dos sites que contêm links para o seu site, unicamente para ontem e hoje; esta lista é zerada a cada 24 horas.',
321
-	'info_gauche_visiteurs_enregistres' => 'Você encontrará aqui os visitantes registrados na área pública do site (fóruns por assinatura).',
322
-	'info_generation_miniatures_images' => 'Geração de miniaturas das imagens',
323
-	'info_gerer_trad_objets' => '@objets@ : gerenciar os links de tradução',
324
-	'info_hebergeur_desactiver_envoi_email' => 'Alguns serviços de hospedagem desativam o envio automático de e-mails a partir dos seus servidores. Neste caso, as funcionalidades a seguir não funcionarão.',
325
-	'info_hier' => 'ontem:',
326
-	'info_identification_publique' => 'Sua identificação pública...',
327
-	'info_image_process' => 'Por favor, selecione o melhor método de criação dos ícones, clicando na imagem correspondente.',
328
-	'info_images_auto' => 'Imagens calculadas automaticamente',
329
-	'info_informations_personnelles' => 'Informações pessoais',
330
-	'info_inscription' => 'Inscrição online',
331
-	'info_inscription_automatique' => 'Inscrição automática de novos redatores',
332
-	'info_jeu_caractere' => 'Conjunto de caracteres do site',
333
-	'info_jours' => 'dias',
334
-	'info_laisser_champs_vides' => 'deixar estes campos vazios)',
335
-	'info_langues' => 'Idiomas do site',
336
-	'info_ldap_ok' => 'A autenticação LDAP está instalada.',
337
-	'info_lien_hypertexte' => 'Link hipertexto:',
338
-	'info_liste_nouveautes_envoyee' => 'A lista de novidades foi enviada',
339
-	'info_liste_redacteurs_connectes' => 'Lista de redatores conectados',
340
-	'info_login_existant' => 'Este login já está cadastrado.',
341
-	'info_login_trop_court' => 'Login muito curto.',
342
-	'info_login_trop_court_car_pluriel' => 'O login deve conter pelo menos @nb@ caracteres.',
343
-	'info_logos' => 'Os ícones',
344
-	'info_maximum' => 'máximo:',
345
-	'info_meme_rubrique' => 'Na mesma seção',
346
-	'info_message_en_redaction' => 'Suas mensagens em fase de redação',
347
-	'info_message_technique' => 'Mensagem técnica:',
348
-	'info_messagerie_interne' => 'Mensageria interna',
349
-	'info_mise_a_niveau_base' => 'atualização da sua base SQL',
350
-	'info_mise_a_niveau_base_2' => '{{Atenção!}} Você instalou uma versão de arquivos SPIP {anterior} à que estava instalada no site: a sua base de dados corre o risco de se corromper e o seu site não funcionar mais.<br />{{Reinstale os arquivos SPIP.}}',
351
-	'info_modification_enregistree' => 'Sua alteração foi gravada',
352
-	'info_modifier_auteur' => 'Editar o autor:',
353
-	'info_modifier_rubrique' => 'Editar a seção:',
354
-	'info_modifier_titre' => 'Editar: @titre@',
355
-	'info_mon_site_spip' => 'Meu site SPIP',
356
-	'info_moyenne' => 'média:',
357
-	'info_multi_cet_article' => 'Idioma desta matéria:',
358
-	'info_multi_langues_choisies' => 'Por favor, selecione a seguir os idiomas à disposição dos redatores do seu site.
319
+    'info_gauche_messagerie' => 'O sistema interno de mensagens permite a troca de mensagens entre redatores, a criação de lembretes (para seu uso pessoal) ou exibir anúncios na página de entrada da área privada (se você for administrador).',
320
+    'info_gauche_statistiques_referers' => 'Esta página apresenta a lista dos  <i>referers</i>, ou seja, dos sites que contêm links para o seu site, unicamente para ontem e hoje; esta lista é zerada a cada 24 horas.',
321
+    'info_gauche_visiteurs_enregistres' => 'Você encontrará aqui os visitantes registrados na área pública do site (fóruns por assinatura).',
322
+    'info_generation_miniatures_images' => 'Geração de miniaturas das imagens',
323
+    'info_gerer_trad_objets' => '@objets@ : gerenciar os links de tradução',
324
+    'info_hebergeur_desactiver_envoi_email' => 'Alguns serviços de hospedagem desativam o envio automático de e-mails a partir dos seus servidores. Neste caso, as funcionalidades a seguir não funcionarão.',
325
+    'info_hier' => 'ontem:',
326
+    'info_identification_publique' => 'Sua identificação pública...',
327
+    'info_image_process' => 'Por favor, selecione o melhor método de criação dos ícones, clicando na imagem correspondente.',
328
+    'info_images_auto' => 'Imagens calculadas automaticamente',
329
+    'info_informations_personnelles' => 'Informações pessoais',
330
+    'info_inscription' => 'Inscrição online',
331
+    'info_inscription_automatique' => 'Inscrição automática de novos redatores',
332
+    'info_jeu_caractere' => 'Conjunto de caracteres do site',
333
+    'info_jours' => 'dias',
334
+    'info_laisser_champs_vides' => 'deixar estes campos vazios)',
335
+    'info_langues' => 'Idiomas do site',
336
+    'info_ldap_ok' => 'A autenticação LDAP está instalada.',
337
+    'info_lien_hypertexte' => 'Link hipertexto:',
338
+    'info_liste_nouveautes_envoyee' => 'A lista de novidades foi enviada',
339
+    'info_liste_redacteurs_connectes' => 'Lista de redatores conectados',
340
+    'info_login_existant' => 'Este login já está cadastrado.',
341
+    'info_login_trop_court' => 'Login muito curto.',
342
+    'info_login_trop_court_car_pluriel' => 'O login deve conter pelo menos @nb@ caracteres.',
343
+    'info_logos' => 'Os ícones',
344
+    'info_maximum' => 'máximo:',
345
+    'info_meme_rubrique' => 'Na mesma seção',
346
+    'info_message_en_redaction' => 'Suas mensagens em fase de redação',
347
+    'info_message_technique' => 'Mensagem técnica:',
348
+    'info_messagerie_interne' => 'Mensageria interna',
349
+    'info_mise_a_niveau_base' => 'atualização da sua base SQL',
350
+    'info_mise_a_niveau_base_2' => '{{Atenção!}} Você instalou uma versão de arquivos SPIP {anterior} à que estava instalada no site: a sua base de dados corre o risco de se corromper e o seu site não funcionar mais.<br />{{Reinstale os arquivos SPIP.}}',
351
+    'info_modification_enregistree' => 'Sua alteração foi gravada',
352
+    'info_modifier_auteur' => 'Editar o autor:',
353
+    'info_modifier_rubrique' => 'Editar a seção:',
354
+    'info_modifier_titre' => 'Editar: @titre@',
355
+    'info_mon_site_spip' => 'Meu site SPIP',
356
+    'info_moyenne' => 'média:',
357
+    'info_multi_cet_article' => 'Idioma desta matéria:',
358
+    'info_multi_langues_choisies' => 'Por favor, selecione a seguir os idiomas à disposição dos redatores do seu site.
359 359
 Os idiomas já utilizados no site (no topo da lista) não podem ser desativados.',
360
-	'info_multi_objets' => '@objets@ : ativar o menu de idioma',
361
-	'info_multi_secteurs' => '... apenas para as seções situadas na raiz?',
362
-	'info_nb_articles' => '@nb@ matérias',
363
-	'info_nb_auteurs' => '@nb@ autores',
364
-	'info_nb_messages' => '@nb@ mensagens',
365
-	'info_nb_mots_cles' => '@nb@ palavras-chave',
366
-	'info_nb_rubriques' => '@nb@ seções',
367
-	'info_nb_visiteurs' => '@nb@ visitantes',
368
-	'info_nom' => 'Nome',
369
-	'info_nom_destinataire' => 'Nome do destinatário',
370
-	'info_nom_pas_conforme' => 'tags HTML não são permitidas',
371
-	'info_nom_site' => 'Nome do seu site',
372
-	'info_nombre_articles' => '@nb_articles@ matérias,',
373
-	'info_nombre_rubriques' => '@nb_rubriques@ seções,',
374
-	'info_nombre_sites' => '@nb_sites@ sites,',
375
-	'info_non_deplacer' => 'Não mover...',
376
-	'info_non_envoi_annonce_dernieres_nouveautes' => 'O SPIP pode enviar regularmente o anúncio das últimas novidades do site (matérias e notas publicadas recentemente).',
377
-	'info_non_envoi_liste_nouveautes' => 'Não enviar a lista de novidades',
378
-	'info_non_modifiable' => 'não pode ser modificado',
379
-	'info_non_suppression_mot_cle' => 'Eu não quero excluir esta palavra-chave.',
380
-	'info_notes' => 'Observações',
381
-	'info_nouvel_article' => 'Nova matéria',
382
-	'info_nouvelle_traduction' => 'Nova tradução:',
383
-	'info_numero_article' => 'MATÉRIA NÚMERO:',
384
-	'info_obligatoire_02' => '(obrigatório)',
385
-	'info_option_accepter_visiteurs' => 'Aceitar a inscrição de visitantes do site público',
386
-	'info_option_ne_pas_accepter_visiteurs' => 'Recusar a inscrição dos visitantes',
387
-	'info_options_avancees' => 'OPÇÕES AVANÇADAS',
388
-	'info_ou' => 'ou...',
389
-	'info_page_interdite' => 'Página não autorizada',
390
-	'info_par_nom' => 'por nome',
391
-	'info_par_nombre_article' => 'por número de matérias',
392
-	'info_par_statut' => 'por status',
393
-	'info_par_tri' => '’(por @tri@)’',
394
-	'info_passe_trop_court' => 'Senha muito curta.',
395
-	'info_passe_trop_court_car_pluriel' => 'A senha deve conter pelo menos @nb@ caracteres.',
396
-	'info_passes_identiques' => 'As duas senhas não são idênticas.',
397
-	'info_plus_cinq_car' => 'mais de 5 caracteres',
398
-	'info_plus_cinq_car_2' => '(Mais de 5 caracteres)',
399
-	'info_plus_trois_car' => '(Mais de 3 caracteres)',
400
-	'info_popularite' => 'popularidade: @popularite@; visitas: @visites@',
401
-	'info_post_scriptum' => 'Rodapé',
402
-	'info_post_scriptum_2' => 'Rodapé:',
403
-	'info_pour' => 'para',
404
-	'info_preview_texte' => 'É possível visualizar os diferentes elementos editoriais do site que tenham  pelo menos o status de «proposto», bem como os elementos em fase de redação de que se é autor. Esta funcionalidade deve estar disponível para os administradores, para os redatores, ou para ninguém?',
405
-	'info_procedez_par_etape' => 'proceder passo-a-passo',
406
-	'info_procedure_maj_version' => 'o procedimento de atualização deve ser rodado para adaptar a base de dados à nova versão do SPIP.',
407
-	'info_proxy_ok' => 'Teste do proxy bem sucedido',
408
-	'info_ps' => 'P.S.',
409
-	'info_publier' => 'publicar',
410
-	'info_publies' => 'Suas matérias publicadas online',
411
-	'info_question_accepter_visiteurs' => 'Se os templates do seu site prevêem o cadastramento de visitantes sem acesso à área privada, por favor, ative a opção abaixo:',
412
-	'info_question_inscription_nouveaux_redacteurs' => 'Você quer aceitar inscrições de novos redatores a partir do site público? Se você aceitar, os visitantes poderão se cadastrar através de um formulário automatizado, tendo acesso à área privada para propôr as suas próprias matérias. <div class="notice">Durante a fase de inscrição, os usuários recebem um e-mail automático, fornecendo-lhes os seus códigos de acesso à área privada. Alguns serviços de hospedagem desativam o envio de e-mails a partir dos seus servidores: nesse caso, a inscrição automática é impossível.</div>',
413
-	'info_qui_edite' => '@nom_auteur_modif@ trabalhou neste conteúdo há @date_diff@ minutos',
414
-	'info_racine_site' => 'Raiz do site',
415
-	'info_recharger_page' => 'Por favor, atualize esta página em alguns instantes.',
416
-	'info_recherche_auteur_zero' => 'Nenhum resultado para «@cherche_auteur@».',
417
-	'info_recommencer' => 'Por favor, recomece.',
418
-	'info_redacteur_1' => 'Redator',
419
-	'info_redacteur_2' => 'com acesso à área privada (<i>recomendado</i>)',
420
-	'info_redacteurs' => 'Redatores',
421
-	'info_redaction_en_cours' => 'EM FASE DE REDAÇÃO',
422
-	'info_redirection' => 'Redirecionamento',
423
-	'info_redirection_activee' => 'O redirecionamento foi ativado.',
424
-	'info_redirection_boucle' => 'Você tentou redirecionar a matéria para ela mesma.',
425
-	'info_redirection_desactivee' => 'O redirecionamento foi excluído.',
426
-	'info_refuses' => 'Suas matérias recusadas',
427
-	'info_reglage_ldap' => 'Opções: <b>Configuração da importação LDAP</b>',
428
-	'info_renvoi_article' => '<b>Redirecionamento.</b> Esta matéria redireciona para a página:',
429
-	'info_reserve_admin' => 'Apenas os administradores podem alterar este endereço.',
430
-	'info_restreindre_rubrique' => 'Restringir o gerenciamento à seção:',
431
-	'info_resultat_recherche' => 'Resultados da busca:',
432
-	'info_rubriques' => 'Seções',
433
-	'info_rubriques_02' => 'seções',
434
-	'info_rubriques_trouvees' => 'Seções encontradas',
435
-	'info_sans_titre' => 'Sem título',
436
-	'info_selection_chemin_acces' => '<b>Selecione</b> a seguir o caminho para acessar o diretório:',
437
-	'info_signatures' => 'assinaturas',
438
-	'info_site' => 'Site',
439
-	'info_site_2' => 'site:',
440
-	'info_site_min' => 'site',
441
-	'info_site_reference_2' => 'Site referenciado',
442
-	'info_site_web' => 'Website:',
443
-	'info_sites' => 'sites',
444
-	'info_sites_lies_mot' => 'Os sites referenciados vinculados a esta palavra-chave',
445
-	'info_sites_proxy' => 'Utilizar um proxy',
446
-	'info_sites_trouves' => 'Sites encontrados',
447
-	'info_sous_titre' => 'Subtítulo:',
448
-	'info_statut_administrateur' => 'Administrador',
449
-	'info_statut_auteur' => 'Status deste autor:',
450
-	'info_statut_auteur_2' => 'Eu sou',
451
-	'info_statut_auteur_a_confirmer' => 'Inscrição a confirmar',
452
-	'info_statut_auteur_autre' => 'Outro status:',
453
-	'info_statut_redacteur' => 'Redator',
454
-	'info_statut_utilisateurs_1' => 'Status padrão dos usuários importados',
455
-	'info_statut_utilisateurs_2' => 'Escolha o status atribuído às pessoas que constam do diretório LDAP, quando elas se conectarem pela primeira vêz. Você poderá, em seguida, alterar caso a caso este valor para cada autor.',
456
-	'info_suivi_activite' => 'Acompanhamento da atividade editorial',
457
-	'info_surtitre' => 'Sobretítulo:',
458
-	'info_syndication_integrale_1' => 'O seu site propõe arquivos de sindicação (ver «<a href="@url@">@titre@</a>»).',
459
-	'info_syndication_integrale_2' => 'Você deseja transmitir as matérias integralmente, ou difundir apenas um resumo de algumas centenas de caracteres?',
460
-	'info_table_prefix' => 'Você pode alterar o prefixo do nome das tabelas de dados (indispensável no caso de pretender instalar diversos sites na mesma base de dados). Este prefixo deve estar em minúsculas, não acentuadas, e sem espaços.',
461
-	'info_taille_maximale_images' => 'SPIP irá testar o tamanho máximo das imagens que o sistema pode tratar (em milhões de pixels).<br />As imagens muito grandes não serão reduzidas.',
462
-	'info_taille_maximale_vignette' => 'Tamanho máximo dos ícones gerados pelo sistema:',
463
-	'info_terminer_installation' => 'Você pode agora terminar o procedimento de instalação padrão.',
464
-	'info_texte' => 'Texto',
465
-	'info_texte_explicatif' => 'Texto explicativo',
466
-	'info_texte_long' => '(o texto é longo: ele aparecerá em diversas partes que serão recombinadas após validação.)',
467
-	'info_texte_message' => 'Texto da sua mensagem',
468
-	'info_texte_message_02' => 'Texto da mensagem',
469
-	'info_titre' => 'Título:',
470
-	'info_total' => 'total:',
471
-	'info_tous_articles_en_redaction' => 'Todas as matérias em fase de redação',
472
-	'info_tous_articles_presents' => 'Todas as matérias publicadas nesta seção',
473
-	'info_tous_articles_refuses' => 'Todas as matérias recusadas',
474
-	'info_tous_les' => 'todos os:',
475
-	'info_tout_site' => 'Todo o site',
476
-	'info_tout_site2' => 'A matéria não foi traduzida para este idioma.',
477
-	'info_tout_site3' => 'A matéria foi traduzida para este idioma, mas foram feitas alterações na matéria de referência. A tradução procisa ser atualizada.',
478
-	'info_tout_site4' => 'A matéria foi traduzida para este idioma e a tradução está em dia.',
479
-	'info_tout_site5' => 'Matéria original.',
480
-	'info_tout_site6' => '<b>Atenção:</b> apenas as matérias originais estão exibidas.
360
+    'info_multi_objets' => '@objets@ : ativar o menu de idioma',
361
+    'info_multi_secteurs' => '... apenas para as seções situadas na raiz?',
362
+    'info_nb_articles' => '@nb@ matérias',
363
+    'info_nb_auteurs' => '@nb@ autores',
364
+    'info_nb_messages' => '@nb@ mensagens',
365
+    'info_nb_mots_cles' => '@nb@ palavras-chave',
366
+    'info_nb_rubriques' => '@nb@ seções',
367
+    'info_nb_visiteurs' => '@nb@ visitantes',
368
+    'info_nom' => 'Nome',
369
+    'info_nom_destinataire' => 'Nome do destinatário',
370
+    'info_nom_pas_conforme' => 'tags HTML não são permitidas',
371
+    'info_nom_site' => 'Nome do seu site',
372
+    'info_nombre_articles' => '@nb_articles@ matérias,',
373
+    'info_nombre_rubriques' => '@nb_rubriques@ seções,',
374
+    'info_nombre_sites' => '@nb_sites@ sites,',
375
+    'info_non_deplacer' => 'Não mover...',
376
+    'info_non_envoi_annonce_dernieres_nouveautes' => 'O SPIP pode enviar regularmente o anúncio das últimas novidades do site (matérias e notas publicadas recentemente).',
377
+    'info_non_envoi_liste_nouveautes' => 'Não enviar a lista de novidades',
378
+    'info_non_modifiable' => 'não pode ser modificado',
379
+    'info_non_suppression_mot_cle' => 'Eu não quero excluir esta palavra-chave.',
380
+    'info_notes' => 'Observações',
381
+    'info_nouvel_article' => 'Nova matéria',
382
+    'info_nouvelle_traduction' => 'Nova tradução:',
383
+    'info_numero_article' => 'MATÉRIA NÚMERO:',
384
+    'info_obligatoire_02' => '(obrigatório)',
385
+    'info_option_accepter_visiteurs' => 'Aceitar a inscrição de visitantes do site público',
386
+    'info_option_ne_pas_accepter_visiteurs' => 'Recusar a inscrição dos visitantes',
387
+    'info_options_avancees' => 'OPÇÕES AVANÇADAS',
388
+    'info_ou' => 'ou...',
389
+    'info_page_interdite' => 'Página não autorizada',
390
+    'info_par_nom' => 'por nome',
391
+    'info_par_nombre_article' => 'por número de matérias',
392
+    'info_par_statut' => 'por status',
393
+    'info_par_tri' => '’(por @tri@)’',
394
+    'info_passe_trop_court' => 'Senha muito curta.',
395
+    'info_passe_trop_court_car_pluriel' => 'A senha deve conter pelo menos @nb@ caracteres.',
396
+    'info_passes_identiques' => 'As duas senhas não são idênticas.',
397
+    'info_plus_cinq_car' => 'mais de 5 caracteres',
398
+    'info_plus_cinq_car_2' => '(Mais de 5 caracteres)',
399
+    'info_plus_trois_car' => '(Mais de 3 caracteres)',
400
+    'info_popularite' => 'popularidade: @popularite@; visitas: @visites@',
401
+    'info_post_scriptum' => 'Rodapé',
402
+    'info_post_scriptum_2' => 'Rodapé:',
403
+    'info_pour' => 'para',
404
+    'info_preview_texte' => 'É possível visualizar os diferentes elementos editoriais do site que tenham  pelo menos o status de «proposto», bem como os elementos em fase de redação de que se é autor. Esta funcionalidade deve estar disponível para os administradores, para os redatores, ou para ninguém?',
405
+    'info_procedez_par_etape' => 'proceder passo-a-passo',
406
+    'info_procedure_maj_version' => 'o procedimento de atualização deve ser rodado para adaptar a base de dados à nova versão do SPIP.',
407
+    'info_proxy_ok' => 'Teste do proxy bem sucedido',
408
+    'info_ps' => 'P.S.',
409
+    'info_publier' => 'publicar',
410
+    'info_publies' => 'Suas matérias publicadas online',
411
+    'info_question_accepter_visiteurs' => 'Se os templates do seu site prevêem o cadastramento de visitantes sem acesso à área privada, por favor, ative a opção abaixo:',
412
+    'info_question_inscription_nouveaux_redacteurs' => 'Você quer aceitar inscrições de novos redatores a partir do site público? Se você aceitar, os visitantes poderão se cadastrar através de um formulário automatizado, tendo acesso à área privada para propôr as suas próprias matérias. <div class="notice">Durante a fase de inscrição, os usuários recebem um e-mail automático, fornecendo-lhes os seus códigos de acesso à área privada. Alguns serviços de hospedagem desativam o envio de e-mails a partir dos seus servidores: nesse caso, a inscrição automática é impossível.</div>',
413
+    'info_qui_edite' => '@nom_auteur_modif@ trabalhou neste conteúdo há @date_diff@ minutos',
414
+    'info_racine_site' => 'Raiz do site',
415
+    'info_recharger_page' => 'Por favor, atualize esta página em alguns instantes.',
416
+    'info_recherche_auteur_zero' => 'Nenhum resultado para «@cherche_auteur@».',
417
+    'info_recommencer' => 'Por favor, recomece.',
418
+    'info_redacteur_1' => 'Redator',
419
+    'info_redacteur_2' => 'com acesso à área privada (<i>recomendado</i>)',
420
+    'info_redacteurs' => 'Redatores',
421
+    'info_redaction_en_cours' => 'EM FASE DE REDAÇÃO',
422
+    'info_redirection' => 'Redirecionamento',
423
+    'info_redirection_activee' => 'O redirecionamento foi ativado.',
424
+    'info_redirection_boucle' => 'Você tentou redirecionar a matéria para ela mesma.',
425
+    'info_redirection_desactivee' => 'O redirecionamento foi excluído.',
426
+    'info_refuses' => 'Suas matérias recusadas',
427
+    'info_reglage_ldap' => 'Opções: <b>Configuração da importação LDAP</b>',
428
+    'info_renvoi_article' => '<b>Redirecionamento.</b> Esta matéria redireciona para a página:',
429
+    'info_reserve_admin' => 'Apenas os administradores podem alterar este endereço.',
430
+    'info_restreindre_rubrique' => 'Restringir o gerenciamento à seção:',
431
+    'info_resultat_recherche' => 'Resultados da busca:',
432
+    'info_rubriques' => 'Seções',
433
+    'info_rubriques_02' => 'seções',
434
+    'info_rubriques_trouvees' => 'Seções encontradas',
435
+    'info_sans_titre' => 'Sem título',
436
+    'info_selection_chemin_acces' => '<b>Selecione</b> a seguir o caminho para acessar o diretório:',
437
+    'info_signatures' => 'assinaturas',
438
+    'info_site' => 'Site',
439
+    'info_site_2' => 'site:',
440
+    'info_site_min' => 'site',
441
+    'info_site_reference_2' => 'Site referenciado',
442
+    'info_site_web' => 'Website:',
443
+    'info_sites' => 'sites',
444
+    'info_sites_lies_mot' => 'Os sites referenciados vinculados a esta palavra-chave',
445
+    'info_sites_proxy' => 'Utilizar um proxy',
446
+    'info_sites_trouves' => 'Sites encontrados',
447
+    'info_sous_titre' => 'Subtítulo:',
448
+    'info_statut_administrateur' => 'Administrador',
449
+    'info_statut_auteur' => 'Status deste autor:',
450
+    'info_statut_auteur_2' => 'Eu sou',
451
+    'info_statut_auteur_a_confirmer' => 'Inscrição a confirmar',
452
+    'info_statut_auteur_autre' => 'Outro status:',
453
+    'info_statut_redacteur' => 'Redator',
454
+    'info_statut_utilisateurs_1' => 'Status padrão dos usuários importados',
455
+    'info_statut_utilisateurs_2' => 'Escolha o status atribuído às pessoas que constam do diretório LDAP, quando elas se conectarem pela primeira vêz. Você poderá, em seguida, alterar caso a caso este valor para cada autor.',
456
+    'info_suivi_activite' => 'Acompanhamento da atividade editorial',
457
+    'info_surtitre' => 'Sobretítulo:',
458
+    'info_syndication_integrale_1' => 'O seu site propõe arquivos de sindicação (ver «<a href="@url@">@titre@</a>»).',
459
+    'info_syndication_integrale_2' => 'Você deseja transmitir as matérias integralmente, ou difundir apenas um resumo de algumas centenas de caracteres?',
460
+    'info_table_prefix' => 'Você pode alterar o prefixo do nome das tabelas de dados (indispensável no caso de pretender instalar diversos sites na mesma base de dados). Este prefixo deve estar em minúsculas, não acentuadas, e sem espaços.',
461
+    'info_taille_maximale_images' => 'SPIP irá testar o tamanho máximo das imagens que o sistema pode tratar (em milhões de pixels).<br />As imagens muito grandes não serão reduzidas.',
462
+    'info_taille_maximale_vignette' => 'Tamanho máximo dos ícones gerados pelo sistema:',
463
+    'info_terminer_installation' => 'Você pode agora terminar o procedimento de instalação padrão.',
464
+    'info_texte' => 'Texto',
465
+    'info_texte_explicatif' => 'Texto explicativo',
466
+    'info_texte_long' => '(o texto é longo: ele aparecerá em diversas partes que serão recombinadas após validação.)',
467
+    'info_texte_message' => 'Texto da sua mensagem',
468
+    'info_texte_message_02' => 'Texto da mensagem',
469
+    'info_titre' => 'Título:',
470
+    'info_total' => 'total:',
471
+    'info_tous_articles_en_redaction' => 'Todas as matérias em fase de redação',
472
+    'info_tous_articles_presents' => 'Todas as matérias publicadas nesta seção',
473
+    'info_tous_articles_refuses' => 'Todas as matérias recusadas',
474
+    'info_tous_les' => 'todos os:',
475
+    'info_tout_site' => 'Todo o site',
476
+    'info_tout_site2' => 'A matéria não foi traduzida para este idioma.',
477
+    'info_tout_site3' => 'A matéria foi traduzida para este idioma, mas foram feitas alterações na matéria de referência. A tradução procisa ser atualizada.',
478
+    'info_tout_site4' => 'A matéria foi traduzida para este idioma e a tradução está em dia.',
479
+    'info_tout_site5' => 'Matéria original.',
480
+    'info_tout_site6' => '<b>Atenção:</b> apenas as matérias originais estão exibidas.
481 481
 As traduções estão associadas ao original, numa côr que indica o seu status:',
482
-	'info_traductions' => 'Traduções',
483
-	'info_travail_colaboratif' => 'Trabalho colaborativo nas matérias',
484
-	'info_un_article' => 'uma matéria,',
485
-	'info_un_site' => 'um site,',
486
-	'info_une_rubrique' => 'uma seção,',
487
-	'info_une_rubrique_02' => '1 seção',
488
-	'info_url' => 'URL:',
489
-	'info_url_proxy' => 'URL do proxy',
490
-	'info_url_proxy_pas_conforme' => 'O URL do proxy não é válido.',
491
-	'info_url_site_pas_conforme' => 'O URL do site não é válido.',
492
-	'info_url_test_proxy' => 'URL de teste',
493
-	'info_urlref' => 'Link hipertexto:',
494
-	'info_utilisation_spip' => 'Você pode agora começar a utilizar o sistema de publicação assistida...',
495
-	'info_visites_par_mois' => 'Exibir por mês:',
496
-	'info_visiteur_1' => 'Visitante',
497
-	'info_visiteur_2' => 'do site público',
498
-	'info_visiteurs' => 'Visitantes',
499
-	'info_visiteurs_02' => 'Visitantes do site público',
500
-	'info_webmestre_forces' => 'Os webmasters são definidos em <tt>@file_options@</tt>.',
501
-	'install_adresse_base_hebergeur' => 'Endereço da base de dados atribuído pelo serviço de hospedagem:',
502
-	'install_connect_ok' => 'A nova base de dados foi corretamente declarada sob o nome de servidor @connect@.',
503
-	'install_echec_annonce' => 'A instalação irá, provavelmente, falhar, ou levar a um site que não funciona...',
504
-	'install_extension_php_obligatoire' => 'O SPIP exige a extensão php:',
505
-	'install_login_base_hebergeur' => 'Login de conexão atribuído pelo serviço de hospedagem:',
506
-	'install_nom_base_hebergeur' => 'Nome da base atribuído pelo serviço de hospedagem:',
507
-	'install_pas_table' => 'Base atualmente sem tabelas',
508
-	'install_pass_base_hebergeur' => 'Senha de conexão atribuída pelo serviço de hospedagem',
509
-	'install_php_extension' => 'As extensões a seguir estão faltando: @extensions@',
510
-	'install_php_version' => 'PHP versão @version@ é insuficiente (mínimo = @minimum@)',
511
-	'install_php_version_max' => 'A versão @version@ do PHP é muito recente (máximo = @maximum@)',
512
-	'install_select_langue' => 'Escolha um idioma e clique no botão «avançar» para iniciar o procedimento de instalação.',
513
-	'install_select_type_db' => 'Indicar o tipo de base de dados:',
514
-	'install_select_type_mysql' => 'MySQL',
515
-	'install_select_type_pg' => 'PostgreSQL',
516
-	'install_select_type_sqlite2' => 'SQLite 2',
517
-	'install_select_type_sqlite3' => 'SQLite 3',
518
-	'install_serveur_hebergeur' => 'Servidor de base de dados atribuído pelo serviço de hospedagem',
519
-	'install_table_prefix_hebergeur' => 'Prefixo de tabela atribuído pelo serviço de hospedagem:',
520
-	'install_tables_base' => 'Tabelas da base',
521
-	'install_types_db_connus' => 'SPIP pode usar <b>MySQL</b> (a mais comum), e <b>SQLite</b>.',
522
-	'install_types_db_connus_avertissement' => 'O suporte ao <b>PostgreSQL</b> é também proposto a título experimental',
523
-	'instituer_erreur_statut_a_change' => 'O status já foi alterado',
524
-	'instituer_erreur_statut_non_autorise' => 'Você não pode escolher este status',
525
-	'intem_redacteur' => 'redator',
526
-	'intitule_licence' => 'Licença',
527
-	'item_accepter_inscriptions' => 'Aceitar as inscrições',
528
-	'item_activer_messages_avertissement' => 'Ativar as mensagens de aviso',
529
-	'item_administrateur_2' => 'administrador',
530
-	'item_afficher_calendrier' => 'Exibir no calendário',
531
-	'item_autoriser_syndication_integrale' => 'Difundir a íntegra das matérias nos arquivos de sindicação',
532
-	'item_choix_administrateurs' => 'os administradores',
533
-	'item_choix_generation_miniature' => 'Gerar automaticamente as miniaturas das imagens.',
534
-	'item_choix_non_generation_miniature' => 'Não gerar as miniaturas das imagens.',
535
-	'item_choix_redacteurs' => 'os redatores',
536
-	'item_choix_visiteurs' => 'os visitantes do site público',
537
-	'item_creer_fichiers_authent' => 'Criar os arquivos .htpasswd',
538
-	'item_login' => 'Login',
539
-	'item_messagerie_agenda' => 'Ativar as mesagens internas e a agenda',
540
-	'item_mots_cles_association_articles' => 'às matérias',
541
-	'item_mots_cles_association_rubriques' => 'às seções',
542
-	'item_mots_cles_association_sites' => 'aos sites referenciados ou sindicados.',
543
-	'item_non' => 'Não',
544
-	'item_non_accepter_inscriptions' => 'Não aceitar inscrições',
545
-	'item_non_activer_messages_avertissement' => 'Sem mensagens de aviso',
546
-	'item_non_afficher_calendrier' => 'Não exibir no calendário',
547
-	'item_non_autoriser_syndication_integrale' => 'Difundir apenas um resumo',
548
-	'item_non_creer_fichiers_authent' => 'Não criar os arquivos',
549
-	'item_non_messagerie_agenda' => 'Desativar as mensagens internas e a agenda',
550
-	'item_non_publier_articles' => 'Não publicar as matérias antes da data de publicação fixada.',
551
-	'item_nouvel_auteur' => 'Novo autor',
552
-	'item_nouvelle_rubrique' => 'Nova seção',
553
-	'item_oui' => 'Sim',
554
-	'item_publier_articles' => 'Publicar as matérias seja qual for a sua data de publicação.',
555
-	'item_reponse_article' => 'Resposta à matéria',
556
-	'item_visiteur' => 'Visitante',
482
+    'info_traductions' => 'Traduções',
483
+    'info_travail_colaboratif' => 'Trabalho colaborativo nas matérias',
484
+    'info_un_article' => 'uma matéria,',
485
+    'info_un_site' => 'um site,',
486
+    'info_une_rubrique' => 'uma seção,',
487
+    'info_une_rubrique_02' => '1 seção',
488
+    'info_url' => 'URL:',
489
+    'info_url_proxy' => 'URL do proxy',
490
+    'info_url_proxy_pas_conforme' => 'O URL do proxy não é válido.',
491
+    'info_url_site_pas_conforme' => 'O URL do site não é válido.',
492
+    'info_url_test_proxy' => 'URL de teste',
493
+    'info_urlref' => 'Link hipertexto:',
494
+    'info_utilisation_spip' => 'Você pode agora começar a utilizar o sistema de publicação assistida...',
495
+    'info_visites_par_mois' => 'Exibir por mês:',
496
+    'info_visiteur_1' => 'Visitante',
497
+    'info_visiteur_2' => 'do site público',
498
+    'info_visiteurs' => 'Visitantes',
499
+    'info_visiteurs_02' => 'Visitantes do site público',
500
+    'info_webmestre_forces' => 'Os webmasters são definidos em <tt>@file_options@</tt>.',
501
+    'install_adresse_base_hebergeur' => 'Endereço da base de dados atribuído pelo serviço de hospedagem:',
502
+    'install_connect_ok' => 'A nova base de dados foi corretamente declarada sob o nome de servidor @connect@.',
503
+    'install_echec_annonce' => 'A instalação irá, provavelmente, falhar, ou levar a um site que não funciona...',
504
+    'install_extension_php_obligatoire' => 'O SPIP exige a extensão php:',
505
+    'install_login_base_hebergeur' => 'Login de conexão atribuído pelo serviço de hospedagem:',
506
+    'install_nom_base_hebergeur' => 'Nome da base atribuído pelo serviço de hospedagem:',
507
+    'install_pas_table' => 'Base atualmente sem tabelas',
508
+    'install_pass_base_hebergeur' => 'Senha de conexão atribuída pelo serviço de hospedagem',
509
+    'install_php_extension' => 'As extensões a seguir estão faltando: @extensions@',
510
+    'install_php_version' => 'PHP versão @version@ é insuficiente (mínimo = @minimum@)',
511
+    'install_php_version_max' => 'A versão @version@ do PHP é muito recente (máximo = @maximum@)',
512
+    'install_select_langue' => 'Escolha um idioma e clique no botão «avançar» para iniciar o procedimento de instalação.',
513
+    'install_select_type_db' => 'Indicar o tipo de base de dados:',
514
+    'install_select_type_mysql' => 'MySQL',
515
+    'install_select_type_pg' => 'PostgreSQL',
516
+    'install_select_type_sqlite2' => 'SQLite 2',
517
+    'install_select_type_sqlite3' => 'SQLite 3',
518
+    'install_serveur_hebergeur' => 'Servidor de base de dados atribuído pelo serviço de hospedagem',
519
+    'install_table_prefix_hebergeur' => 'Prefixo de tabela atribuído pelo serviço de hospedagem:',
520
+    'install_tables_base' => 'Tabelas da base',
521
+    'install_types_db_connus' => 'SPIP pode usar <b>MySQL</b> (a mais comum), e <b>SQLite</b>.',
522
+    'install_types_db_connus_avertissement' => 'O suporte ao <b>PostgreSQL</b> é também proposto a título experimental',
523
+    'instituer_erreur_statut_a_change' => 'O status já foi alterado',
524
+    'instituer_erreur_statut_non_autorise' => 'Você não pode escolher este status',
525
+    'intem_redacteur' => 'redator',
526
+    'intitule_licence' => 'Licença',
527
+    'item_accepter_inscriptions' => 'Aceitar as inscrições',
528
+    'item_activer_messages_avertissement' => 'Ativar as mensagens de aviso',
529
+    'item_administrateur_2' => 'administrador',
530
+    'item_afficher_calendrier' => 'Exibir no calendário',
531
+    'item_autoriser_syndication_integrale' => 'Difundir a íntegra das matérias nos arquivos de sindicação',
532
+    'item_choix_administrateurs' => 'os administradores',
533
+    'item_choix_generation_miniature' => 'Gerar automaticamente as miniaturas das imagens.',
534
+    'item_choix_non_generation_miniature' => 'Não gerar as miniaturas das imagens.',
535
+    'item_choix_redacteurs' => 'os redatores',
536
+    'item_choix_visiteurs' => 'os visitantes do site público',
537
+    'item_creer_fichiers_authent' => 'Criar os arquivos .htpasswd',
538
+    'item_login' => 'Login',
539
+    'item_messagerie_agenda' => 'Ativar as mesagens internas e a agenda',
540
+    'item_mots_cles_association_articles' => 'às matérias',
541
+    'item_mots_cles_association_rubriques' => 'às seções',
542
+    'item_mots_cles_association_sites' => 'aos sites referenciados ou sindicados.',
543
+    'item_non' => 'Não',
544
+    'item_non_accepter_inscriptions' => 'Não aceitar inscrições',
545
+    'item_non_activer_messages_avertissement' => 'Sem mensagens de aviso',
546
+    'item_non_afficher_calendrier' => 'Não exibir no calendário',
547
+    'item_non_autoriser_syndication_integrale' => 'Difundir apenas um resumo',
548
+    'item_non_creer_fichiers_authent' => 'Não criar os arquivos',
549
+    'item_non_messagerie_agenda' => 'Desativar as mensagens internas e a agenda',
550
+    'item_non_publier_articles' => 'Não publicar as matérias antes da data de publicação fixada.',
551
+    'item_nouvel_auteur' => 'Novo autor',
552
+    'item_nouvelle_rubrique' => 'Nova seção',
553
+    'item_oui' => 'Sim',
554
+    'item_publier_articles' => 'Publicar as matérias seja qual for a sua data de publicação.',
555
+    'item_reponse_article' => 'Resposta à matéria',
556
+    'item_visiteur' => 'Visitante',
557 557
 
558
-	// J
559
-	'jour_non_connu_nc' => 'n.c.',
558
+    // J
559
+    'jour_non_connu_nc' => 'n.c.',
560 560
 
561
-	// L
562
-	'label_bando_outils' => 'Barra de ferramentas',
563
-	'label_bando_outils_afficher' => 'Exibir as ferramentas',
564
-	'label_bando_outils_masquer' => 'Esconder as ferramentas',
565
-	'label_choix_langue' => 'Escolha o seu idioma',
566
-	'label_langue' => 'Idioma',
567
-	'label_nom_fichier_connect' => 'Informe o nome usado por este servidor',
568
-	'label_slogan_site' => 'Slogan do site',
569
-	'label_taille_ecran' => 'Largura da tela',
570
-	'label_texte_et_icones_navigation' => 'Menu de navegação',
571
-	'label_texte_et_icones_page' => 'Exibição na página',
572
-	'ldap_correspondance' => 'herança do campo @champ@',
573
-	'ldap_correspondance_1' => 'Herança dos campos LDAP',
574
-	'ldap_correspondance_2' => 'Para cada um dos campos SPIP a seguir, indique o nome do campo LDAP correspondente. Deixe em branco para não preencher, separe por espaços ou vírgulas para tentar vários campos LDAP.',
575
-	'lien_ajouter_auteur' => 'Incluir este autor',
576
-	'lien_ajouter_une_rubrique' => 'Incluir esta seção',
577
-	'lien_email' => 'e-mail',
578
-	'lien_nom_site' => 'NOME DO SITE:',
579
-	'lien_rapide_contenu' => 'Ir para o conteúdo',
580
-	'lien_rapide_navigation' => 'Ir para a navegação',
581
-	'lien_rapide_recherche' => 'Ir para a busca',
582
-	'lien_retirer_auteur' => 'Retirar o autor',
583
-	'lien_retirer_rubrique' => 'Excluir a seção',
584
-	'lien_retirer_tous_auteurs' => 'Retirar todos os autores',
585
-	'lien_retirer_toutes_rubriques' => 'Retirar todas as seções',
586
-	'lien_site' => 'site',
587
-	'lien_tout_decocher' => 'Desmarcar tudo',
588
-	'lien_tout_deplier' => 'Expandir tudo',
589
-	'lien_tout_replier' => 'Retrair tudo',
590
-	'lien_tout_supprimer' => 'Excluir tudo',
591
-	'lien_trier_nom' => 'Ordenar pelo nome',
592
-	'lien_trier_nombre_articles' => 'Ordenar por número de matérias',
593
-	'lien_trier_statut' => 'Ordenar pelo status',
594
-	'lien_voir_en_ligne' => 'VER ONLINE:',
595
-	'logo_article' => 'Ícone da matéria',
596
-	'logo_auteur' => 'Ícone do autor',
597
-	'logo_rubrique' => 'Ícone da seção',
598
-	'logo_site' => 'Ícone deste site',
599
-	'logo_standard_rubrique' => 'Ícone padrão das seções',
600
-	'logo_survol' => 'Ícone para mouseOver',
561
+    // L
562
+    'label_bando_outils' => 'Barra de ferramentas',
563
+    'label_bando_outils_afficher' => 'Exibir as ferramentas',
564
+    'label_bando_outils_masquer' => 'Esconder as ferramentas',
565
+    'label_choix_langue' => 'Escolha o seu idioma',
566
+    'label_langue' => 'Idioma',
567
+    'label_nom_fichier_connect' => 'Informe o nome usado por este servidor',
568
+    'label_slogan_site' => 'Slogan do site',
569
+    'label_taille_ecran' => 'Largura da tela',
570
+    'label_texte_et_icones_navigation' => 'Menu de navegação',
571
+    'label_texte_et_icones_page' => 'Exibição na página',
572
+    'ldap_correspondance' => 'herança do campo @champ@',
573
+    'ldap_correspondance_1' => 'Herança dos campos LDAP',
574
+    'ldap_correspondance_2' => 'Para cada um dos campos SPIP a seguir, indique o nome do campo LDAP correspondente. Deixe em branco para não preencher, separe por espaços ou vírgulas para tentar vários campos LDAP.',
575
+    'lien_ajouter_auteur' => 'Incluir este autor',
576
+    'lien_ajouter_une_rubrique' => 'Incluir esta seção',
577
+    'lien_email' => 'e-mail',
578
+    'lien_nom_site' => 'NOME DO SITE:',
579
+    'lien_rapide_contenu' => 'Ir para o conteúdo',
580
+    'lien_rapide_navigation' => 'Ir para a navegação',
581
+    'lien_rapide_recherche' => 'Ir para a busca',
582
+    'lien_retirer_auteur' => 'Retirar o autor',
583
+    'lien_retirer_rubrique' => 'Excluir a seção',
584
+    'lien_retirer_tous_auteurs' => 'Retirar todos os autores',
585
+    'lien_retirer_toutes_rubriques' => 'Retirar todas as seções',
586
+    'lien_site' => 'site',
587
+    'lien_tout_decocher' => 'Desmarcar tudo',
588
+    'lien_tout_deplier' => 'Expandir tudo',
589
+    'lien_tout_replier' => 'Retrair tudo',
590
+    'lien_tout_supprimer' => 'Excluir tudo',
591
+    'lien_trier_nom' => 'Ordenar pelo nome',
592
+    'lien_trier_nombre_articles' => 'Ordenar por número de matérias',
593
+    'lien_trier_statut' => 'Ordenar pelo status',
594
+    'lien_voir_en_ligne' => 'VER ONLINE:',
595
+    'logo_article' => 'Ícone da matéria',
596
+    'logo_auteur' => 'Ícone do autor',
597
+    'logo_rubrique' => 'Ícone da seção',
598
+    'logo_site' => 'Ícone deste site',
599
+    'logo_standard_rubrique' => 'Ícone padrão das seções',
600
+    'logo_survol' => 'Ícone para mouseOver',
601 601
 
602
-	// M
603
-	'menu_aide_installation_choix_base' => 'Seleção da sua base',
604
-	'module_fichier_langue' => 'Arquivo de idioma',
605
-	'module_raccourci' => 'Atalho',
606
-	'module_texte_affiche' => 'Texto exibido',
607
-	'module_texte_explicatif' => 'Você pode inserir os atalhos a seguir nos templates do seu site público. Eles serão traduzidos automaticamente para os idiomas para os quais exista um arquivo de idioma.',
608
-	'module_texte_traduction' => 'O arquivo de idioma «@module@» está disponível em:',
609
-	'mois_non_connu' => 'desconhecido',
602
+    // M
603
+    'menu_aide_installation_choix_base' => 'Seleção da sua base',
604
+    'module_fichier_langue' => 'Arquivo de idioma',
605
+    'module_raccourci' => 'Atalho',
606
+    'module_texte_affiche' => 'Texto exibido',
607
+    'module_texte_explicatif' => 'Você pode inserir os atalhos a seguir nos templates do seu site público. Eles serão traduzidos automaticamente para os idiomas para os quais exista um arquivo de idioma.',
608
+    'module_texte_traduction' => 'O arquivo de idioma «@module@» está disponível em:',
609
+    'mois_non_connu' => 'desconhecido',
610 610
 
611
-	// N
612
-	'nouvelle_version_spip' => 'A versão @version@ do SPIP está disponível',
613
-	'nouvelle_version_spip_majeure' => 'Uma nova versão SPIP @version@ está disponível',
611
+    // N
612
+    'nouvelle_version_spip' => 'A versão @version@ do SPIP está disponível',
613
+    'nouvelle_version_spip_majeure' => 'Uma nova versão SPIP @version@ está disponível',
614 614
 
615
-	// O
616
-	'onglet_contenu' => 'Conteúdo',
617
-	'onglet_declarer_une_autre_base' => 'Configurar outra base',
618
-	'onglet_discuter' => 'Discutir',
619
-	'onglet_interactivite' => 'Interatividade',
620
-	'onglet_proprietes' => 'Propriedades',
621
-	'onglet_repartition_actuelle' => 'atualmente',
622
-	'onglet_sous_rubriques' => 'Subseções',
615
+    // O
616
+    'onglet_contenu' => 'Conteúdo',
617
+    'onglet_declarer_une_autre_base' => 'Configurar outra base',
618
+    'onglet_discuter' => 'Discutir',
619
+    'onglet_interactivite' => 'Interatividade',
620
+    'onglet_proprietes' => 'Propriedades',
621
+    'onglet_repartition_actuelle' => 'atualmente',
622
+    'onglet_sous_rubriques' => 'Subseções',
623 623
 
624
-	// P
625
-	'page_pas_proxy' => 'Esta página não deve passar pelo proxy',
626
-	'pas_de_proxy_pour' => 'Se necessário, indique as máquinas ou domínios para os quais este proxy não se aplica (por exemplo: @exemple@)',
627
-	'phpinfo' => 'Configuração PHP',
628
-	'plugin_charge_paquet' => 'Carregamento do pacote @name@',
629
-	'plugin_charger' => 'Transferir',
630
-	'plugin_erreur_charger' => 'erro: não foi possível carregar @zip@',
631
-	'plugin_erreur_droit1' => 'O diretório <code>@dest@</code> não está acessível para escrita.',
632
-	'plugin_erreur_droit2' => 'Por favor, verifique os direitos deste diretório (e criá-lo, caso não exista), ou instalar os arquivos por FTP.',
633
-	'plugin_erreur_zip' => 'falha pclzip: erro @status@',
634
-	'plugin_etat_developpement' => 'em desenvolvimento',
635
-	'plugin_etat_experimental' => 'experimental',
636
-	'plugin_etat_stable' => 'estável',
637
-	'plugin_etat_test' => 'em teste',
638
-	'plugin_impossible_activer' => 'Não foi possível ativar o plugin @plugin@',
639
-	'plugin_info_automatique1' => 'Se você deseja autorizar a instalaçào automática dos plugins, por favor:',
640
-	'plugin_info_automatique1_lib' => 'Se você deseja autorizar a instalação automática desta biblioteca, por favor:',
641
-	'plugin_info_automatique2' => 'crie um diretório <code>@rep@</code> ;',
642
-	'plugin_info_automatique3' => 'verifique se o servidor está autorizado a escrever neste diretório',
643
-	'plugin_info_automatique_creer' => 'a ser criado na raiz do site.',
644
-	'plugin_info_automatique_exemples' => 'exemplos:',
645
-	'plugin_info_automatique_ftp' => 'Você pode instalar os plugins, por FTP, no diretório <tt>@rep@</tt>',
646
-	'plugin_info_automatique_lib' => 'Alguns plugins precisam também poder transferir arquivos para o diretório <code>lib/</code>, a ser criado, caso não exista, na raiz do site.',
647
-	'plugin_info_automatique_liste' => 'Suas listas de plugins:',
648
-	'plugin_info_automatique_liste_officielle' => 'os plugins oficiais',
649
-	'plugin_info_automatique_liste_update' => 'Atualizar as listas',
650
-	'plugin_info_automatique_ou' => 'ou...',
651
-	'plugin_info_automatique_select' => 'Selecione abaixo um plugin: O SPIP o transferirá e o instalará no diretório <code>@rep@</code>; se o plugin já existir, será atualizado.',
652
-	'plugin_info_credit' => 'Créditos',
653
-	'plugin_info_erreur_xml' => 'A declaração deste plugin está incorreta',
654
-	'plugin_info_install_ok' => 'Instalação bem sucedida',
655
-	'plugin_info_necessite' => 'Requer:',
656
-	'plugin_info_non_compatible_spip' => 'Este plugin não é compatível com esta versão do SPIP',
657
-	'plugin_info_plugins_dist_1' => 'Os plugins abaixo são carregados e ativados no diretório @plugins_dist@.',
658
-	'plugin_info_plugins_dist_2' => 'Eles não são desativáveis.',
659
-	'plugin_info_telecharger' => 'transferir de @url@ e instalar em @rep@',
660
-	'plugin_info_upgrade_ok' => 'Atualização bem sucedida',
661
-	'plugin_librairies_installees' => 'Bibliotecas instaladas',
662
-	'plugin_necessite_extension_php' => 'Requer a extensão PHP @plugin@ na versão @version@.',
663
-	'plugin_necessite_extension_php_sans_version' => 'Requer a extensão PHP @plugin@',
664
-	'plugin_necessite_lib' => 'Este plugin precisa da biblioteca @lib@',
665
-	'plugin_necessite_php' => 'Requer @plugin@ na versão @version@.',
666
-	'plugin_necessite_plugin' => 'Precisa do plugin @plugin@, na versão @version@.',
667
-	'plugin_necessite_plugin_sans_version' => 'Precisa do plugin @plugin@',
668
-	'plugin_necessite_spip' => 'É necessário o SPIP na versão @version@, pelo menos.',
669
-	'plugin_source' => 'fonte: ',
670
-	'plugin_titre_automatique' => 'Instalação automática',
671
-	'plugin_titre_automatique_ajouter' => 'Incluir plugins',
672
-	'plugin_titre_installation' => 'Instalação do plugin @plugin@',
673
-	'plugin_titre_modifier' => 'Meus plugins',
674
-	'plugin_utilise_extension_php' => 'A extensão PHP @plugin@ deve estar na versão @version@.',
675
-	'plugin_utilise_php' => '@plugin@ deve estar na versão @version@.',
676
-	'plugin_utilise_plugin' => 'O plugin @plugin@ deve estar na versão @version@.',
677
-	'plugin_zip_active' => 'Continue para o ativar',
678
-	'plugin_zip_adresse' => 'Indique abaixo o endereço de um arquivo zip de plugin a ser transferido, ou ainda o endereço de uma lista de plugins.',
679
-	'plugin_zip_adresse_champ' => 'Endereço do plugin ou da lista',
680
-	'plugin_zip_content' => 'Ele contém os arquivos a seguir (@taille@),<br />prontos para serem instalados no diretório <code>@rep@</code>',
681
-	'plugin_zip_installe_finie' => 'O arquivo @zip@ foi descompactado e instalado.',
682
-	'plugin_zip_installe_rep_finie' => 'O arquivo @zip@ foi descompactado e instalado no diretório @rep@',
683
-	'plugin_zip_installer' => 'Você pode, agora, instalá-lo.',
684
-	'plugin_zip_telecharge' => 'O arquivo @zip@ foi transferido',
685
-	'plugins_actif_aucun' => 'Nenhum plugin ativado.',
686
-	'plugins_actif_un' => 'Um plugin ativado.',
687
-	'plugins_actifs' => '@count@ plugins ativados.',
688
-	'plugins_actifs_liste' => 'Ativos',
689
-	'plugins_compte' => '@count@ plugins',
690
-	'plugins_disponible_un' => 'Um plugin disponível.',
691
-	'plugins_disponibles' => '@count@ plugins disponiveis.',
692
-	'plugins_erreur' => 'Erro nos plugins: @plugins@',
693
-	'plugins_liste' => 'Lista dos plugins',
694
-	'plugins_liste_dist' => 'Plugins bloqueados',
695
-	'plugins_recents' => 'Plugins recentes.',
696
-	'plugins_tous_liste' => 'Todos',
697
-	'plugins_vue_hierarchie' => 'Hierarquia',
698
-	'plugins_vue_liste' => 'Lista',
699
-	'protocole_ldap' => 'Versão do protocolo:',
624
+    // P
625
+    'page_pas_proxy' => 'Esta página não deve passar pelo proxy',
626
+    'pas_de_proxy_pour' => 'Se necessário, indique as máquinas ou domínios para os quais este proxy não se aplica (por exemplo: @exemple@)',
627
+    'phpinfo' => 'Configuração PHP',
628
+    'plugin_charge_paquet' => 'Carregamento do pacote @name@',
629
+    'plugin_charger' => 'Transferir',
630
+    'plugin_erreur_charger' => 'erro: não foi possível carregar @zip@',
631
+    'plugin_erreur_droit1' => 'O diretório <code>@dest@</code> não está acessível para escrita.',
632
+    'plugin_erreur_droit2' => 'Por favor, verifique os direitos deste diretório (e criá-lo, caso não exista), ou instalar os arquivos por FTP.',
633
+    'plugin_erreur_zip' => 'falha pclzip: erro @status@',
634
+    'plugin_etat_developpement' => 'em desenvolvimento',
635
+    'plugin_etat_experimental' => 'experimental',
636
+    'plugin_etat_stable' => 'estável',
637
+    'plugin_etat_test' => 'em teste',
638
+    'plugin_impossible_activer' => 'Não foi possível ativar o plugin @plugin@',
639
+    'plugin_info_automatique1' => 'Se você deseja autorizar a instalaçào automática dos plugins, por favor:',
640
+    'plugin_info_automatique1_lib' => 'Se você deseja autorizar a instalação automática desta biblioteca, por favor:',
641
+    'plugin_info_automatique2' => 'crie um diretório <code>@rep@</code> ;',
642
+    'plugin_info_automatique3' => 'verifique se o servidor está autorizado a escrever neste diretório',
643
+    'plugin_info_automatique_creer' => 'a ser criado na raiz do site.',
644
+    'plugin_info_automatique_exemples' => 'exemplos:',
645
+    'plugin_info_automatique_ftp' => 'Você pode instalar os plugins, por FTP, no diretório <tt>@rep@</tt>',
646
+    'plugin_info_automatique_lib' => 'Alguns plugins precisam também poder transferir arquivos para o diretório <code>lib/</code>, a ser criado, caso não exista, na raiz do site.',
647
+    'plugin_info_automatique_liste' => 'Suas listas de plugins:',
648
+    'plugin_info_automatique_liste_officielle' => 'os plugins oficiais',
649
+    'plugin_info_automatique_liste_update' => 'Atualizar as listas',
650
+    'plugin_info_automatique_ou' => 'ou...',
651
+    'plugin_info_automatique_select' => 'Selecione abaixo um plugin: O SPIP o transferirá e o instalará no diretório <code>@rep@</code>; se o plugin já existir, será atualizado.',
652
+    'plugin_info_credit' => 'Créditos',
653
+    'plugin_info_erreur_xml' => 'A declaração deste plugin está incorreta',
654
+    'plugin_info_install_ok' => 'Instalação bem sucedida',
655
+    'plugin_info_necessite' => 'Requer:',
656
+    'plugin_info_non_compatible_spip' => 'Este plugin não é compatível com esta versão do SPIP',
657
+    'plugin_info_plugins_dist_1' => 'Os plugins abaixo são carregados e ativados no diretório @plugins_dist@.',
658
+    'plugin_info_plugins_dist_2' => 'Eles não são desativáveis.',
659
+    'plugin_info_telecharger' => 'transferir de @url@ e instalar em @rep@',
660
+    'plugin_info_upgrade_ok' => 'Atualização bem sucedida',
661
+    'plugin_librairies_installees' => 'Bibliotecas instaladas',
662
+    'plugin_necessite_extension_php' => 'Requer a extensão PHP @plugin@ na versão @version@.',
663
+    'plugin_necessite_extension_php_sans_version' => 'Requer a extensão PHP @plugin@',
664
+    'plugin_necessite_lib' => 'Este plugin precisa da biblioteca @lib@',
665
+    'plugin_necessite_php' => 'Requer @plugin@ na versão @version@.',
666
+    'plugin_necessite_plugin' => 'Precisa do plugin @plugin@, na versão @version@.',
667
+    'plugin_necessite_plugin_sans_version' => 'Precisa do plugin @plugin@',
668
+    'plugin_necessite_spip' => 'É necessário o SPIP na versão @version@, pelo menos.',
669
+    'plugin_source' => 'fonte: ',
670
+    'plugin_titre_automatique' => 'Instalação automática',
671
+    'plugin_titre_automatique_ajouter' => 'Incluir plugins',
672
+    'plugin_titre_installation' => 'Instalação do plugin @plugin@',
673
+    'plugin_titre_modifier' => 'Meus plugins',
674
+    'plugin_utilise_extension_php' => 'A extensão PHP @plugin@ deve estar na versão @version@.',
675
+    'plugin_utilise_php' => '@plugin@ deve estar na versão @version@.',
676
+    'plugin_utilise_plugin' => 'O plugin @plugin@ deve estar na versão @version@.',
677
+    'plugin_zip_active' => 'Continue para o ativar',
678
+    'plugin_zip_adresse' => 'Indique abaixo o endereço de um arquivo zip de plugin a ser transferido, ou ainda o endereço de uma lista de plugins.',
679
+    'plugin_zip_adresse_champ' => 'Endereço do plugin ou da lista',
680
+    'plugin_zip_content' => 'Ele contém os arquivos a seguir (@taille@),<br />prontos para serem instalados no diretório <code>@rep@</code>',
681
+    'plugin_zip_installe_finie' => 'O arquivo @zip@ foi descompactado e instalado.',
682
+    'plugin_zip_installe_rep_finie' => 'O arquivo @zip@ foi descompactado e instalado no diretório @rep@',
683
+    'plugin_zip_installer' => 'Você pode, agora, instalá-lo.',
684
+    'plugin_zip_telecharge' => 'O arquivo @zip@ foi transferido',
685
+    'plugins_actif_aucun' => 'Nenhum plugin ativado.',
686
+    'plugins_actif_un' => 'Um plugin ativado.',
687
+    'plugins_actifs' => '@count@ plugins ativados.',
688
+    'plugins_actifs_liste' => 'Ativos',
689
+    'plugins_compte' => '@count@ plugins',
690
+    'plugins_disponible_un' => 'Um plugin disponível.',
691
+    'plugins_disponibles' => '@count@ plugins disponiveis.',
692
+    'plugins_erreur' => 'Erro nos plugins: @plugins@',
693
+    'plugins_liste' => 'Lista dos plugins',
694
+    'plugins_liste_dist' => 'Plugins bloqueados',
695
+    'plugins_recents' => 'Plugins recentes.',
696
+    'plugins_tous_liste' => 'Todos',
697
+    'plugins_vue_hierarchie' => 'Hierarquia',
698
+    'plugins_vue_liste' => 'Lista',
699
+    'protocole_ldap' => 'Versão do protocolo:',
700 700
 
701
-	// Q
702
-	'queue_args_fonction_label' => 'Argumentos passados à função @fonction@',
703
-	'queue_args_voir' => 'Ver os argumentos',
704
-	'queue_executer_maintenant' => 'Executar agora',
705
-	'queue_fonction_label' => 'Função',
706
-	'queue_info_purger' => 'Você pode excluir todas as tarefas de fundo em espera e reinicializar a lista com as tarefas periódicas',
707
-	'queue_liens_label' => 'Links',
708
-	'queue_nb_jobs_in_queue' => '@nb@ tarefas em espera',
709
-	'queue_next_job_in_nb_sec' => 'Próxima tarefa em @nb@ s',
710
-	'queue_next_job_scheduled' => 'Próxima tarefa',
711
-	'queue_no_job_in_queue' => 'Nenhum tarefa em espera',
712
-	'queue_one_job_in_queue' => '1 tarefa em espera',
713
-	'queue_priorite_tache' => 'prioridade',
714
-	'queue_purger_queue' => 'Reiniciar a lista de tarefas',
715
-	'queue_statut_en_cours' => 'Em curso',
716
-	'queue_titre' => 'Tarefas de fundo',
701
+    // Q
702
+    'queue_args_fonction_label' => 'Argumentos passados à função @fonction@',
703
+    'queue_args_voir' => 'Ver os argumentos',
704
+    'queue_executer_maintenant' => 'Executar agora',
705
+    'queue_fonction_label' => 'Função',
706
+    'queue_info_purger' => 'Você pode excluir todas as tarefas de fundo em espera e reinicializar a lista com as tarefas periódicas',
707
+    'queue_liens_label' => 'Links',
708
+    'queue_nb_jobs_in_queue' => '@nb@ tarefas em espera',
709
+    'queue_next_job_in_nb_sec' => 'Próxima tarefa em @nb@ s',
710
+    'queue_next_job_scheduled' => 'Próxima tarefa',
711
+    'queue_no_job_in_queue' => 'Nenhum tarefa em espera',
712
+    'queue_one_job_in_queue' => '1 tarefa em espera',
713
+    'queue_priorite_tache' => 'prioridade',
714
+    'queue_purger_queue' => 'Reiniciar a lista de tarefas',
715
+    'queue_statut_en_cours' => 'Em curso',
716
+    'queue_titre' => 'Tarefas de fundo',
717 717
 
718
-	// R
719
-	'repertoire_plugins' => 'Diretório:',
720
-	'required' => '(obrigatório)',
718
+    // R
719
+    'repertoire_plugins' => 'Diretório:',
720
+    'required' => '(obrigatório)',
721 721
 
722
-	// S
723
-	'sans_heure' => 'sem hora',
724
-	'statut_admin_restreint' => '(admin limitado)',
725
-	'statut_webmestre' => 'webmaster',
722
+    // S
723
+    'sans_heure' => 'sem hora',
724
+    'statut_admin_restreint' => '(admin limitado)',
725
+    'statut_webmestre' => 'webmaster',
726 726
 
727
-	// T
728
-	'tache_cron_asap' => 'Tarefa CRON @function@ (ASAP)',
729
-	'tache_cron_secondes' => 'Tarefa CRON @function@ (a cada @nb@ s)',
730
-	'taille_cache_image' => 'As imagens calculadas automaticamente pelo SPIP (ícones de documentos, títulos apresentados sob a forma gráfica, funções matemáticas em formato TeX...) ocupam, no diretório @dir@, um total de @taille@.',
731
-	'taille_cache_moins_de' => 'O tamanho do cache é menor do que @octets@.',
732
-	'taille_cache_octets' => 'O tamanho atual do cache é de cerca de @octets@.',
733
-	'taille_cache_vide' => 'O cache está vazio.',
734
-	'taille_repertoire_cache' => 'Tamanho do diretório cache',
735
-	'text_article_propose_publication' => 'Matéria proposta para publicação.',
736
-	'texte_acces_ldap_anonyme_1' => 'Alguns servidores LDAP não aceitam nenhum acesso anônimo. Neste caso, é necessário especificar um identificador de acesso inicial de modo a poder, em seguida, pesquisar as informações no diretório. Na maior parte dos casos, entretanto, os campos a seguir poderão ser deixados em branco.',
737
-	'texte_admin_effacer_01' => 'Este comando apaga <i>todo</i> o conteúdo da base de dados,incluindo <i>todos</i> os acessos dos redatores e administradores. Após executá-lo, você deverá reinstalar o SPIP para recriar uma nova base de dados bem como um acesso inicial de administrador.',
738
-	'texte_adresse_annuaire_1' => '(Se o seu diretório está instalado na mesma máquina que este website, trata-se provavelmente de «localhost».)',
739
-	'texte_ajout_auteur' => 'O autor a seguir foi incluído na matéria:',
740
-	'texte_annuaire_ldap_1' => 'Se você tem acesso a um diretório LDAP, você poderá utilizá-lo para importar automaticamente os usuários para o SPIP.',
741
-	'texte_article_statut' => 'Esta matéria está:',
742
-	'texte_article_virtuel' => 'Matéria virtual',
743
-	'texte_article_virtuel_reference' => '<b>Matéria virtual:</b> matéria referenciada no seu site SPIP, mas redirecionada para um outro URL. Para cancelar o redirecionamento, apague o URL abaixo.',
744
-	'texte_aucun_resultat_auteur' => 'Nenhum resultado para "@cherche_auteur@"',
745
-	'texte_auteur_messagerie' => 'Este site pode monitorar permanentemente a lista de editores conectados, permitindo-lhe trocar mensagens em tempo real. Você pode decidir não aparecer nessa lista (ficando "invisível" para os outros usuários).',
746
-	'texte_auteurs' => 'OS AUTORES',
747
-	'texte_choix_base_1' => 'Escolha a sua base:',
748
-	'texte_choix_base_2' => 'O servidor SQL contém várias bases de dados.',
749
-	'texte_choix_base_3' => '<b>Escolha</b> abaixo a que lhe foi atribuída pelo seu serviço de hospedagem:',
750
-	'texte_choix_table_prefix' => 'Prefixo das tabelas:',
751
-	'texte_compte_element' => '@count@ elemento',
752
-	'texte_compte_elements' => '@count@ elementos',
753
-	'texte_conflit_edition_correction' => 'Por favor, controle abaixo as diferenças entre as duas versões do texto; você pode também copiar as suas modificações e depois recomeçar.',
754
-	'texte_connexion_mysql' => 'Consulte as informações fornecidas pelo seu serviço de hospedagem: nelas, você deverá encontrar o servidor de base de dados fornecido e os seus dados de conexão ao servidor SQL.',
755
-	'texte_contenu_article' => '(Conteúdo da matéria em poucas palavras.)',
756
-	'texte_contenu_articles' => 'De acordo com o layout adotado pelo seu site, você poderá decidir se certos elementos das matérias serão utilizados. Use a listagem abaixo para indicar quais elementos estão disponíveis.',
757
-	'texte_crash_base' => 'Se a sua base de dados se corrompeu, você poderá tentar uma reparação automática.',
758
-	'texte_creer_rubrique' => 'Antes de poder escrever matérias, você precisa criar uma seção.',
759
-	'texte_date_creation_article' => 'DATA DE CRIAÇÃO DA MATÉRIA:',
760
-	'texte_date_creation_objet' => 'Data de criação:', # on ajoute le &quot;:&quot;
761
-	'texte_date_publication_anterieure' => 'Data de redação anterior:',
762
-	'texte_date_publication_anterieure_nonaffichee' => 'Não exibir a data de redação anterior.',
763
-	'texte_date_publication_article' => 'DATA DE PUBLICAÇÃO ONLINE:',
764
-	'texte_date_publication_objet' => 'Data de publicação online:',
765
-	'texte_definir_comme_traduction_rubrique' => 'Esta seção é uma tradução da seção número:',
766
-	'texte_descriptif_rapide' => 'Descrição rápida',
767
-	'texte_effacer_base' => 'Apagar a base de dados do SPIP',
768
-	'texte_effacer_statistiques' => 'Apagar as estatísticas',
769
-	'texte_en_cours_validation' => 'Os conteúdos abaixo estão propostos para publicação.',
770
-	'texte_enrichir_mise_a_jour' => 'Você pode enriquecer a diagramação do seu texto usando «atalhos tipográficos».',
771
-	'texte_fichier_authent' => '<b>O SPIP pode criar os arquivos especiais  <tt>.htpasswd</tt> e <tt>.htpasswd-admin</tt> no diretório @dossier@?</b><p>
727
+    // T
728
+    'tache_cron_asap' => 'Tarefa CRON @function@ (ASAP)',
729
+    'tache_cron_secondes' => 'Tarefa CRON @function@ (a cada @nb@ s)',
730
+    'taille_cache_image' => 'As imagens calculadas automaticamente pelo SPIP (ícones de documentos, títulos apresentados sob a forma gráfica, funções matemáticas em formato TeX...) ocupam, no diretório @dir@, um total de @taille@.',
731
+    'taille_cache_moins_de' => 'O tamanho do cache é menor do que @octets@.',
732
+    'taille_cache_octets' => 'O tamanho atual do cache é de cerca de @octets@.',
733
+    'taille_cache_vide' => 'O cache está vazio.',
734
+    'taille_repertoire_cache' => 'Tamanho do diretório cache',
735
+    'text_article_propose_publication' => 'Matéria proposta para publicação.',
736
+    'texte_acces_ldap_anonyme_1' => 'Alguns servidores LDAP não aceitam nenhum acesso anônimo. Neste caso, é necessário especificar um identificador de acesso inicial de modo a poder, em seguida, pesquisar as informações no diretório. Na maior parte dos casos, entretanto, os campos a seguir poderão ser deixados em branco.',
737
+    'texte_admin_effacer_01' => 'Este comando apaga <i>todo</i> o conteúdo da base de dados,incluindo <i>todos</i> os acessos dos redatores e administradores. Após executá-lo, você deverá reinstalar o SPIP para recriar uma nova base de dados bem como um acesso inicial de administrador.',
738
+    'texte_adresse_annuaire_1' => '(Se o seu diretório está instalado na mesma máquina que este website, trata-se provavelmente de «localhost».)',
739
+    'texte_ajout_auteur' => 'O autor a seguir foi incluído na matéria:',
740
+    'texte_annuaire_ldap_1' => 'Se você tem acesso a um diretório LDAP, você poderá utilizá-lo para importar automaticamente os usuários para o SPIP.',
741
+    'texte_article_statut' => 'Esta matéria está:',
742
+    'texte_article_virtuel' => 'Matéria virtual',
743
+    'texte_article_virtuel_reference' => '<b>Matéria virtual:</b> matéria referenciada no seu site SPIP, mas redirecionada para um outro URL. Para cancelar o redirecionamento, apague o URL abaixo.',
744
+    'texte_aucun_resultat_auteur' => 'Nenhum resultado para "@cherche_auteur@"',
745
+    'texte_auteur_messagerie' => 'Este site pode monitorar permanentemente a lista de editores conectados, permitindo-lhe trocar mensagens em tempo real. Você pode decidir não aparecer nessa lista (ficando "invisível" para os outros usuários).',
746
+    'texte_auteurs' => 'OS AUTORES',
747
+    'texte_choix_base_1' => 'Escolha a sua base:',
748
+    'texte_choix_base_2' => 'O servidor SQL contém várias bases de dados.',
749
+    'texte_choix_base_3' => '<b>Escolha</b> abaixo a que lhe foi atribuída pelo seu serviço de hospedagem:',
750
+    'texte_choix_table_prefix' => 'Prefixo das tabelas:',
751
+    'texte_compte_element' => '@count@ elemento',
752
+    'texte_compte_elements' => '@count@ elementos',
753
+    'texte_conflit_edition_correction' => 'Por favor, controle abaixo as diferenças entre as duas versões do texto; você pode também copiar as suas modificações e depois recomeçar.',
754
+    'texte_connexion_mysql' => 'Consulte as informações fornecidas pelo seu serviço de hospedagem: nelas, você deverá encontrar o servidor de base de dados fornecido e os seus dados de conexão ao servidor SQL.',
755
+    'texte_contenu_article' => '(Conteúdo da matéria em poucas palavras.)',
756
+    'texte_contenu_articles' => 'De acordo com o layout adotado pelo seu site, você poderá decidir se certos elementos das matérias serão utilizados. Use a listagem abaixo para indicar quais elementos estão disponíveis.',
757
+    'texte_crash_base' => 'Se a sua base de dados se corrompeu, você poderá tentar uma reparação automática.',
758
+    'texte_creer_rubrique' => 'Antes de poder escrever matérias, você precisa criar uma seção.',
759
+    'texte_date_creation_article' => 'DATA DE CRIAÇÃO DA MATÉRIA:',
760
+    'texte_date_creation_objet' => 'Data de criação:', # on ajoute le &quot;:&quot;
761
+    'texte_date_publication_anterieure' => 'Data de redação anterior:',
762
+    'texte_date_publication_anterieure_nonaffichee' => 'Não exibir a data de redação anterior.',
763
+    'texte_date_publication_article' => 'DATA DE PUBLICAÇÃO ONLINE:',
764
+    'texte_date_publication_objet' => 'Data de publicação online:',
765
+    'texte_definir_comme_traduction_rubrique' => 'Esta seção é uma tradução da seção número:',
766
+    'texte_descriptif_rapide' => 'Descrição rápida',
767
+    'texte_effacer_base' => 'Apagar a base de dados do SPIP',
768
+    'texte_effacer_statistiques' => 'Apagar as estatísticas',
769
+    'texte_en_cours_validation' => 'Os conteúdos abaixo estão propostos para publicação.',
770
+    'texte_enrichir_mise_a_jour' => 'Você pode enriquecer a diagramação do seu texto usando «atalhos tipográficos».',
771
+    'texte_fichier_authent' => '<b>O SPIP pode criar os arquivos especiais  <tt>.htpasswd</tt> e <tt>.htpasswd-admin</tt> no diretório @dossier@?</b><p>
772 772
 Estes arquivos podem servir para restringir o acesso aos autores e administradores em outras áreas do seu site (programas externos de estatísticas, por exemplo).</p><p>
773 773
 Se eles não forem úteis, você poderá deixar esta opção com o seu valor padrão (sem criar os arquivos).</p>',
774
-	'texte_informations_personnelles_1' => 'O sistema vai criar agora um acesso personalizado ao site.',
775
-	'texte_informations_personnelles_2' => '(Nota: trata-se de uma reinstalação, se o seu acesso funciona corretamente, você pode',
776
-	'texte_introductif_article' => '(Texto introdutório da matéria.)',
777
-	'texte_jeu_caractere' => 'É aconselhável usar no seu site o alfabeto universal (<tt>utf-8</tt>): ele permite a exibição de textos em todos os idiomas, e não tem problemas de compatibilidade com os navegadores modernos.',
778
-	'texte_jeu_caractere_3' => 'O seu site está configurado atualmente com o conjunto de caracteres:',
779
-	'texte_jeu_caractere_4' => 'Se isso não corresponde à realidade dos seus dados (por ex., em seguimento a um restauro da base de dados), ou se <em>você lançou este site</em> e deseja utilizar um outro conjunto de caracteres, por favor, indique-o aqui:',
780
-	'texte_login_ldap_1' => '(Deixe em branco para acesso anônimo, ou informe o caminho completo, por exemplo «<tt>uid=dupont, ou=users, dc=mon-domaine, dc=com</tt>».)',
781
-	'texte_login_precaution' => 'Atenção! Este é o login com o qual você está conectado agora. Use este formulário com cautela...',
782
-	'texte_messagerie_agenda' => 'As mensagens internas permitem que os redatores se comuniquem entre si, diretamente da área privada do site. Elas estão associadas a uma agenda.',
783
-	'texte_mise_a_niveau_base_1' => 'Você acabou de atualizar os arquivos do SPIP.
774
+    'texte_informations_personnelles_1' => 'O sistema vai criar agora um acesso personalizado ao site.',
775
+    'texte_informations_personnelles_2' => '(Nota: trata-se de uma reinstalação, se o seu acesso funciona corretamente, você pode',
776
+    'texte_introductif_article' => '(Texto introdutório da matéria.)',
777
+    'texte_jeu_caractere' => 'É aconselhável usar no seu site o alfabeto universal (<tt>utf-8</tt>): ele permite a exibição de textos em todos os idiomas, e não tem problemas de compatibilidade com os navegadores modernos.',
778
+    'texte_jeu_caractere_3' => 'O seu site está configurado atualmente com o conjunto de caracteres:',
779
+    'texte_jeu_caractere_4' => 'Se isso não corresponde à realidade dos seus dados (por ex., em seguimento a um restauro da base de dados), ou se <em>você lançou este site</em> e deseja utilizar um outro conjunto de caracteres, por favor, indique-o aqui:',
780
+    'texte_login_ldap_1' => '(Deixe em branco para acesso anônimo, ou informe o caminho completo, por exemplo «<tt>uid=dupont, ou=users, dc=mon-domaine, dc=com</tt>».)',
781
+    'texte_login_precaution' => 'Atenção! Este é o login com o qual você está conectado agora. Use este formulário com cautela...',
782
+    'texte_messagerie_agenda' => 'As mensagens internas permitem que os redatores se comuniquem entre si, diretamente da área privada do site. Elas estão associadas a uma agenda.',
783
+    'texte_mise_a_niveau_base_1' => 'Você acabou de atualizar os arquivos do SPIP.
784 784
 Agora é necessário atualizar a base de dados do site.',
785
-	'texte_modifier_article' => 'Editar a matéria:',
786
-	'texte_multilinguisme' => 'Se você deseja gerar objetos em diversos idiomas, com uma navegação complexa, você pode incluir um menu de seleção de idioma nesses objetos, de acordo com a estrutura do seu site.',
787
-	'texte_multilinguisme_trad' => 'Você pode, igualmente, ativar um sistema de gerenciamento de links entre as diferentes traduções em certos objetos.',
788
-	'texte_non_compresse' => '<i>não compactado</i> (seu servidor não suporta esta funcionalidade)',
789
-	'texte_nouvelle_version_spip_1' => 'Você instalou uma nova versão do SPIP.',
790
-	'texte_nouvelle_version_spip_2' => 'Esta nova versão precisa de uma atualização mais completa do que o normal. Se você é o webmaster do site, por favor, apague o arquivo @connect@ e retome a instalação de forma a incluir os seus parâmetros de conexão à base de dados.<p> (NB.: se você não se lembra dos seus parâmetros de conexão, consulte o arquivo @connect@ antes de apagá-lo...)</p>',
791
-	'texte_operation_echec' => 'Volte à página anterior, escolha uma outra base de dados ou crie uma nova. Verifique as informações fornecidas pelo seu serviço de hospedagem.',
792
-	'texte_plus_trois_car' => 'mais de 3 caracteres',
793
-	'texte_plusieurs_articles' => 'Demasiados autores encontrados para "@cherche_auteur@":',
794
-	'texte_port_annuaire' => '(O valor padrão indicado é geralmente conveniente.)',
795
-	'texte_presente_plugin' => 'Esta página lista os plugins disponíveis para o site. Você pode ativar os plugins necessários marcando a opção correspondente.',
796
-	'texte_proposer_publication' => 'Assim que a sua matéria estiver pronta, você pode propor a sua publicação.',
797
-	'texte_proxy' => 'Em alguns casos (intranet, redes protegidas...), os sites remotos (documentação do SPIP, sites sindicados etc.) só estarão acessíveis através de um <i>proxy HTTP</i>. Nesse caso, informe abaixo o endereço, no formato @[email protected], você pode deixar este campo vazio.',
798
-	'texte_publication_articles_post_dates' => 'Que comportamento o SPIP deve adotar face às matérias em que a data de publicação está pré-datada?',
799
-	'texte_rappel_selection_champs' => '[Não se esqueça de selecionar corretamente este campo.]',
800
-	'texte_recalcul_page' => 'Se você quiser recalcular uma única página, passe para a área pública e clique no botão «atualizar».',
801
-	'texte_recuperer_base' => 'Reparar a base de dados',
802
-	'texte_reference_mais_redirige' => 'matéria referenciada no seu site em  SPIP, mas redirecionada para outro URL.',
803
-	'texte_requetes_echouent' => '<b>Já que certas solicitações SQL falharam sistematicamente e sem razão aparente, é possível que a causa esteja na base de dados em si.</b><p>
785
+    'texte_modifier_article' => 'Editar a matéria:',
786
+    'texte_multilinguisme' => 'Se você deseja gerar objetos em diversos idiomas, com uma navegação complexa, você pode incluir um menu de seleção de idioma nesses objetos, de acordo com a estrutura do seu site.',
787
+    'texte_multilinguisme_trad' => 'Você pode, igualmente, ativar um sistema de gerenciamento de links entre as diferentes traduções em certos objetos.',
788
+    'texte_non_compresse' => '<i>não compactado</i> (seu servidor não suporta esta funcionalidade)',
789
+    'texte_nouvelle_version_spip_1' => 'Você instalou uma nova versão do SPIP.',
790
+    'texte_nouvelle_version_spip_2' => 'Esta nova versão precisa de uma atualização mais completa do que o normal. Se você é o webmaster do site, por favor, apague o arquivo @connect@ e retome a instalação de forma a incluir os seus parâmetros de conexão à base de dados.<p> (NB.: se você não se lembra dos seus parâmetros de conexão, consulte o arquivo @connect@ antes de apagá-lo...)</p>',
791
+    'texte_operation_echec' => 'Volte à página anterior, escolha uma outra base de dados ou crie uma nova. Verifique as informações fornecidas pelo seu serviço de hospedagem.',
792
+    'texte_plus_trois_car' => 'mais de 3 caracteres',
793
+    'texte_plusieurs_articles' => 'Demasiados autores encontrados para "@cherche_auteur@":',
794
+    'texte_port_annuaire' => '(O valor padrão indicado é geralmente conveniente.)',
795
+    'texte_presente_plugin' => 'Esta página lista os plugins disponíveis para o site. Você pode ativar os plugins necessários marcando a opção correspondente.',
796
+    'texte_proposer_publication' => 'Assim que a sua matéria estiver pronta, você pode propor a sua publicação.',
797
+    'texte_proxy' => 'Em alguns casos (intranet, redes protegidas...), os sites remotos (documentação do SPIP, sites sindicados etc.) só estarão acessíveis através de um <i>proxy HTTP</i>. Nesse caso, informe abaixo o endereço, no formato @[email protected], você pode deixar este campo vazio.',
798
+    'texte_publication_articles_post_dates' => 'Que comportamento o SPIP deve adotar face às matérias em que a data de publicação está pré-datada?',
799
+    'texte_rappel_selection_champs' => '[Não se esqueça de selecionar corretamente este campo.]',
800
+    'texte_recalcul_page' => 'Se você quiser recalcular uma única página, passe para a área pública e clique no botão «atualizar».',
801
+    'texte_recuperer_base' => 'Reparar a base de dados',
802
+    'texte_reference_mais_redirige' => 'matéria referenciada no seu site em  SPIP, mas redirecionada para outro URL.',
803
+    'texte_requetes_echouent' => '<b>Já que certas solicitações SQL falharam sistematicamente e sem razão aparente, é possível que a causa esteja na base de dados em si.</b><p>
804 804
 O seu servidor SQL dispõe de uma funcionalidade de reparação das suas tabelas quando elas são danificadas por acidente. Você poderá tentar esta reparação; em caso de falha, conserve uma cópia da mensagem de erro, que poderá conter indícios do que não está funcionando...</p><p>
805 805
 Se o problema persistir, contate o seu serviço de hospedagem.</p>',
806
-	'texte_selection_langue_principale' => 'Você pode escolher abaixo o «idioma principal» do site. esta escolha não o obriga - felizmente! - a escrever as suas matérias no idioma selecionado, mas permite determinar:
806
+    'texte_selection_langue_principale' => 'Você pode escolher abaixo o «idioma principal» do site. esta escolha não o obriga - felizmente! - a escrever as suas matérias no idioma selecionado, mas permite determinar:
807 807
  <ul><li>o formato padrão das datas no site público;</li>
808 808
  <li>a natureza do motor tipográfico que o SPIP deverá usar para a composição dos textos;</li>
809 809
  <li>o idioma usado nos formulários do site público;</li>
810 810
  <li>o idioma padrão exibido na área privada.</li></ul>',
811
-	'texte_sous_titre' => 'Subtítulo',
812
-	'texte_statistiques_visites' => '(barras escuras:  domingo / curva escura: evolução da média)',
813
-	'texte_statut_attente_validation' => 'aguardando validação',
814
-	'texte_statut_publies' => 'publicadas online',
815
-	'texte_statut_refuses' => 'recusadas',
816
-	'texte_suppression_fichiers' => 'Use este comando para excluir todos os arquivos que constam do cache do SPIP. Isto permite, por exemplo, forçar a reconstrução de todas as páginas, caso você tenha feito alterações importantes no layout ou na estrutura do site.',
817
-	'texte_sur_titre' => 'Sobretítulo',
818
-	'texte_table_ok' => ': esta tabela está OK.',
819
-	'texte_tentative_recuperation' => 'Tentativa de reparação',
820
-	'texte_tenter_reparation' => 'Tentar uma reparação da base de dados',
821
-	'texte_test_proxy' => 'Para testar este proxy, informe aqui o endereço de um website que você deseje testar.',
822
-	'texte_titre_02' => 'Título:',
823
-	'texte_titre_obligatoire' => '<b>Título</b> [obrigatório]',
824
-	'texte_travail_article' => '@nom_auteur_modif@ trabalhou nesta matéria há @date_diff@ minutos',
825
-	'texte_travail_collaboratif' => 'Se é frequente acontecer de mais de um redator trabalhar em uma mesma matéria, o sistema pode exibir as matérias recentemente "abertas", de modo a evitar modificações concorrentes. Esta opção está desativada por padrão, para evitar a exibição de mensagens de aviso desnecessárias.',
826
-	'texte_vide' => 'vazia',
827
-	'texte_vider_cache' => 'Esvaziar o cache',
828
-	'titre_admin_tech' => 'Manutenção técnica',
829
-	'titre_admin_vider' => 'Manutenção técnica',
830
-	'titre_ajouter_un_auteur' => 'Incluir um autor',
831
-	'titre_ajouter_un_mot' => 'Incluir uma palavra-chave',
832
-	'titre_cadre_afficher_article' => 'Exibir as matérias',
833
-	'titre_cadre_afficher_traductions' => 'Exibir o status das traduções para os idiomas a seguir:',
834
-	'titre_cadre_ajouter_auteur' => 'INCLUIR UM AUTOR:',
835
-	'titre_cadre_interieur_rubrique' => 'Na seção',
836
-	'titre_cadre_numero_auteur' => 'AUTOR NÚMERO',
837
-	'titre_cadre_numero_objet' => '@objet@ NÚMERO:',
838
-	'titre_cadre_signature_obligatoire' => '<b>Assinatura</b> [obrigatório]<br />',
839
-	'titre_config_contenu_notifications' => 'Notificações',
840
-	'titre_config_contenu_prive' => 'Na área privada',
841
-	'titre_config_contenu_public' => 'No site público',
842
-	'titre_config_fonctions' => 'Configuração do site',
843
-	'titre_config_langage' => 'Configurar o idioma',
844
-	'titre_configuration' => 'Configuração do site',
845
-	'titre_configurer_preferences' => 'Configurar as suas preferências',
846
-	'titre_configurer_preferences_menus' => 'Configurar as suas preferências de menus',
847
-	'titre_conflit_edition' => 'Conflito durante a edição',
848
-	'titre_connexion_ldap' => 'Opções: <b>Sua conexão LDAP</b>',
849
-	'titre_groupe_mots' => 'GRUPO DE PALAVRAS-CHAVE:',
850
-	'titre_identite_site' => 'Identidade do site',
851
-	'titre_langue_article' => 'Idioma da matéria',
852
-	'titre_langue_rubrique' => 'Idioma da seção',
853
-	'titre_langue_trad_article' => 'IDIOMA E TRADUÇÕES DA MATÉRIA',
854
-	'titre_les_articles' => 'AS MATÉRIAS',
855
-	'titre_messagerie_agenda' => 'Mensagens internas e agenda',
856
-	'titre_naviguer_dans_le_site' => 'Navegar no site...',
857
-	'titre_nouvelle_rubrique' => 'Nova seção',
858
-	'titre_numero_rubrique' => 'SEÇÃO NÚMERO:',
859
-	'titre_page_articles_edit' => 'Editar: @titre@',
860
-	'titre_page_articles_page' => 'As matérias',
861
-	'titre_page_articles_tous' => 'Todo o site',
862
-	'titre_page_calendrier' => 'Calendário @nom_mois@ @annee@',
863
-	'titre_page_config_contenu' => 'Configuração do site',
864
-	'titre_page_delete_all' => 'supressão total e irreversível',
865
-	'titre_page_recherche' => 'Resultados da busca por @recherche@',
866
-	'titre_page_statistiques_referers' => 'Estatísticas (links de entrada)',
867
-	'titre_page_upgrade' => 'Atualização do SPIP',
868
-	'titre_preference_menus_favoris' => 'Menus favoritos',
869
-	'titre_publication_articles_post_dates' => 'Publicação de matérias pós-datadas',
870
-	'titre_reparation' => 'Reparação',
871
-	'titre_suivi_petition' => 'Acompanhamento das petições',
872
-	'tls_ldap' => 'Transport Layer Security:',
873
-	'trad_article_traduction' => 'Todas as versões desta matéria:',
874
-	'trad_delier' => 'Desvincular destas traduções',
875
-	'trad_lier' => 'Esta matéria é uma tradução da matéria número:',
876
-	'trad_new' => 'Escrever uma nova tradução',
811
+    'texte_sous_titre' => 'Subtítulo',
812
+    'texte_statistiques_visites' => '(barras escuras:  domingo / curva escura: evolução da média)',
813
+    'texte_statut_attente_validation' => 'aguardando validação',
814
+    'texte_statut_publies' => 'publicadas online',
815
+    'texte_statut_refuses' => 'recusadas',
816
+    'texte_suppression_fichiers' => 'Use este comando para excluir todos os arquivos que constam do cache do SPIP. Isto permite, por exemplo, forçar a reconstrução de todas as páginas, caso você tenha feito alterações importantes no layout ou na estrutura do site.',
817
+    'texte_sur_titre' => 'Sobretítulo',
818
+    'texte_table_ok' => ': esta tabela está OK.',
819
+    'texte_tentative_recuperation' => 'Tentativa de reparação',
820
+    'texte_tenter_reparation' => 'Tentar uma reparação da base de dados',
821
+    'texte_test_proxy' => 'Para testar este proxy, informe aqui o endereço de um website que você deseje testar.',
822
+    'texte_titre_02' => 'Título:',
823
+    'texte_titre_obligatoire' => '<b>Título</b> [obrigatório]',
824
+    'texte_travail_article' => '@nom_auteur_modif@ trabalhou nesta matéria há @date_diff@ minutos',
825
+    'texte_travail_collaboratif' => 'Se é frequente acontecer de mais de um redator trabalhar em uma mesma matéria, o sistema pode exibir as matérias recentemente "abertas", de modo a evitar modificações concorrentes. Esta opção está desativada por padrão, para evitar a exibição de mensagens de aviso desnecessárias.',
826
+    'texte_vide' => 'vazia',
827
+    'texte_vider_cache' => 'Esvaziar o cache',
828
+    'titre_admin_tech' => 'Manutenção técnica',
829
+    'titre_admin_vider' => 'Manutenção técnica',
830
+    'titre_ajouter_un_auteur' => 'Incluir um autor',
831
+    'titre_ajouter_un_mot' => 'Incluir uma palavra-chave',
832
+    'titre_cadre_afficher_article' => 'Exibir as matérias',
833
+    'titre_cadre_afficher_traductions' => 'Exibir o status das traduções para os idiomas a seguir:',
834
+    'titre_cadre_ajouter_auteur' => 'INCLUIR UM AUTOR:',
835
+    'titre_cadre_interieur_rubrique' => 'Na seção',
836
+    'titre_cadre_numero_auteur' => 'AUTOR NÚMERO',
837
+    'titre_cadre_numero_objet' => '@objet@ NÚMERO:',
838
+    'titre_cadre_signature_obligatoire' => '<b>Assinatura</b> [obrigatório]<br />',
839
+    'titre_config_contenu_notifications' => 'Notificações',
840
+    'titre_config_contenu_prive' => 'Na área privada',
841
+    'titre_config_contenu_public' => 'No site público',
842
+    'titre_config_fonctions' => 'Configuração do site',
843
+    'titre_config_langage' => 'Configurar o idioma',
844
+    'titre_configuration' => 'Configuração do site',
845
+    'titre_configurer_preferences' => 'Configurar as suas preferências',
846
+    'titre_configurer_preferences_menus' => 'Configurar as suas preferências de menus',
847
+    'titre_conflit_edition' => 'Conflito durante a edição',
848
+    'titre_connexion_ldap' => 'Opções: <b>Sua conexão LDAP</b>',
849
+    'titre_groupe_mots' => 'GRUPO DE PALAVRAS-CHAVE:',
850
+    'titre_identite_site' => 'Identidade do site',
851
+    'titre_langue_article' => 'Idioma da matéria',
852
+    'titre_langue_rubrique' => 'Idioma da seção',
853
+    'titre_langue_trad_article' => 'IDIOMA E TRADUÇÕES DA MATÉRIA',
854
+    'titre_les_articles' => 'AS MATÉRIAS',
855
+    'titre_messagerie_agenda' => 'Mensagens internas e agenda',
856
+    'titre_naviguer_dans_le_site' => 'Navegar no site...',
857
+    'titre_nouvelle_rubrique' => 'Nova seção',
858
+    'titre_numero_rubrique' => 'SEÇÃO NÚMERO:',
859
+    'titre_page_articles_edit' => 'Editar: @titre@',
860
+    'titre_page_articles_page' => 'As matérias',
861
+    'titre_page_articles_tous' => 'Todo o site',
862
+    'titre_page_calendrier' => 'Calendário @nom_mois@ @annee@',
863
+    'titre_page_config_contenu' => 'Configuração do site',
864
+    'titre_page_delete_all' => 'supressão total e irreversível',
865
+    'titre_page_recherche' => 'Resultados da busca por @recherche@',
866
+    'titre_page_statistiques_referers' => 'Estatísticas (links de entrada)',
867
+    'titre_page_upgrade' => 'Atualização do SPIP',
868
+    'titre_preference_menus_favoris' => 'Menus favoritos',
869
+    'titre_publication_articles_post_dates' => 'Publicação de matérias pós-datadas',
870
+    'titre_reparation' => 'Reparação',
871
+    'titre_suivi_petition' => 'Acompanhamento das petições',
872
+    'tls_ldap' => 'Transport Layer Security:',
873
+    'trad_article_traduction' => 'Todas as versões desta matéria:',
874
+    'trad_delier' => 'Desvincular destas traduções',
875
+    'trad_lier' => 'Esta matéria é uma tradução da matéria número:',
876
+    'trad_new' => 'Escrever uma nova tradução',
877 877
 
878
-	// U
879
-	'utf8_convert_erreur_orig' => 'Erro: o conjunto de caracteres @charset@ não é suportado.',
878
+    // U
879
+    'utf8_convert_erreur_orig' => 'Erro: o conjunto de caracteres @charset@ não é suportado.',
880 880
 
881
-	// V
882
-	'version' => 'Versão:',
881
+    // V
882
+    'version' => 'Versão:',
883 883
 ];
Please login to merge, or discard this patch.