source: spip-zone/_dev_/salvatore2/lecteur.php @ 75725

Last change on this file since 75725 was 75725, checked in by kent1@…, 6 years ago

Même salvatore crée des révisions lorsqu'il modifie une chaîne de langue d'origine dans la base.

Il fout bien entendu lui donner un id_auteur (dans mes_options) pour que cette révision lui soit liée.

On améliore aussi la rapidité du script

File size: 13.3 KB
Line 
1<?php
2
3/*
4    This file is part of Salvatore, the translation robot of Trad-lang (SPIP)
5
6    Salvatore is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    Trad-Lang is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with Trad-Lang; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20    Copyright 2003-2013
21        Florent Jugla <florent.jugla@eledo.com>,
22        Philippe Riviere <fil@rezo.net>,
23        Chryjs <chryjs!@!free!.!fr>,
24                kent1 <kent1@arscenic.info>
25*/
26
27
28require_once(dirname(__FILE__).'/inc_tradlang.php');
29$tmp=_SALVATORE_TMP;
30$invalider = $die_message = false;
31
32/* modules de SPIP requis - il y a surement plus propre... */
33include_spip('base/abstract_sql');
34include_spip('inc/tradlang_verifier_langue_base');
35include_spip('inc/charsets');
36include_spip('inc/filtres');
37include_spip('inc/xml');
38include_spip('inc/lang_liste');
39include_spip('inc/session');
40
41if(defined('_ID_AUTEUR_SALVATORE') && is_numeric(_ID_AUTEUR_SALVATORE))
42        $GLOBALS['visiteur_session']['id_auteur'] = _ID_AUTEUR_SALVATORE;
43
44$url_site = sql_getfetsel('valeur','spip_meta','nom="adresse_site"');
45
46/* MAIN ***********************************************************************/
47
48trad_log("\n=======================================\nLECTEUR\nPrend les fichiers de reference dans sa copie locale et met a jour la base de donnees\n=======================================\n");
49
50$liste_sources=charger_fichier_traductions(); // chargement du fichier traductions.txt
51
52foreach ($liste_sources as $source) {
53        trad_log("==== Module ".$source[1]." =======================================\n");
54        $liste_fic_lang= glob($tmp.$source[1].'/'.$source[1]."_*.php");
55        $import = true;
56        /**
57         * On test ici si le fichier est géré par un autre salvatore
58         * Si oui on empeche son import en le signifiant
59         */
60        if(file_exists($xml = $tmp.$source[1].'/'.$source[1].'.xml')){
61                $xml_content = spip_xml_load($xml);
62                if(is_array($xml_content)){
63                        spip_xml_match_nodes('/^traduction/',$xml_content,$matches);
64                        $test = '<'.key($matches).'>';
65                        $url = extraire_attribut($test,'url');
66                        if($url && ($url != $url_site)){
67                                $import = false;
68                                $sujet = 'Lecteur : Erreur sur '.$source[1];
69                                $corps = "\nErreur : import impossible, le fichier est traduit autre part : $url\n\n";
70                                trad_sendmail($sujet,$corps);
71                                trad_log("\nErreur : import impossible, le fichier est traduit autre part : $url\n\n");
72                        }
73                }
74        }
75        if($import){
76                /**
77                 * on doit absolument charger la langue principale en premier (a cause des MD5)
78                 */ 
79                $fic_lang_principal=$tmp.$source[1].'/'.$source[1].'_'.$source[2].".php";
80               
81                /**
82                 * On regarde quelle est la date de dernière modification du fichier de langue principale
83                 */
84                $last_update = filemtime($fic_lang_principal);
85                if ($last_update > strtotime('-1 hour')){
86                        $priorite = '';
87                        $modifs = 0;
88                        if(defined('_TRAD_PRIORITE_DEFAUT'))
89                                $priorite = _TRAD_PRIORITE_DEFAUT;
90                        if (in_array($fic_lang_principal,$liste_fic_lang)) {
91                                $module = sql_fetsel('*','spip_tradlang_modules','module='.sql_quote($source[1]));
92                                $id_module = $module['id_tradlang_module'];
93                                /**
94                                 * Si le module n'existe pas... on le crée
95                                 */
96                                if(!intval($id_module))
97                                        $id_module = sql_insertq('spip_tradlang_modules',array('module'=>$source[1],'nom_mod'=>$source[1],'lang_prefix'=>$source[1],'lang_mere'=>$source[2],'priorite' => $priorite));
98                                /**
99                                 * Si la langue mere a changée, on la modifie
100                                 */
101                                else if($module['lang_mere'] != $source[2])
102                                        sql_updateq('spip_tradlang_modules',array('lang_mere'=>$source[2]),'id_tradlang_module='.intval($id_module));
103                                /**
104                                 * Si $id_module n'est pas un entier => on tue le script
105                                 */
106                                if(!intval($id_module)){
107                                        $sujet = 'Lecteur : Erreur sur '.$source[1];
108                                        $corps = "Le module n'est pas un entier";
109                                        trad_sendmail($sujet,$corps);
110                                        $die_message = "Le module n'est pas un entier";
111                                        break;
112                                }
113                                $liste_id_orig = array();
114                                $modifs = import_module_spip($source,$fic_lang_principal,$liste_id_orig,1,$id_module);
115                                $langues_a_jour = array();
116                                foreach ($liste_fic_lang as $f){
117                                        if ($f != $fic_lang_principal){
118                                                import_module_spip($source,$f,$liste_id_orig,0,$id_module);
119                                                $fich = str_replace($source[1],'',basename($f,".php"));
120                                                list(,$lang) = explode("_",$fich,2);
121                                                if(($modifs > 0) && function_exists('inc_tradlang_verifier_langue_base_dist')){
122                                                        inc_tradlang_verifier_langue_base_dist($source[1],$lang);
123                                                        trad_log("|-- Synchro de la langue ".$lang." pour le module ".$source[1]."\n");
124                                                }else if (!function_exists('inc_tradlang_verifier_langue_base_dist'))
125                                                        trad_log("|-- Fonction de synchro inexistante\n");
126                                                $langues_a_jour[] = $lang;
127                                        }
128                                }
129                                /**
130                                 * On s'occupe des langues en base sans fichier
131                                 * s'il y a eu au moins une modif et que l'on peut faire la synchro
132                                 */
133                                if(($modifs > 0) && function_exists('inc_tradlang_verifier_langue_base_dist')){
134                                        $langues_pas_a_jour = sql_select('lang','spip_tradlangs','id_tradlang_module='.intval($id_module).' AND '.sql_in('lang',$langues_a_jour,'NOT'),'lang');
135                                        while($langue_a_jour = sql_fetch($langues_pas_a_jour)){
136                                                inc_tradlang_verifier_langue_base_dist($source[1],$langue_a_jour['lang']);
137                                                trad_log("|-- Synchro de la langue non exportée en fichier ".$langue_a_jour['lang']." pour le module ".$source[1]."\n");
138                                        }
139                                }
140                                $invalider = true;
141                                trad_log("|\n");
142                                unset($langues_a_jour,$langues_pas_a_jour);
143                        }
144                        else {
145                                $sujet = 'Lecteur : Erreur sur '.$source[1];
146                                $corps = "|-- Pas de fichier lang ".$source[2]." pour le module ".$source[1]." : import impossible pour ce module\n";
147                                trad_sendmail($sujet,$corps);
148                                $die_message = "|-- Pas de fichier lang ".$source[2]." pour le module ".$source[1]." : import impossible pour ce module\n"; 
149                                break;
150                        }
151                }else{
152                        trad_log("On ne l importe pas car modifié il y a longtemps\n\n");
153                }
154        }
155}
156
157if($invalider){
158        include_spip('inc/invalideur');
159        suivre_invalideur('1');
160}
161
162if($die_message){
163        die("$die_message");
164}
165return 0;
166
167/**
168 * Import d'un fichier de langue dans la base
169 *
170 * @param array $source
171 * @param string $module
172 * @param array $liste_id_orig
173 * @param int $orig 1 signifie que c'est la langue originale
174 * @param int $id_module
175 * @return string
176 */
177function import_module_spip($source=array(),$module='',&$liste_id_orig,$orig=null,$id_module) {
178        trad_log( "!\n+ Import de $module\n");
179        $memtrad = $GLOBALS['idx_lang'] = 'i18n_'.crc32($module).'_tmp';
180        $GLOBALS[$GLOBALS['idx_lang']] = null;
181        $comm_fic_lang = charger_comm_fichier_langue($module);
182        include $module;
183
184        $str_lang = $GLOBALS[$memtrad];  // on a vu certains fichiers faire des betises et modifier idx_lang
185
186        if (is_null($str_lang)) {
187                trad_log("Erreur, fichier $module mal forme\n");
188                $sujet = 'Lecteur : Erreur sur '.$module;
189                $corps = "Erreur, fichier $module mal forme\n";
190                trad_sendmail($sujet,$corps);
191                return false;
192        }
193
194        /**
195         * Nettoyer le contenu de ses <MODIF>,<NEW> et <PLUS_UTILISE>
196         * Ces chaines sont utilisées comme statut
197         */ 
198        $status = array();
199
200        foreach($str_lang as $id=>$v) {
201                if(1==$orig)
202                        $status[$id] = 'OK';
203                else if (preg_match(',^<(MODIF|NEW|PLUS_UTILISE)>,US', $v, $r)) {
204                        $str_lang[$id] = preg_replace(',^(<(MODIF|NEW|PLUS_UTILISE)>)+,US', '', $v);
205                        $status[$id] = $r[1];
206                }
207                else   
208                        $status[$id] = 'OK';
209        }
210
211        $fich = str_replace($source[1],'',basename($module,".php"));
212        $mod = $source[1];
213        list(,$lang)=explode("_",$fich,2);
214       
215        if(!array_key_exists($lang,$GLOBALS['codes_langues'])){
216                trad_log("!-- Attention : La langue $lang n'existe pas dans les langues possibles - $mod \n"); 
217        }
218        else{
219                if (1==$orig)
220                        $res = spip_query("SELECT id, str, md5 FROM spip_tradlangs WHERE module='".$source[1]."' and lang='".$lang."' ");
221                else
222                        $res = spip_query("SELECT id, str, md5 FROM spip_tradlangs WHERE module='".$source[1]."' and lang='".$lang."' and statut!='MODIF' ");
223                $nb = sql_count($res);
224                if ($nb > 0)
225                        trad_log("!-- Fichier de langue $lang du module $mod deja inclus dans la base\n");
226       
227                $ajoutees = $inchangees = $supprimees = $modifiees = $ignorees = 0;
228               
229                /**
230                 * Si la langue est deja dans la base, on ne l'ecrase que s'il s'agit
231                 * de la langue source
232                 */
233                if ($nb == 0 OR $orig == 1) {
234                        // La liste de ce qui existe deja
235                        $existant = array();
236                        while ($t = spip_fetch_array($res))
237                                $existant[$t['id']] = $t['md5'];
238       
239                        $bigwhere = "module='".$source[1]."' and lang='".$lang."'";
240       
241                        include_spip('action/editer_tradlang');
242                        // Dans ce qui arrive, il y a 4 cas :
243                        foreach (array_unique(array_merge(
244                                array_keys($existant), array_keys($str_lang)
245                        )) as $id) {
246                                $comm=(isset($comm_fic_lang[$id])) ? $comm_fic_lang[$id] : "";
247                                // * chaine neuve
248                                if (isset($str_lang[$id])
249                                AND !isset($existant[$id]))
250                                {
251                                        if ($orig) {
252                                                $md5 = md5($str_lang[$id]);
253                                        } else if (!isset($liste_id_orig[$id])) {
254                                                trad_log("!-- Chaine $id inconnue dans la langue principale\n");
255                                                $ignorees++;
256                                        } else {
257                                                $md5 = $liste_id_orig[$id];
258                                        }
259       
260                                        if (isset($md5)){
261                                                /**
262                                                 * Forcer le passage en UTF-8
263                                                 */
264                                                $str_lang[$id] = str_replace("\r\n", "\n", unicode_to_utf_8(
265                                                        html_entity_decode(
266                                                                preg_replace('/&([lg]t;)/S', '&amp;\1', $str_lang[$id]),
267                                                                ENT_NOQUOTES, 'utf-8')
268                                                ));
269                                               
270                                                /**
271                                                 * Si le commentaire est un statut et que l'on ne traite pas le fichier de langue mère
272                                                 * On vire le commentaire et met son contenu comme statut
273                                                 */
274                                                if(in_array($comm,array('NEW','OK','MODIF','MODI')) && $orig != 1){
275                                                        if($comm == 'MODI')
276                                                                $comm = 'MODIF';
277                                                        $status[$id] = $comm;
278                                                        $comm = '';
279                                                }
280                                                else if ((strlen($comm) > 1) && preg_match("/(.*?)(NEW|OK|MODIF)(.*?)/",$comm,$matches)) {
281                                                        if($orig != 1)
282                                                                $status[$id] = $matches[2];
283                                                        $comm = preg_replace("/(NEW|OK|MODIF)/",'',$comm);
284                                                }
285                                               
286                                                /**
287                                                 * On génère un titre
288                                                 */
289                                                $titre = $id.' : '.$source[1].' - '.$lang;
290                                               
291                                                spip_query("INSERT spip_tradlangs (id_tradlang_module,titre,module,lang,id,str,comm,md5,statut)
292                                                VALUES ("
293                                                        ._q($id_module).', '
294                                                        ._q($titre).', '
295                                                        ._q($source[1]).', '
296                                                        ._q($lang).', '
297                                                        ._q($id).', '
298                                                        ._q($str_lang[$id]).', '
299                                                        ._q($comm).', '
300                                                        ._q($md5).', '
301                                                        ._q($status[$id])
302                                                        .")"
303                                                );
304                                                $ajoutees++;
305                                        }
306                                }
307                                else
308                                // * chaine existante
309                                if (isset($str_lang[$id]) AND isset($existant[$id]))
310                                {
311                                        // * identique ? => NOOP
312                                        $md5 = md5($str_lang[$id]);
313                                        if ($md5 == $existant[$id]) {
314                                                $inchangees++;
315                                        }
316                                        // * modifiee ? => UPDATE
317                                        else {
318                                                // modifier la chaine
319                                                $modifs = array(
320                                                        'str' => $str_lang[$id],
321                                                        'md5' => ($orig ? $md5 : $existant[$id]),
322                                                        'statut' => ($orig ? 'OK' : ''),
323                                                        'comm' => $comm,
324                                                );
325                                               
326                                                $id_tradlang = sql_getfetsel('id_tradlang','spip_tradlangs',"$bigwhere AND id=".sql_quote($id));
327                                                $test = tradlang_set($id_tradlang,$modifs);
328       
329                                                // signaler le status MODIF de ses traductions
330                                                if ($orig && ($orig != 0))
331                                                        spip_query("UPDATE spip_tradlangs SET statut='MODIF'
332                                                                WHERE module='".$source[1]
333                                                                ."' AND id="._q($id)
334                                                                ." AND md5!="._q($md5)
335                                                                ." AND lang!="._q($lang)
336                                                                ." AND statut!='NEW'"
337                                                        );
338                                                $modifiees++;
339                                        }
340                                }
341                                else
342                                // * chaine supprimee
343                                if (!isset($str_lang[$id]) AND isset($existant[$id])){
344                                        // mettre au grenier
345                                        spip_query("UPDATE spip_tradlangs SET id="._q($source[1].'_'.$id)
346                                        .", module='attic*".$source[1]."' WHERE id="._q($id)." AND module="._q($source[1]));
347                                        $supprimees++;
348                                }
349                               
350                                if ($orig AND isset($str_lang[$id]))
351                                        $liste_id_orig[$id] = md5($str_lang[$id]);
352                        }
353       
354                        trad_log("!-- module ".$source[1].", $lang : $modifiees modifiees, $ajoutees ajoutees, $supprimees supprimees, $ignorees ignorees, $inchangees inchangees\n");
355                }
356        }
357        unset($liste_id_orig,$str_lang,$GLOBALS[$GLOBALS['idx_lang']]);
358        return $ajoutees + $supprimees + $modifiees;
359}
360
361/**
362 * Chargement des commentaires de fichier de langue
363 * Le fichier est chargé en mode texte pour récupérer les commentaires dans lesquels sont situés les statuts
364 *
365 * @param string $f Le chemin du fichier de langue
366 * @return array $liste_trad Un tableau id/chaine
367 */
368function charger_comm_fichier_langue($f) {
369
370        $contenu=file_get_contents($f);
371
372        $tab=preg_split("/\r\n|\n\r|;\n|\n\/\/|\(\n|\n\);\n|\'\,\n|\n[\s\t]*(\')|\/\/[\s\t][0-9A-Z]\n[\s\t](\')/", $contenu,'-1',PREG_SPLIT_NO_EMPTY);
373
374        $liste_trad=array();
375        reset($tab);
376       
377        while (list(,$ligne) = each($tab)){
378                $ligne = str_replace("\'",'',$ligne);
379                if (strlen($ligne)>0) {
380                        if (preg_match("/(.*?)\'[\s\t]*=>[\s\t]*\'(.*?)\'[\s\t]*,{0,1}[\s\t]*(#.*)?/ms",$ligne,$matches)) {
381                                if (isset($matches[1]) and isset($matches[3]) and strlen(trim($matches[3]))>0 ) {
382                                        list(,$comm)=explode("#",$matches[3]);
383                                        $liste_trad[$matches[1]]=trim($comm);
384                                }
385                        }
386                }
387        }
388        reset($liste_trad);
389        return $liste_trad;
390}
391
392?>
Note: See TracBrowser for help on using the repository browser.