source: spip-zone/_dev_/salvatore2/ecriveur.php @ 82790

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

Utiliser sql_allfetsel + foreach plutot que spip_query et while + spip_fetch_array

File size: 16.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
27require_once(dirname(__FILE__).'/inc_tradlang.php');
28$tmp= _SALVATORE_TMP;
29
30trad_log("\n=======================================\nECRIVEUR\nExporte les fichiers de traduction dans sa copie locale a partir de la base de donnees\n=======================================\n");
31
32$liste_sources=charger_fichier_traductions(); // chargement du fichier traductions.txt
33
34if (!is_dir($tmp)) die ("Manque le repertoire ".$tmp);
35
36include_spip('base/abstract_sql');
37include_spip('inc/filtres');
38include_spip('inc/texte');
39include_spip('inc/config');
40include_spip('inc/xml');
41
42/**
43 * On récupère l'URL du site de traduction
44 * Elle servira à :
45 * -* empêcher l'export de fichiers traduits sur une autre plateforme
46 * -* générer l'url de l'interface de traduction d'un module
47 */
48$url_site = $GLOBALS['meta']['adresse_site'];
49
50if(isset($argv[1]) && strlen($argv[1]) > 1)
51        $message_commit = $argv[1]."\n\n";
52
53foreach ($liste_sources as $source) {
54        trad_log("==== Module ".$source[1]." =======================================\n");
55        $export = true;
56        /**
57         * On test ici si le fichier est géré par un autre salvatore
58         * Si oui on empeche son export 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                                $export = false;
68                                $sujet = 'Ecriveur : Erreur sur '.$source[1];
69                                $corps = "\nErreur : export impossible, le fichier est traduit autre part : $url != $url_site\n\n";
70                                trad_sendmail($sujet,$corps);
71                                trad_log("\nErreur : export impossible, le fichier est traduit autre part : $url != $url_site\n\n");           
72                        }
73                }
74        }
75        /**
76         * Si on l'exporte
77         */
78        if($export){
79                $id_tradlang_module = sql_getfetsel('id_tradlang_module','spip_tradlang_modules','module='.sql_quote($source[1]));
80                $url_trad = url_absolue(generer_url_entite($id_tradlang_module,'tradlang_module'),$url_site);
81                export_trad_module($source,$url_site,$url_trad,$message_commit);
82        }
83}
84
85return 0;
86
87//
88// Genere les fichiers de traduction d'un module
89//
90function export_trad_module($source,$url_site,$url_trad,$message_commit='') {
91        global $tmp;
92
93        // sanity check
94        if (!is_dir($tmp.$source[1]."/"))
95                return false;
96
97        $module = sql_fetsel('id_tradlang_module,limite_trad,lang_mere','spip_tradlang_modules','module='.sql_quote($source[1]));
98
99        $seuil_export = 50;
100        if(is_numeric($module['limite_trad']) && $module['limite_trad'] > 0){
101                $seuil_export = $module['limite_trad'];
102        }elseif(function_exists('lire_config')){
103                $seuil_export = lire_config('tradlang/seuil_export_tradlang',50);
104        }
105        if(intval($module['id_tradlang_module']) >= 1){
106                // charger la langue originale, pour la copier si necessaire
107                $count_original = 0;
108                $res=sql_allfetsel("id,id_tradlang_module,str,comm,statut","spip_tradlangs","id_tradlang_module=".intval($module['id_tradlang_module'])." and lang=".sql_quote($module['lang_mere'])." AND statut='OK'","id");
109                foreach ($res as $row) {
110                        $row['statut'] = 'NEW';
111                        $lorigine[$row['id']] = $row;
112                        $id_tradlang_module = $row['id_tradlang_module'];
113                        $count_original++;
114                }
115
116                $liste_lang = $liste_lang_non_exportees = $liste_lang_supprimer = array();
117                $minimal = ceil((($count_original*$seuil_export)/100));
118                trad_log("\n Minimal = $minimal ($seuil_export %)\n");
119
120                //$res=spip_query("SELECT lang,COUNT(*) as N FROM spip_tradlangs WHERE module='".$source[1]."' AND statut != 'NEW' AND statut != 'attic' GROUP BY lang ORDER BY lang");
121                $res=sql_allfetsel("lang,COUNT(*) as N","spip_tradlangs","module=".sql_quote($source[1])." AND statut != 'NEW' AND statut != 'attic'","lang","lang");
122                foreach ($res as $row) {
123                        /**
124                         * Le fichier est il suffisamment traduit
125                         */
126                        if($row['N'] >= $minimal)
127                                $liste_lang[]=$row['lang'];
128                        else{
129                                /**
130                                 * Le fichier n'est pas suffisamment traduit et n'existe pas, on ne fera donc rien
131                                 */
132                                if(!file_exists($tmp.$source[1]."/".$source[1].'_'.$row['lang'].'.php'))
133                                        $liste_lang_non_exportees[]=$row['lang'];
134
135                                /**
136                                 * Il n'est pas suffisamment traduit, cependant, il existe déjà
137                                 * On ne va donc pas le supprimer à la barbare, mais on le met à jour quand même
138                                 */
139                                else{
140                                        $liste_lang[]=$row['lang'];
141                                        $liste_lang_supprimer[]=$row['lang'];
142                                        $percent = (($row['N']/$count_original)*100);
143                                        if($percent < ($seuil_export-15))
144                                                $message_commit .= "La langue '".$row['lang']."' devrait être supprimée car trop peu traduite (".number_format($percent,2)." %)\n";
145                                }
146                        }
147                }
148       
149                // traiter chaque langue
150                $infos = $commiteurs = array();
151                foreach($liste_lang as $lang) {
152                        //trad_log(" generation de la langue $lang ");
153                        // Proteger les caracteres typographiques a l'interieur des tags html
154                        $typo = (in_array($lang,array('eo','fr','cpf')) || strncmp($lang, 'fr_', 3)==0) ? 'fr' : 'en';
155                        $typographie = charger_fonction($typo, 'typographie');
156                        $tab = "\t";
157                       
158                        $x = $tous = $tradlangs = array();
159                        $prev="";
160                        $traduits = $modifs = $relire = 0;
161
162                        // On ne prend que les MODIF, les RELIRE et les OK pour ne pas rendre les sites multilingues en français
163                        $res=sql_allfetsel("id_tradlang,id,str,comm,statut,md5","spip_tradlangs", "module='".$source[1]."' AND lang='".$lang."' AND statut != 'NEW' AND statut != 'attic'","id");
164                        foreach ($res as $row) {
165                                $tradlangs[] = $row['id_tradlang'];
166                                $tous[$row['id']] = $row;
167                        }
168                        ksort($tous);
169                       
170                        foreach ($tous as $row) {
171                                if ($row['statut'] == 'OK')
172                                        $traduits ++;
173                                else if($row['statut'] == 'MODIF')
174                                        $modifs ++;
175                                else if($row['statut'] == 'RELIRE')
176                                        $relire ++;
177       
178                                if(strlen($row['comm']) > 1){
179                                        // On remplace les sauts de lignes des commentaires sinon ça crée des erreurs php
180                                        $row['comm'] = str_replace(array("\r\n", "\n", "\r"),' ', $row['comm']);
181                                        // Conversion des commentaires en utf-8
182                                        $row['comm'] = unicode_to_utf_8(
183                                                html_entity_decode(
184                                                        preg_replace('/&([lg]t;)/S', '&amp;\1', $row['comm']),
185                                                        ENT_NOQUOTES, 'utf-8')
186                                        );
187                                }
188                               
189                                if ($prev!=strtoupper($row['id'][0])) $x[] = "\n$tab// ".strtoupper($row['id'][0]);
190                                $prev=strtoupper($row['id'][0]);
191                               
192                                if (strlen($row['statut']) && ($row['statut'] != 'OK'))
193                                        $row['comm'] .= ' '.$row['statut'];
194                                if (trim($row['comm'])) $row['comm']=" # ".trim($row['comm']); // on rajoute les commentaires ?
195       
196                                $str = $row['str'];
197                               
198                                /**
199                                 * On enlève les sauts de lignes windows pour des sauts de ligne linux
200                                 */
201                                $str = str_replace("\r\n", "\n", $str);
202                               
203                                /**
204                                 * protection dans les balises genre <a href="..." ou <img src="..."
205                                 * cf inc/filtres
206                                 */
207                                if (preg_match_all(_TYPO_BALISE, $str, $regs, PREG_SET_ORDER)) {
208                                        foreach ($regs as $reg) {
209                                                $insert = $reg[0];
210                                                // hack: on transforme les caracteres a proteger en les remplacant
211                                                // par des caracteres "illegaux". (cf corriger_caracteres())
212                                                $insert = strtr($insert, _TYPO_PROTEGER, _TYPO_PROTECTEUR);
213                                                $str = str_replace($reg[0], $insert, $str);
214                                        }
215                                }
216                               
217                                /**
218                                 * Protéger le contenu des balises <html> <code> <cadre> <frame> <tt> <pre>
219                                 */
220                                define('_PROTEGE_BLOCS_HTML', ',<(html|code|cadre|pre|tt)(\s[^>]*)?>(.*)</\1>,UimsS');
221                                if ((strpos($str,"<")!==false) && preg_match_all(_PROTEGE_BLOCS_HTML, $str, $matches, PREG_SET_ORDER)) {
222                                        foreach ($matches as $reg) {
223                                                $insert = $reg[0];
224                                                // hack: on transforme les caracteres a proteger en les remplacant
225                                                // par des caracteres "illegaux". (cf corriger_caracteres())
226                                                $insert = strtr($insert, _TYPO_PROTEGER, _TYPO_PROTECTEUR);
227                                                $str = str_replace($reg[0], $insert, $str);
228                                        }
229                                }
230                               
231                                /**
232                                 * On applique la typographie de la langue
233                                 */
234                                $str = $typographie($str);
235                                /**
236                                 * On remet les caractères normaux sur les caractères illégaux
237                                 */
238                                $str = strtr($str, _TYPO_PROTECTEUR, _TYPO_PROTEGER);
239                               
240                                $str = unicode_to_utf_8(
241                                        html_entity_decode(
242                                                preg_replace('/&([lg]t;)/S', '&amp;\1',$str),
243                                                ENT_NOQUOTES, 'utf-8')
244                                );
245                               
246                                /**
247                                 * Calcul du nouveau md5
248                                 */
249                                $newmd5 = md5($str);
250                               
251                                /**
252                                 * Si le md5 ou la chaine à changé, on la met à jour dans la base
253                                 */
254                                if (($row['md5'] != $newmd5) || ($str != $row['str']))
255                                        $r = sql_updateq("spip_tradlangs",array('md5'=>$newmd5,'str' =>$str),"id_tradlang=".intval($row['id_tradlang']));
256       
257                                $x[]="$tab".var_export($row['id'],1).' => ' .var_export($str,1).','.$row['comm'];
258                        }
259                        $orig = ($lang == $source[2]) ? $source[0] : false;
260       
261                        //trad_log(" - traduction ($traduits/$count_original OK | $relire/$count_original RELIRE | $modifs/$count_original MODIFS), export\n");
262                        // historiquement les fichiers de lang de spip_loader ne peuvent pas etre securises
263                        $secure = ($source[1] == 'tradloader')
264                                ? ''
265                                : "if (!defined('_ECRIRE_INC_VERSION')) return;\n\n";
266       
267                        $fd = fopen($tmp.$source[1]."/".$source[1].'_'.$lang.'.php', 'w');
268       
269                        # supprimer la virgule du dernier item
270                        $x[count($x)-1] = preg_replace('/,([^,]*)$/', '\1', $x[count($x)-1]);
271       
272                        $contenu = join("\n",$x);
273       
274                        // L'URL du site de traduction
275                        $url_trad = parametre_url($url_trad,'lang_cible',$lang);
276                        /**
277                         * Ecrire le fichier de langue complet
278                         */
279                        fwrite($fd,
280                        '<'.'?php
281// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
282'
283
284. ($orig
285        ? '// Fichier source, a modifier dans '.$orig
286: '// extrait automatiquement de '.$url_trad.'
287// ** ne pas modifier le fichier **
288'
289)
290."\n".$secure.'$GLOBALS[$GLOBALS[\'idx_lang\']] = array(
291'
292. $contenu
293.'
294);
295
296?'.'>
297'
298                        );
299                        fclose($fd);
300                       
301                        // noter la langue et les traducteurs pour lang/module.xml
302                        $infos[$lang] = $people_unique = array();
303                        $infos[$lang]['traducteurs'] = array();
304                        $infos[$lang]['traduits'] = $traduits;
305                        $infos[$lang]['modifs'] = $modifs;
306                        $infos[$lang]['relire'] = $relire;
307                        if(defined('_ID_AUTEUR_SALVATORE') && intval(_ID_AUTEUR_SALVATORE) > 0)
308                                $people_unique[] = _ID_AUTEUR_SALVATORE;
309                        $s = sql_allfetsel('DISTINCT(traducteur)','spip_tradlangs','id_tradlang_module='.intval($module['id_tradlang_module']).' AND lang='.sql_quote($lang));
310                        foreach ($s as $t){
311                                $traducteurs_lang = explode(',',$t['traducteur']);
312                                foreach($traducteurs_lang as $traducteur){
313                                        if(!in_array($traducteur,$people_unique)){
314                                                if(is_numeric($traducteur) AND $id_auteur=intval($traducteur)){
315                                                        $traducteur_supp['nom'] = extraire_multi(sql_getfetsel('nom','spip_auteurs','id_auteur='.$id_auteur));
316                                                        $traducteur_supp['lien'] = url_absolue(generer_url_entite($id_auteur,'auteur'),$url_site);
317                                                }else if(trim(strlen($traducteur)) > 0){
318                                                        $traducteur_supp['nom'] = trim($traducteur);
319                                                        $traducteur_supp['lien'] = '';
320                                                }
321                                                if(isset($traducteur_supp['nom']))
322                                                        $infos[$lang]['traducteurs'][strtolower($traducteur_supp['nom'])] = $traducteur_supp;
323                                                unset($traducteur_supp);
324                                                $people_unique[] = $traducteur;
325                                        }
326                                }
327                        }
328                        unset($people_unique);
329
330                        if(substr(exec("svn status "._SALVATORE_TMP.$source[1]."/".$source[1]."_$lang.php"),0,1) == '?'){
331                                if($module['limite_trad'] == 0)
332                                        passthru("svn add "._SALVATORE_TMP.$source[1]."/".$source[1]."_$lang.php 2> /dev/null") ? trad_log("$log\n") : '';
333                                else if(!in_array($source[1],array('ecrire','spip','public'))){
334                                        if((intval(($infos[$lang]['traduits']/$count_original)*100) > $seuil_export))
335                                                passthru("svn add "._SALVATORE_TMP.$source[1]."/".$source[1]."_$lang.php* 2> /dev/null") ? trad_log("$log\n") : '';
336                                }
337                        }
338                        /**
339                         * Le fichier a été modifié ou ajouté (svn status A ou M)
340                         *
341                         * On récupère la date de dernier changement avec svn info
342                         * On cherche toutes les dernières modifications dans la base de donnée
343                         * Si un seul auteur de révisions (Hors salvatore et -1) on l'ajoute comme commiteur
344                         * Si plusieurs auteurs le commiteur sera Salvatore
345                         */
346                        if(in_array(substr(exec("svn status "._SALVATORE_TMP.$source[1]."/".$source[1]."_$lang.php"),0,1),array('A','M'))){
347                                $last_change = exec("env LC_MESSAGES=en_US.UTF-8 svn info "._SALVATORE_TMP.$source[1]."/".$source[1]."_$lang.php | awk '/^Last Changed Date/ { print $4 \" \" $5 }'");
348                                $auteur_versions = sql_allfetsel('id_auteur','spip_versions','objet="tradlang" AND date > '.sql_quote($last_change).' AND '.sql_in('id_objet',$tradlangs).' AND id_auteur != "-1" AND id_auteur !='.intval(_ID_AUTEUR_SALVATORE),"id_auteur");
349                                if(count($auteur_versions) == 1){
350                                        $email = sql_getfetsel('email','spip_auteurs','id_auteur='.intval($auteur_versions[0]['id_auteur']));
351                                        if($email)
352                                                $commiteurs[$lang] = $email;
353                                        trad_log("\nLe commiteur sera pour la langue $lang : ".$commiteurs[$lang]." \n");
354                                }
355                        }
356                }
357       
358                // ecrire lang/module.xml
359                $xml = "<traduction module=\"$source[1]\" gestionnaire=\"salvatore\" url=\"$url_site\" source=\"$source[0]\" reference=\"$source[2]\">\n";
360                foreach($infos as $lang => $info) {
361                        if (count($info['traducteurs'] > 0)) {
362                                $xml .= "       <langue code=\"$lang\" url=\"".parametre_url($url_trad,'lang_cible',$lang)."\" total=\"$count_original\" traduits=\"".$info['traduits']."\" relire=\"".$info['relire']."\" modifs=\"".$info['modifs']."\" nouveaux=\"".($count_original-($info['modifs']+$info['traduits']+$info['relire']))."\" pourcent=\"".number_format((($info['traduits']/$count_original)*100),2)."\">\n";
363                                ksort($info['traducteurs']);
364                                foreach ($info['traducteurs'] as $nom => $people) {
365                                        $xml .= "               <traducteur nom=\"".entites_html($people['nom'])."\" lien=\"".entites_html($people['lien'])."\" />\n";
366                                }
367                                $xml .= "       </langue>\n";
368                        } else
369                                $xml .= "       <langue code=\"$lang\" url=\"".parametre_url($url_trad,'lang_cible',$lang)."\" />\n";
370                }
371                unset($traducteurs[$source[2]]);
372                $xml .= "</traduction>\n";
373       
374                ecrire_fichier($tmp.$source[1]."/".$source[1].'.xml', $xml);
375               
376                if(isset($liste_lang_non_exportees) && (count($liste_lang_non_exportees) > 0)){
377                        $liste_lang_non_exportees_string = implode(', ',$liste_lang_non_exportees);
378                        trad_log("\nLes langues suivantes ne sont pas exportées car trop peu traduites:\n");
379                        trad_log("$liste_lang_non_exportees_string\n");
380                }
381                if(isset($liste_lang_supprimer) && (count($liste_lang_supprimer) > 0)){
382                        $liste_lang_supprimer_string = implode(', ',$liste_lang_supprimer);
383                        trad_log("\nLes langues suivantes devraient être supprimées car trop peu traduites:\n");
384                        trad_log("$liste_lang_supprimer_string\n");
385                }
386                if($module['limite_trad'] == 0){
387                        foreach($liste_lang as $lang){
388                                passthru("svn add "._SALVATORE_TMP.$source[1]."/".$source[1]."_$lang.php* 2> /dev/null") ? trad_log("$log\n") : '';
389                        }
390                }
391                else if(!in_array($source[1],array('ecrire','spip','public'))){
392                        trad_log('Limite trad = '.$seuil_export);
393                        foreach($liste_lang as $lang){
394                                if( (intval(($infos[$lang]['traduits']/$count_original)*100) > $seuil_export) 
395                                        && (substr(exec("svn status "._SALVATORE_TMP.$source[1]."/".$source[1]."_$lang.php"),0,1) == '?')){
396                                        passthru("svn add "._SALVATORE_TMP.$source[1]."/".$source[1]."_$lang.php* 2> /dev/null") ? trad_log("$log\n") : '';
397                                }
398                        }
399                }
400                trad_log("\n".passthru("svn status "._SALVATORE_TMP.$source[1]."/")."\n");
401                if(strlen($message_commit) > 1 || count($commiteurs) > 0){
402                        $fd = fopen($tmp.$source[1]."/message_commit.inc", 'w');
403                        # ecrire le fichier
404                        fwrite($fd,
405                        '<'.'?php
406$message_commit = "'.$message_commit.'";
407
408$commiteurs = '.var_export($commiteurs,1).';
409
410?'.'>
411'
412                        );
413                        fclose($fd);
414                }
415        }else
416                trad_log("\n Ce module n'existe pas\n");
417
418}
419
420?>
Note: See TracBrowser for help on using the repository browser.