source: spip-zone/_dev_/salvatore/trunk/ecriveur.php

Last change on this file was 101880, checked in by kent1@…, 4 years ago

Ici aussi ne pas prendre en compte http et https suite au passage en https de trad.spip.net

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