4 |
david |
1 |
<?php
|
|
|
2 |
|
|
|
3 |
/***************************************************************************\
|
|
|
4 |
* SPIP, Systeme de publication pour l'internet *
|
|
|
5 |
* *
|
|
|
6 |
* Copyright (c) 2001-2005 *
|
|
|
7 |
* Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
|
|
|
8 |
* *
|
|
|
9 |
* Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
|
|
|
10 |
* Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
|
|
|
11 |
\***************************************************************************/
|
|
|
12 |
|
|
|
13 |
|
|
|
14 |
// Ce fichier ne sera execute qu'une fois
|
|
|
15 |
if (defined("_ECRIRE_INC_ORTHO")) return;
|
|
|
16 |
define("_ECRIRE_INC_ORTHO", "1");
|
|
|
17 |
|
|
|
18 |
|
|
|
19 |
// Mettre a jour la liste locale des miroirs
|
|
|
20 |
function maj_miroirs_ortho() {
|
|
|
21 |
$liste = explode(" ", lire_meta("liste_miroirs_ortho"));
|
|
|
22 |
$miroirs_old = array();
|
|
|
23 |
foreach ($liste as $index) {
|
|
|
24 |
list($url) = explode(" ", lire_meta("miroir_ortho_$index"));
|
|
|
25 |
$miroirs_old[$url] = $index;
|
|
|
26 |
}
|
|
|
27 |
|
|
|
28 |
// TODO: recuperer la liste dynamiquement depuis ortho.spip.net
|
|
|
29 |
$urls = array(
|
|
|
30 |
'http://tony.ortho.spip.net/ortho_serveur.php',
|
|
|
31 |
'http://spip-ortho.linagora.org:18080/ortho_serveur.php',
|
|
|
32 |
'http://ortho.spip.net/ortho_serveur.php'
|
|
|
33 |
);
|
|
|
34 |
$liste = array();
|
|
|
35 |
$miroirs_new = array();
|
|
|
36 |
$index = 1;
|
|
|
37 |
foreach ($urls as $url) {
|
|
|
38 |
if ($index_old = $miroirs_old[$url]) {
|
|
|
39 |
$s = lire_meta("miroir_ortho_$index_old");
|
|
|
40 |
}
|
|
|
41 |
else {
|
|
|
42 |
$s = $url." ".time();
|
|
|
43 |
}
|
|
|
44 |
$miroirs_new[$index] = $s;
|
|
|
45 |
$liste[] = $index++;
|
|
|
46 |
}
|
|
|
47 |
foreach ($miroirs_old as $index) {
|
|
|
48 |
effacer_meta("miroir_ortho_$index");
|
|
|
49 |
}
|
|
|
50 |
foreach ($miroirs_new as $index => $s) {
|
|
|
51 |
ecrire_meta("miroir_ortho_$index", $s);
|
|
|
52 |
}
|
|
|
53 |
ecrire_meta("liste_miroirs_ortho", join(" ", $liste));
|
|
|
54 |
}
|
|
|
55 |
|
|
|
56 |
// Lire la liste des miroirs et les langues associees
|
|
|
57 |
function lire_miroirs_ortho() {
|
|
|
58 |
global $miroirs_ortho, $index_miroirs_ortho, $duree_cache_miroirs_ortho;
|
|
|
59 |
|
|
|
60 |
$miroirs_ortho = array();
|
|
|
61 |
$index_miroirs_ortho = array();
|
|
|
62 |
|
|
|
63 |
$t = time();
|
|
|
64 |
$maj = lire_meta("maj_miroirs_ortho");
|
|
|
65 |
if ($maj < $t - $duree_cache_miroirs_ortho) {
|
|
|
66 |
maj_miroirs_ortho();
|
|
|
67 |
ecrire_meta("maj_miroirs_ortho", $t);
|
|
|
68 |
lire_metas();
|
|
|
69 |
}
|
|
|
70 |
|
|
|
71 |
$liste = explode(" ", lire_meta("liste_miroirs_ortho"));
|
|
|
72 |
foreach ($liste as $index) {
|
|
|
73 |
$s = explode(" ", lire_meta("miroir_ortho_$index"));
|
|
|
74 |
$url = $s[0];
|
|
|
75 |
$maj = $s[1];
|
|
|
76 |
$langs = explode(",", $s[2]);
|
|
|
77 |
// Reinitialiser periodiquement la liste des langues non-supportees
|
|
|
78 |
if ($maj < $t - $duree_cache_miroirs_ortho) {
|
|
|
79 |
foreach ($langs as $key => $lang) {
|
|
|
80 |
if (substr($lang, 0, 1) == '!') unset($langs[$key]);
|
|
|
81 |
}
|
|
|
82 |
$s[1] = $t;
|
|
|
83 |
$s[2] = join(",", $langs);
|
|
|
84 |
ecrire_meta("miroir_ortho_$index", join(" ", $s));
|
|
|
85 |
}
|
|
|
86 |
$index_miroirs_ortho[$url] = $index;
|
|
|
87 |
$miroirs_ortho[$url] = array();
|
|
|
88 |
foreach ($langs as $lang) {
|
|
|
89 |
if ($lang) $miroirs_ortho[$url][$lang] = $lang;
|
|
|
90 |
}
|
|
|
91 |
}
|
|
|
92 |
lire_metas();
|
|
|
93 |
mt_srand(time());
|
|
|
94 |
}
|
|
|
95 |
|
|
|
96 |
// Sauvegarder les infos de langues pour le miroir
|
|
|
97 |
function ecrire_miroir_ortho($url, $langs) {
|
|
|
98 |
global $index_miroirs_ortho;
|
|
|
99 |
|
|
|
100 |
$index = $index_miroirs_ortho[$url];
|
|
|
101 |
$s = explode(" ", lire_meta("miroir_ortho_$index"));
|
|
|
102 |
$s[2] = join(",", $langs);
|
|
|
103 |
ecrire_meta("miroir_ortho_$index", join(" ", $s));
|
|
|
104 |
}
|
|
|
105 |
|
|
|
106 |
function ajouter_langue_miroir($url, $lang) {
|
|
|
107 |
global $miroirs_ortho;
|
|
|
108 |
$langs = $miroirs_ortho[$url];
|
|
|
109 |
$langs[$lang] = $lang;
|
|
|
110 |
unset($langs["!$lang"]);
|
|
|
111 |
ecrire_miroir_ortho($url, $langs);
|
|
|
112 |
}
|
|
|
113 |
|
|
|
114 |
function enlever_langue_miroir($url, $lang) {
|
|
|
115 |
global $miroirs_ortho;
|
|
|
116 |
$langs = $miroirs_ortho[$url];
|
|
|
117 |
unset($langs[$lang]);
|
|
|
118 |
$langs["!$lang"] = "!$lang";
|
|
|
119 |
ecrire_miroir_ortho($url, $langs);
|
|
|
120 |
}
|
|
|
121 |
|
|
|
122 |
function reset_miroir($url) {
|
|
|
123 |
global $miroirs_ortho;
|
|
|
124 |
ecrire_miroir_ortho($url, array());
|
|
|
125 |
}
|
|
|
126 |
|
|
|
127 |
//
|
|
|
128 |
// Renvoie la liste des miroirs utilisables pour une langue donnee
|
|
|
129 |
//
|
|
|
130 |
function chercher_miroirs_ortho($lang) {
|
|
|
131 |
global $miroirs_ortho;
|
|
|
132 |
|
|
|
133 |
$result = array();
|
|
|
134 |
$chercher = true;
|
|
|
135 |
foreach ($miroirs_ortho as $url => $langs) {
|
|
|
136 |
if ($langs[$lang]) {
|
|
|
137 |
$result[] = $url;
|
|
|
138 |
}
|
|
|
139 |
else if ($chercher && !$langs["!$lang"]) {
|
|
|
140 |
//echo "test $lang $url<br />";
|
|
|
141 |
if (verifier_langue_miroir($url, $lang)) $result[] = $url;
|
|
|
142 |
// Ne recuperer la langue d'un miroir qu'une seule fois par requete
|
|
|
143 |
if ($result) $chercher = false;
|
|
|
144 |
}
|
|
|
145 |
}
|
|
|
146 |
return $result;
|
|
|
147 |
}
|
|
|
148 |
|
|
|
149 |
function choisir_miroirs_ortho($lang) {
|
|
|
150 |
$liste = chercher_miroirs_ortho($lang);
|
|
|
151 |
if (!count($liste)) return false;
|
|
|
152 |
foreach ($liste as $url) {
|
|
|
153 |
$miroirs[md5(mt_rand().$url.rand())] = $url;
|
|
|
154 |
}
|
|
|
155 |
ksort($miroirs);
|
|
|
156 |
return $miroirs;
|
|
|
157 |
}
|
|
|
158 |
|
|
|
159 |
//
|
|
|
160 |
// Envoyer une requete a un serveur d'orthographe
|
|
|
161 |
//
|
|
|
162 |
function post_ortho($url, $texte, $lang) {
|
|
|
163 |
include_ecrire('inc_sites.php3');
|
|
|
164 |
|
|
|
165 |
list($f, $fopen) = init_http('POST', $url);
|
|
|
166 |
if (!$f OR $fopen) {
|
|
|
167 |
spip_log("Echec connexion $url");
|
|
|
168 |
return false;
|
|
|
169 |
}
|
|
|
170 |
|
|
|
171 |
// Si le texte est petit, l'overhead du multipart est dispendieux
|
|
|
172 |
if (!$GLOBALS['flag_gz'] || strlen($texte) < 200) {
|
|
|
173 |
$gz = false;
|
|
|
174 |
$body = "op=spell&lang=".urlencode($lang)."&texte=".urlencode($texte);
|
|
|
175 |
fputs($f, "Content-Type: application/x-www-form-urlencoded\r\n");
|
|
|
176 |
}
|
|
|
177 |
// Sinon, on passe en multipart pour compresser la chaine a corriger
|
|
|
178 |
else {
|
|
|
179 |
// Il faut eliminer les caracteres 0 sinon PHP ne lit pas la suite du parametre
|
|
|
180 |
// passe en multipart/form-data (gros hack bien sale)
|
|
|
181 |
$texte_gz = gzcompress($texte);
|
|
|
182 |
for ($echap = 255; $echap > 0; $echap--) {
|
|
|
183 |
$str_echap = chr($echap ^ 1).chr($echap).chr($echap).chr($echap ^ 2);
|
|
|
184 |
if (!is_int(strpos($texte_gz, $str_echap))) break;
|
|
|
185 |
}
|
|
|
186 |
$texte_gz = str_replace("\x00", $str_echap, $texte_gz);
|
|
|
187 |
$gz = true;
|
|
|
188 |
$vars = array('op' => 'spell', 'lang' => $lang, 'texte' => $texte_gz, 'gz' => 1, 'nul_echap' => $str_echap);
|
|
|
189 |
$boundary = substr(md5(rand().'ortho'), 0, 8);
|
|
|
190 |
$body = '';
|
|
|
191 |
foreach ($vars as $key => $val) {
|
|
|
192 |
$body .= "\r\n--$boundary\r\n";
|
|
|
193 |
$body .= "Content-Disposition: form-data; name=\"$key\"\r\n";
|
|
|
194 |
$body .= "\r\n";
|
|
|
195 |
$body .= $val;
|
|
|
196 |
}
|
|
|
197 |
$body .= "\r\n--$boundary\r\n";
|
|
|
198 |
fputs($f, "Content-Type: multipart/form-data; boundary=$boundary\r\n");
|
|
|
199 |
}
|
|
|
200 |
|
|
|
201 |
// On envoie le contenu
|
|
|
202 |
fputs($f, "Content-Length: ".strlen($body)."\r\n");
|
|
|
203 |
fputs($f, "\r\n"); // Fin des entetes
|
|
|
204 |
fputs($f, $body);
|
|
|
205 |
|
|
|
206 |
// Lire les en-tetes HTTP de la reponse et decoder le Content-Length
|
|
|
207 |
$length = 0;
|
|
|
208 |
$s = fgets($f, 1000);
|
|
|
209 |
$statut = 0;
|
|
|
210 |
if (preg_match(',^HTTP/\d+\.\d+ (\d+) ,', $s, $r))
|
|
|
211 |
$statut = intval($r[1]);
|
|
|
212 |
if ($statut != 200) {
|
|
|
213 |
fclose($f);
|
|
|
214 |
return false;
|
|
|
215 |
}
|
|
|
216 |
while ($s = trim(fgets($f, 1000))) {
|
|
|
217 |
if (preg_match(',Content-Length:(.*),i', $s, $r))
|
|
|
218 |
$length = intval($r[1]);
|
|
|
219 |
}
|
|
|
220 |
$r = "";
|
|
|
221 |
|
|
|
222 |
// Lire le corps de la reponse HTTP
|
|
|
223 |
if ($length) {
|
|
|
224 |
while (($l = strlen($r)) < $length) $r .= fread($f, $length - $l);
|
|
|
225 |
}
|
|
|
226 |
else while (!feof($f) AND $r .= fread($f, 1024));
|
|
|
227 |
|
|
|
228 |
fclose($f);
|
|
|
229 |
if ($gz) $r = gzuncompress($r);
|
|
|
230 |
return $r;
|
|
|
231 |
}
|
|
|
232 |
|
|
|
233 |
//
|
|
|
234 |
// Verifier si un serveur gere une langue donnee
|
|
|
235 |
//
|
|
|
236 |
function verifier_langue_miroir($url, $lang) {
|
|
|
237 |
// Envoyer une requete bidon
|
|
|
238 |
$result = post_ortho($url, " ", $lang);
|
|
|
239 |
if (!preg_match(',<ortho>.*</ortho>,s', $result)) {
|
|
|
240 |
reset_miroir($url);
|
|
|
241 |
return false;
|
|
|
242 |
}
|
|
|
243 |
if (!preg_match(',<erreur>.*<code>E_LANG_ABSENT</code>.*</erreur>,s', $result)) {
|
|
|
244 |
ajouter_langue_miroir($url, $lang);
|
|
|
245 |
return true;
|
|
|
246 |
}
|
|
|
247 |
enlever_langue_miroir($url, $lang);
|
|
|
248 |
return false;
|
|
|
249 |
}
|
|
|
250 |
|
|
|
251 |
|
|
|
252 |
//
|
|
|
253 |
// Gestion du dictionnaire local
|
|
|
254 |
//
|
|
|
255 |
function suggerer_dico_ortho(&$mots, $lang) {
|
|
|
256 |
$lang = addslashes($lang);
|
|
|
257 |
$query = "SELECT mot FROM spip_ortho_dico WHERE lang='$lang' ".
|
|
|
258 |
"AND mot IN ('".join("', '", array_map('addslashes', $mots))."')";
|
|
|
259 |
$result = spip_query($query);
|
|
|
260 |
|
|
|
261 |
$mots = array_flip($mots);
|
|
|
262 |
$bons = array();
|
|
|
263 |
if (isset($mots[''])) unset($mots['']);
|
|
|
264 |
while ($row = spip_fetch_array($result)) {
|
|
|
265 |
$mot = $row['mot'];
|
|
|
266 |
if (isset($mots[$mot])) {
|
|
|
267 |
unset($mots[$mot]);
|
|
|
268 |
$bons[] = $mot;
|
|
|
269 |
}
|
|
|
270 |
}
|
|
|
271 |
|
|
|
272 |
if (count($mots)) $mots = array_flip($mots);
|
|
|
273 |
else $mots = array();
|
|
|
274 |
return $bons;
|
|
|
275 |
}
|
|
|
276 |
|
|
|
277 |
function ajouter_dico_ortho($mot, $lang) {
|
|
|
278 |
global $connect_id_auteur;
|
|
|
279 |
|
|
|
280 |
$lang = addslashes($lang);
|
|
|
281 |
$mot = addslashes($mot);
|
|
|
282 |
$id_auteur = intval($connect_id_auteur);
|
|
|
283 |
$query = "INSERT IGNORE INTO spip_ortho_dico (lang, mot, id_auteur) ".
|
|
|
284 |
"VALUES ('$lang', '$mot', '$id_auteur')";
|
|
|
285 |
spip_query($query);
|
|
|
286 |
}
|
|
|
287 |
|
|
|
288 |
function supprimer_dico_ortho($mot, $lang) {
|
|
|
289 |
$lang = addslashes($lang);
|
|
|
290 |
$mot = addslashes($mot);
|
|
|
291 |
$query = "DELETE FROM spip_ortho_dico WHERE lang='$lang' AND mot='$mot'";
|
|
|
292 |
spip_query($query);
|
|
|
293 |
}
|
|
|
294 |
|
|
|
295 |
function gerer_dico_ortho($lang) {
|
|
|
296 |
global $ajout_ortho, $supp_ortho;
|
|
|
297 |
if ($mot = strval($ajout_ortho)) {
|
|
|
298 |
ajouter_dico_ortho($mot, $lang);
|
|
|
299 |
}
|
|
|
300 |
if ($mot = strval($supp_ortho)) {
|
|
|
301 |
supprimer_dico_ortho($mot, $lang);
|
|
|
302 |
}
|
|
|
303 |
}
|
|
|
304 |
|
|
|
305 |
|
|
|
306 |
//
|
|
|
307 |
// Gestion du cache de corrections
|
|
|
308 |
//
|
|
|
309 |
function suggerer_cache_ortho(&$mots, $lang) {
|
|
|
310 |
global $duree_cache_ortho;
|
|
|
311 |
|
|
|
312 |
$lang = addslashes($lang);
|
|
|
313 |
$query = "SELECT mot, ok, suggest FROM spip_ortho_cache WHERE lang='$lang' ".
|
|
|
314 |
"AND mot IN ('".join("', '", array_map('addslashes', $mots))."') ".
|
|
|
315 |
"AND maj > FROM_UNIXTIME(".(time() - $duree_cache_ortho).")";
|
|
|
316 |
$result = spip_query($query);
|
|
|
317 |
|
|
|
318 |
$mots = array_flip($mots);
|
|
|
319 |
$suggest = array();
|
|
|
320 |
if (isset($mots[''])) unset($mots['']);
|
|
|
321 |
while ($row = spip_fetch_array($result)) {
|
|
|
322 |
$mot = $row['mot'];
|
|
|
323 |
if (isset($mots[$mot])) {
|
|
|
324 |
unset($mots[$mot]);
|
|
|
325 |
if (!$row['ok']) {
|
|
|
326 |
if (strlen($row['suggest']))
|
|
|
327 |
$suggest[$mot] = explode(",", $row['suggest']);
|
|
|
328 |
else
|
|
|
329 |
$suggest[$mot] = array();
|
|
|
330 |
}
|
|
|
331 |
}
|
|
|
332 |
}
|
|
|
333 |
if (count($mots)) $mots = array_flip($mots);
|
|
|
334 |
else $mots = array();
|
|
|
335 |
return $suggest;
|
|
|
336 |
}
|
|
|
337 |
|
|
|
338 |
function ajouter_cache_ortho($tous, $mauvais, $lang) {
|
|
|
339 |
global $duree_cache_ortho;
|
|
|
340 |
|
|
|
341 |
$values = array();
|
|
|
342 |
$lang = addslashes($lang);
|
|
|
343 |
if (count($mauvais)) {
|
|
|
344 |
foreach ($mauvais as $mot => $suggest) {
|
|
|
345 |
$values[] = "('$lang', '".addslashes($mot)."', 0, '".addslashes(join(",", $suggest))."')";
|
|
|
346 |
}
|
|
|
347 |
}
|
|
|
348 |
if (count($tous)) {
|
|
|
349 |
foreach ($tous as $mot) {
|
|
|
350 |
if (!isset($mauvais[$mot]))
|
|
|
351 |
$values[] = "('$lang', '".addslashes($mot)."', 1, '')";
|
|
|
352 |
}
|
|
|
353 |
}
|
|
|
354 |
if (count($values)) {
|
|
|
355 |
$query = "DELETE FROM spip_ortho_cache ".
|
|
|
356 |
"WHERE maj < FROM_UNIXTIME(".(time() - $duree_cache_ortho).")";
|
|
|
357 |
spip_query($query);
|
|
|
358 |
$query = "INSERT IGNORE INTO spip_ortho_cache (lang, mot, ok, suggest) ".
|
|
|
359 |
"VALUES ".join(", ", $values);
|
|
|
360 |
spip_query($query);
|
|
|
361 |
}
|
|
|
362 |
}
|
|
|
363 |
|
|
|
364 |
|
|
|
365 |
//
|
|
|
366 |
// Cette fonction doit etre appelee pour reecrire le texte en utf-8 "propre"
|
|
|
367 |
//
|
|
|
368 |
function preparer_ortho($texte, $lang) {
|
|
|
369 |
include_spip("charsets.php");
|
|
|
370 |
|
|
|
371 |
$charset = lire_meta('charset');
|
|
|
372 |
|
|
|
373 |
if ($charset == 'utf-8')
|
|
|
374 |
return unicode_to_utf_8(html2unicode($texte));
|
|
|
375 |
else
|
|
|
376 |
return unicode_to_utf_8(html2unicode(charset2unicode($texte, $charset, true)));
|
|
|
377 |
}
|
|
|
378 |
|
|
|
379 |
function afficher_ortho($texte) {
|
|
|
380 |
$charset = lire_meta('charset');
|
|
|
381 |
if ($charset == 'utf-8') return $texte;
|
|
|
382 |
|
|
|
383 |
if (!is_array($texte)) return charset2unicode($texte, 'utf-8');
|
|
|
384 |
foreach ($texte as $key => $val) {
|
|
|
385 |
$texte[$key] = afficher_ortho($val);
|
|
|
386 |
}
|
|
|
387 |
return $texte;
|
|
|
388 |
}
|
|
|
389 |
|
|
|
390 |
//
|
|
|
391 |
// Cette fonction envoie le texte prepare a un serveur d'orthographe
|
|
|
392 |
// et retourne un tableau de mots mal orthographies associes chacun a un tableau de mots suggeres
|
|
|
393 |
//
|
|
|
394 |
function corriger_ortho($texte, $lang, $charset = 'AUTO') {
|
|
|
395 |
include_spip("charsets.php");
|
|
|
396 |
include_spip("index.php");
|
|
|
397 |
include_spip("filtres.php");
|
|
|
398 |
|
|
|
399 |
$texte = preg_replace(',<code>.*?</code>,is', '', $texte);
|
|
|
400 |
$texte = preg_replace(',<cadre>.*?</cadre>,is', '', $texte);
|
|
|
401 |
$texte = preg_replace(',\[([^][]*)->([^][]*)\],is', '\\1', $texte);
|
|
|
402 |
$texte = supprimer_tags($texte);
|
|
|
403 |
|
|
|
404 |
$texte = " ".$texte." ";
|
|
|
405 |
|
|
|
406 |
// Virer les caracteres non-alphanumeriques
|
|
|
407 |
if (test_pcre_unicode()) {
|
|
|
408 |
$texte = preg_replace(',[^-\''.pcre_lettres_unicode().']+,us', ' ', $texte);
|
|
|
409 |
}
|
|
|
410 |
else {
|
|
|
411 |
// Ici bidouilles si PCRE en mode UTF-8 ne fonctionne pas correctement ...
|
|
|
412 |
// Caracteres non-alphanumeriques de la plage latin-1 + saloperies non-conformes
|
|
|
413 |
$texte = preg_replace(',\xC2[\x80-\xBF],', ' ', $texte);
|
|
|
414 |
// Poncutation etendue (unicode)
|
|
|
415 |
$texte = preg_replace(",".plage_punct_unicode().",", ' ', $texte);
|
|
|
416 |
// Caracteres ASCII non-alphanumeriques
|
|
|
417 |
$texte = preg_replace(",[^-a-zA-Z0-9\x80-\xFF']+,", ' ', $texte);
|
|
|
418 |
}
|
|
|
419 |
$texte = preg_replace(', [-\']+,', ' ', $texte); // tirets de typo
|
|
|
420 |
$texte = preg_replace(',\' ,', ' ', $texte); // apostrophes utilisees comme guillemets
|
|
|
421 |
|
|
|
422 |
//echo htmlspecialchars($texte)."<br>";
|
|
|
423 |
|
|
|
424 |
// Virer les mots contenant au moins un chiffre
|
|
|
425 |
$texte = preg_replace(', ([^ ]*\d[^ ]* )+,', ' ', $texte);
|
|
|
426 |
|
|
|
427 |
// Melanger les mots
|
|
|
428 |
$mots = preg_split(', +,', $texte);
|
|
|
429 |
sort($mots);
|
|
|
430 |
$mots = array_unique($mots);
|
|
|
431 |
|
|
|
432 |
// 1. Enlever les mots du dico local
|
|
|
433 |
$bons = suggerer_dico_ortho($mots, $lang);
|
|
|
434 |
|
|
|
435 |
// 2. Enlever les mots du cache local
|
|
|
436 |
$result_cache = suggerer_cache_ortho($mots, $lang);
|
|
|
437 |
|
|
|
438 |
// 3. Envoyer les mots restants a un serveur
|
|
|
439 |
$mauvais = array();
|
|
|
440 |
if (count($mots)) {
|
|
|
441 |
$texte = join(' ', $mots);
|
|
|
442 |
|
|
|
443 |
// Hack : ligatures en francais pas gerees par aspell
|
|
|
444 |
unset($trans_rev);
|
|
|
445 |
$texte_envoi = $texte;
|
|
|
446 |
if ($lang == 'fr') {
|
|
|
447 |
$trans = array(chr(197).chr(146) => 'OE', chr(197).chr(147) => 'oe',
|
|
|
448 |
chr(195).chr(134) => 'AE', chr(195).chr(166) => 'ae');
|
|
|
449 |
$texte_envoi = strtr($texte_envoi, $trans);
|
|
|
450 |
$trans_rev = array_flip($trans);
|
|
|
451 |
}
|
|
|
452 |
|
|
|
453 |
// POST de la requete et recuperation du resultat XML
|
|
|
454 |
$urls = choisir_miroirs_ortho($lang);
|
|
|
455 |
if (!$urls) return false;
|
|
|
456 |
unset($ok);
|
|
|
457 |
$erreur = false;
|
|
|
458 |
foreach ($urls as $url) {
|
|
|
459 |
$xml = post_ortho($url, $texte_envoi, $lang);
|
|
|
460 |
if ($xml && preg_match(',<ortho>(.*)</ortho>,s', $xml, $r)) {
|
|
|
461 |
$xml = $r[1];
|
|
|
462 |
if (preg_match(',<erreur>.*<code>(.*)</code>.*</erreur>,s', $xml, $r))
|
|
|
463 |
$erreur = $r[1];
|
|
|
464 |
if (preg_match(',<ok>(.*)</ok>,s', $xml, $r)) {
|
|
|
465 |
$ok = $r[1];
|
|
|
466 |
break;
|
|
|
467 |
}
|
|
|
468 |
}
|
|
|
469 |
reset_miroir($url);
|
|
|
470 |
}
|
|
|
471 |
if (!isset($ok)) return $erreur;
|
|
|
472 |
|
|
|
473 |
// Remplir le tableau des resultats (mots mal orthographies)
|
|
|
474 |
if ($trans_rev) {
|
|
|
475 |
$assoc_mots = array_flip($mots);
|
|
|
476 |
}
|
|
|
477 |
while (preg_match(',<mot>(.*?)</mot>(\s*<suggest>(.*?)</suggest>)?,s', $ok, $r)) {
|
|
|
478 |
$p = strpos($ok, $r[0]);
|
|
|
479 |
$ok = substr($ok, $p + strlen($r[0]));
|
|
|
480 |
$mot = $r[1];
|
|
|
481 |
if ($suggest = $r[3])
|
|
|
482 |
$s = preg_split('/[ ,]+/', $suggest);
|
|
|
483 |
else
|
|
|
484 |
$s = array();
|
|
|
485 |
// Hack ligatures
|
|
|
486 |
if ($trans_rev) {
|
|
|
487 |
$mot_rev = strtr($mot, $trans_rev);
|
|
|
488 |
if ($mot != $mot_rev) {
|
|
|
489 |
if ($assoc_mots[$mot])
|
|
|
490 |
$mauvais[$mot] = $s;
|
|
|
491 |
if ($assoc_mots[$mot_rev])
|
|
|
492 |
$mauvais[$mot_rev] = $s;
|
|
|
493 |
}
|
|
|
494 |
else $mauvais[$mot] = $s;
|
|
|
495 |
}
|
|
|
496 |
else $mauvais[$mot] = $s;
|
|
|
497 |
}
|
|
|
498 |
}
|
|
|
499 |
if (!$erreur) ajouter_cache_ortho($mots, $mauvais, $lang);
|
|
|
500 |
|
|
|
501 |
// Retour a l'envoyeur
|
|
|
502 |
$mauvais = array_merge($result_cache, $mauvais);
|
|
|
503 |
$result = array(
|
|
|
504 |
'bons' => $bons,
|
|
|
505 |
'mauvais' => $mauvais
|
|
|
506 |
);
|
|
|
507 |
if ($erreur) $result['erreur'] = $erreur;
|
|
|
508 |
return $result;
|
|
|
509 |
}
|
|
|
510 |
|
|
|
511 |
//
|
|
|
512 |
// Fonctions d'affichage HTML
|
|
|
513 |
//
|
|
|
514 |
|
|
|
515 |
function panneau_ortho($ortho_result) {
|
|
|
516 |
global $id_suggest;
|
|
|
517 |
|
|
|
518 |
$id_suggest = array();
|
|
|
519 |
$i = 1;
|
|
|
520 |
|
|
|
521 |
$mauvais = $ortho_result['mauvais'];
|
|
|
522 |
$bons = $ortho_result['bons'];
|
|
|
523 |
if (!count($mauvais) && !count($bons)) return;
|
|
|
524 |
ksort($mauvais);
|
|
|
525 |
|
|
|
526 |
echo "<script type='text/javascript'><!--
|
|
|
527 |
var curr_suggest = null;
|
|
|
528 |
function suggest(id) {
|
|
|
529 |
var menu_box;
|
|
|
530 |
if (curr_suggest)
|
|
|
531 |
document.getElementById('suggest' + curr_suggest).className = 'suggest-inactif';
|
|
|
532 |
if (1 || id!=curr_suggest) {
|
|
|
533 |
document.getElementById('suggest' + id).className = 'suggest-actif';
|
|
|
534 |
curr_suggest = id;
|
|
|
535 |
}
|
|
|
536 |
else curr_suggest = null;
|
|
|
537 |
menu_box = document.getElementById('select_ortho');
|
|
|
538 |
if (menu_box.length > id) menu_box.selectedIndex = id;
|
|
|
539 |
}";
|
|
|
540 |
echo "//--></script>";
|
|
|
541 |
|
|
|
542 |
echo "<form class='form-ortho verdana2' action='' method='get'>\n";
|
|
|
543 |
echo "<select name='select_ortho' id='select_ortho' onChange='suggest(this.selectedIndex);'>\n";
|
|
|
544 |
echo "<option value='0'>... "._T('ortho_mots_a_corriger')." ...</option>\n";
|
|
|
545 |
foreach ($mauvais as $mot => $suggest) {
|
|
|
546 |
$id = $id_suggest[$mot] = "$i";
|
|
|
547 |
$i++;
|
|
|
548 |
$mot_html = afficher_ortho($mot);
|
|
|
549 |
echo "<option value='$id'>$mot_html</option>\n";
|
|
|
550 |
}
|
|
|
551 |
foreach ($bons as $mot) {
|
|
|
552 |
$id = $id_suggest[$mot] = "$i";
|
|
|
553 |
$i++;
|
|
|
554 |
}
|
|
|
555 |
echo "</select>\n";
|
|
|
556 |
echo "</form>\n";
|
|
|
557 |
// Mots mal orthographies :
|
|
|
558 |
// liste des suggestions plus lien pour ajouter au dico
|
|
|
559 |
foreach ($mauvais as $mot => $suggest) {
|
|
|
560 |
$id = $id_suggest[$mot];
|
|
|
561 |
$mot_html = afficher_ortho($mot);
|
|
|
562 |
echo "<div class='suggest-inactif' id='suggest$id'>";
|
|
|
563 |
echo "<span class='ortho'>$mot_html</span>\n";
|
|
|
564 |
echo "<div class='detail'>\n";
|
|
|
565 |
if (is_array($suggest) && count($suggest)) {
|
|
|
566 |
echo "<ul>\n";
|
|
|
567 |
$i = 0;
|
|
|
568 |
foreach ($suggest as $sug) {
|
|
|
569 |
if (++$i > 12) {
|
|
|
570 |
echo "<li><i>(...)</i></li>\n";
|
|
|
571 |
break;
|
|
|
572 |
}
|
|
|
573 |
echo "<li>".typo(afficher_ortho($sug))."</li>\n";
|
|
|
574 |
}
|
|
|
575 |
echo "</ul>\n";
|
|
|
576 |
}
|
|
|
577 |
else {
|
|
|
578 |
echo "<i>"._T('ortho_aucune_suggestion')."</i>";
|
|
|
579 |
}
|
|
|
580 |
echo "<br />";
|
|
|
581 |
$link = new Link;
|
|
|
582 |
$link->delVar('supp_ortho');
|
|
|
583 |
$link->addVar('ajout_ortho', $mot);
|
|
|
584 |
icone_horizontale(_T('ortho_ajouter_ce_mot'), $link->getUrl(), "ortho-24.gif", "creer.gif");
|
|
|
585 |
echo "</div>\n";
|
|
|
586 |
echo "</div>\n\n";
|
|
|
587 |
}
|
|
|
588 |
// Mots trouves dans le dico :
|
|
|
589 |
// message plus lien pour retirer du dico
|
|
|
590 |
foreach ($bons as $mot) {
|
|
|
591 |
$id = $id_suggest[$mot];
|
|
|
592 |
$mot_html = afficher_ortho($mot);
|
|
|
593 |
echo "<div class='suggest-inactif' id='suggest$id'>";
|
|
|
594 |
echo "<span class='ortho-dico'>$mot_html</span>";
|
|
|
595 |
echo "<div class='detail'>\n";
|
|
|
596 |
echo "<i>"._T('ortho_ce_mot_connu')."</i>";
|
|
|
597 |
echo "<br />";
|
|
|
598 |
$link = new Link;
|
|
|
599 |
$link->delVar('ajout_ortho');
|
|
|
600 |
$link->addVar('supp_ortho', $mot);
|
|
|
601 |
icone_horizontale(_T('ortho_supprimer_ce_mot'), $link->getUrl(), "ortho-24.gif", "supprimer.gif");
|
|
|
602 |
echo "</div>\n";
|
|
|
603 |
echo "</div>\n";
|
|
|
604 |
}
|
|
|
605 |
}
|
|
|
606 |
|
|
|
607 |
|
|
|
608 |
function souligner_match_ortho(&$texte, $cherche, $remplace) {
|
|
|
609 |
// Eviter les —, etc.
|
|
|
610 |
if ($cherche{0} == '&' AND $cherche{strlen($cherche) - 1} == ';') return;
|
|
|
611 |
|
|
|
612 |
if ($cherche{0} == '>')
|
|
|
613 |
$texte = str_replace($cherche, $remplace, $texte);
|
|
|
614 |
else {
|
|
|
615 |
// Ne pas remplacer a l'interieur des tags HTML
|
|
|
616 |
$table = explode($cherche, $texte);
|
|
|
617 |
unset($avant);
|
|
|
618 |
$texte = '';
|
|
|
619 |
foreach ($table as $s) {
|
|
|
620 |
if (!isset($avant)) {
|
|
|
621 |
$avant = $s;
|
|
|
622 |
continue;
|
|
|
623 |
}
|
|
|
624 |
$ok = true;
|
|
|
625 |
$texte .= $avant;
|
|
|
626 |
// Detecter si le match a eu lieu dans un tag HTML
|
|
|
627 |
if (is_int($deb_tag = strrpos($texte, '<'))) {
|
|
|
628 |
if (strrpos($texte, '>') <= $deb_tag)
|
|
|
629 |
$ok = false;
|
|
|
630 |
}
|
|
|
631 |
if ($ok) $texte .= $remplace;
|
|
|
632 |
else $texte .= $cherche;
|
|
|
633 |
$avant = $s;
|
|
|
634 |
}
|
|
|
635 |
$texte .= $avant;
|
|
|
636 |
}
|
|
|
637 |
}
|
|
|
638 |
|
|
|
639 |
function souligner_ortho($texte, $lang, $ortho_result) {
|
|
|
640 |
global $id_suggest;
|
|
|
641 |
$vu = array();
|
|
|
642 |
|
|
|
643 |
$mauvais = $ortho_result['mauvais'];
|
|
|
644 |
$bons = $ortho_result['bons'];
|
|
|
645 |
|
|
|
646 |
// Neutraliser l'apostrophe unicode pour surligner correctement les fautes
|
|
|
647 |
$texte = " ".str_replace("\xE2\x80\x99", "'", $texte)." ";
|
|
|
648 |
// Chercher et remplacer les mots un par un
|
|
|
649 |
$delim = '[^-\''.pcre_lettres_unicode().']';
|
|
|
650 |
foreach ($mauvais as $mot => $suggest) {
|
|
|
651 |
$pattern = ",$delim".$mot."$delim,us";
|
|
|
652 |
// Recuperer les occurences du mot dans le texte
|
|
|
653 |
if (preg_match_all($pattern, $texte, $regs, PREG_SET_ORDER)) {
|
|
|
654 |
$id = $id_suggest[$mot];
|
|
|
655 |
$mot_html = afficher_ortho($mot);
|
|
|
656 |
foreach ($regs as $r) {
|
|
|
657 |
if ($vu[$cherche = $r[0]]) continue;
|
|
|
658 |
$vu[$cherche] = 1;
|
|
|
659 |
$html = "<a class='ortho' onclick=\"suggest($id);return false;\" href=''>$mot_html</a>";
|
|
|
660 |
$remplace = str_replace($mot, $html, $cherche);
|
|
|
661 |
souligner_match_ortho($texte, $cherche, $remplace);
|
|
|
662 |
}
|
|
|
663 |
}
|
|
|
664 |
}
|
|
|
665 |
foreach ($bons as $mot) {
|
|
|
666 |
$pattern = ",$delim".$mot."$delim,us";
|
|
|
667 |
// Recuperer les occurences du mot dans le texte
|
|
|
668 |
if (preg_match_all($pattern, $texte, $regs, PREG_SET_ORDER)) {
|
|
|
669 |
$id = $id_suggest[$mot];
|
|
|
670 |
$mot_html = afficher_ortho($mot);
|
|
|
671 |
foreach ($regs as $r) {
|
|
|
672 |
if ($vu[$cherche = $r[0]]) continue;
|
|
|
673 |
$vu[$cherche] = 1;
|
|
|
674 |
$html = "<a class='ortho-dico' onclick=\"suggest($id);return false;\" href=''>$mot_html</a>";
|
|
|
675 |
$remplace = str_replace($mot, $html, $cherche);
|
|
|
676 |
souligner_match_ortho($texte, $cherche, $remplace);
|
|
|
677 |
}
|
|
|
678 |
}
|
|
|
679 |
}
|
|
|
680 |
|
|
|
681 |
$texte = preg_replace(',(^ | $),', '', $texte);
|
|
|
682 |
return $texte;
|
|
|
683 |
}
|
|
|
684 |
|
|
|
685 |
function init_ortho() {
|
|
|
686 |
global $duree_cache_ortho, $duree_cache_miroirs_ortho;
|
|
|
687 |
|
|
|
688 |
$duree_cache_ortho = 7 * 24 * 3600;
|
|
|
689 |
$duree_cache_miroirs_ortho = 24 * 3600;
|
|
|
690 |
lire_miroirs_ortho();
|
|
|
691 |
}
|
|
|
692 |
|
|
|
693 |
init_ortho();
|
|
|
694 |
|
|
|
695 |
?>
|