source: spip-zone/_plugins_/trad-lang/trunk/inc/salvatore.php @ 119741

Last change on this file since 119741 was 119741, checked in by Cerdic, 2 years ago

permettre de tester en dev en forcant l'url du gestionnaire

  • Property svn:eol-style set to native
File size: 13.7 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
28/**
29 * initialiser salvatore si besoin
30 * peut etre appelle plusieurs fois
31 * @param string|array $log_function
32 * @throws Exception
33 */
34function salvatore_init($log_function = null){
35        static $initialized;
36
37        // set log function if any
38        if ($log_function){
39                salvatore_log('', $log_function);
40        }
41
42        if (is_null($initialized)){
43                @ini_set('memory_limit', '50M');
44                if (!defined('_DEBUG_TRAD_LANG')){
45                        define('_DEBUG_TRAD_LANG', 1); // undef si on ne veut pas de messages
46                }
47
48                if (!defined('_DIR_SALVATORE')){
49                        define('_DIR_SALVATORE', _DIR_RACINE . 'salvatore/');
50                }
51
52                if (!defined('_DIR_SALVATORE_TRADUCTIONS')){
53                        define('_DIR_SALVATORE_TRADUCTIONS', _DIR_SALVATORE . 'traductions/');
54                }
55
56                if (!defined('_DIR_SALVATORE_TMP')){
57                        define('_DIR_SALVATORE_TMP', _DIR_SALVATORE . 'tmp/');
58                }
59
60                if (!defined('_DIR_SALVATORE_MODULES')){
61                        define('_DIR_SALVATORE_MODULES', _DIR_SALVATORE . 'modules/');
62                }
63
64                if (!defined('_DIR_SALVATORE_DEPOTS')){
65                        define('_DIR_SALVATORE_DEPOTS', _DIR_SALVATORE . 'depots/');
66                }
67
68                if (defined('_ID_AUTEUR_SALVATORE') and is_numeric(_ID_AUTEUR_SALVATORE)){
69                        $GLOBALS['visiteur_session'] = array();
70                        $GLOBALS['visiteur_session']['id_auteur'] = _ID_AUTEUR_SALVATORE;
71                        // TODO : charger une session complete ?
72                }
73
74                // par defaut on relit les fichiers si modifies depuis moins de 1J
75                if (!defined('_SALVATORE_LECTEUR_REFRESH_DELAY')){
76                        define('_SALVATORE_LECTEUR_REFRESH_DELAY', 24 * 3600);
77                }
78
79                if (!isset($GLOBALS['idx_lang'])){
80                        $GLOBALS['idx_lang'] = 0;
81                }
82
83                // verifications des repertoires
84                foreach ([_DIR_SALVATORE, _DIR_SALVATORE_TRADUCTIONS, _DIR_SALVATORE_MODULES, _DIR_SALVATORE_DEPOTS, _DIR_SALVATORE_TMP] as $dir){
85                        salvatore_check_dir($dir);
86                }
87                $initialized = true;
88        }
89}
90
91
92/**
93 * chargement du fichier traductions.txt
94 * Construit une liste de modules avec pour chacun un tableau associatif
95 *
96 * @param string $fichier_traductions
97 * @return array
98 * @throws Exception
99 */
100function salvatore_charger_fichier_traductions($fichier_traductions = null){
101
102        salvatore_init();
103        if (is_null($fichier_traductions)){
104                $fichier_traductions = _DIR_SALVATORE_TRADUCTIONS . 'traductions.txt';
105        }
106        salvatore_check_file($fichier_traductions);
107
108        $lignes = file($fichier_traductions);
109        $lignes = array_map('trim', $lignes);
110        $lignes = array_filter($lignes);
111
112        $liste_trad = array();
113        foreach ($lignes as $ligne){
114                if ($ligne[0]!=='#'){
115                        $liste = explode(';', trim($ligne));
116                        $methode = $url = $branche = $dir = $module = $lang = '';
117
118                        // deprecated ancien format, forcement en svn
119                        // liste courte de type
120                        // url;module;lang
121                        if (count($liste)<=3){
122                                $methode = 'svn';
123                                $branche = '';
124                                $url = $liste[0];
125                                if (empty($liste[1])){
126                                        $module = preg_replace('#.*/(.*)$#', '$1', $url);
127                                } else {
128                                        $module = $liste[1];
129                                }
130                                if (empty($liste[2])){
131                                        $lang = 'fr';
132                                } else {
133                                        $lang = $liste[2];
134                                }
135                        }
136                        // format complet et explicite de 6 valeurs
137                        // seule les valeurs pour branche et dir peuvent etre vide (branche master par defaut en git)
138                        // svn;url;;;module;lang
139                        // git;url;master;subdir/tolang;module;lang
140                        else {
141                                list($methode, $url, $branche, $dir, $module, $lang) = $liste;
142                        }
143                        $methode = trim($methode);
144                        $url = trim($url);
145                        $url = rtrim($url, '/'); // homogeneiser
146                        $dir = trim($dir);
147                        $dir = trim($dir, '/'); // homogeneiser
148                        $branche = trim($branche);
149                        $module = trim($module);
150                        $lang = trim($lang);
151
152                        if ($methode
153                                and $url
154                                and $module
155                                and $lang){
156                                // que fait la $GLOBALS['modules'] ?
157                                if (empty($GLOBALS['modules']) or in_array($module, $GLOBALS['modules'])){
158                                        // definir un dir checkout unique meme si plusieurs modules de meme nom dans differents repos
159                                        $d = explode('/', $url);
160                                        while (count($d) and in_array(end($d), ['', 'lang', 'trunk', 'ecrire'])){
161                                                array_pop($d);
162                                        }
163                                        $source = '';
164                                        if (end($d)){
165                                                $source = basename(end($d), '.git');
166                                                $source = '--' . preg_replace(',[^\w-],', '_', $source);
167                                        }
168                                        $dir_module = "{$module}{$source}-" . substr(md5("$methode:$url:$branche:$dir"), 0, 5);
169                                        $dir_checkout = preg_replace(",\W+,", "-", "$methode-$url") . ($branche ? "--$branche-" : "-") . substr(md5("$methode:$url:$branche"), 0, 5);
170
171                                        $liste_trad[] = [
172                                                'methode' => $methode,
173                                                'url' => $url,
174                                                'branche' => $branche,
175                                                'dir' => $dir,
176                                                'module' => $module,
177                                                'lang' => $lang,
178                                                'dir_module' => $dir_module,
179                                                'dir_checkout' => $dir_checkout,
180                                        ];
181                                }
182                        } else {
183                                salvatore_log("Fichier $fichier_traductions, IGNORE ligne incomplete : $ligne");
184                        }
185                }
186        }
187        return $liste_trad;
188}
189
190/**
191 * Extraire la lang d'un fichier de langue d'un module donne
192 * @param string $module
193 * @param string $fichier_lang
194 * @return array|mixed|string|string[]
195 */
196function salvatore_get_lang_from($module, $fichier_lang) {
197        $lang = str_replace($module, '__', basename($fichier_lang, '.php'));
198        $lang = explode('___', $lang, 2);
199        $lang = end($lang);
200
201        return $lang;
202}
203
204
205/**
206 * Verifier si un module de langue est gere par ce salvatore
207 * @param $dir_module
208 * @param $module
209 * @return string
210 *   l'autre gestionnaire de trad si c'est pas nous
211 *   chaine vide si c'est bien nous qui gerons
212 */
213function salvatore_verifier_gestionnaire_traduction($dir_module, $module) {
214
215        /**
216         * On teste ici si le fichier est géré par un autre salvatore
217         * Si oui on empeche son import en le signifiant
218         */
219        if ($t = salvatore_lire_gestionnaire_traduction($dir_module, $module)){
220                $url = extraire_attribut($t, 'url');
221                $gestionnaire = extraire_attribut($t, 'gestionnaire');
222                $gestionnaire_url = $GLOBALS['meta']['adresse_site'];
223                if (defined('_SALVATORE_TEST_URL_GESTIONNAIRE')) {
224                        $gestionnaire_url = _SALVATORE_TEST_URL_GESTIONNAIRE;
225                }
226                if ($gestionnaire !== 'salvatore'
227                  or protocole_implicite($url) !== protocole_implicite($gestionnaire_url)) {
228                        return "$gestionnaire@$url";
229                }
230        }
231
232        return '';
233}
234
235/**
236 * Lire la balise <traduction> du fichier .xml
237 * @param string $dir_module
238 * @param string $module
239 * @return string
240 */
241function salvatore_lire_gestionnaire_traduction($dir_module, $module) {
242        $xml_file = $dir_module . '/' . $module . '.xml';
243        /**
244         * On teste ici si le fichier est géré par un autre salvatore
245         * Si oui on empeche son import en le signifiant
246         */
247        if (file_exists($xml_file)){
248                $xml_content = spip_xml_load($xml_file);
249                if (is_array($xml_content)){
250                        // normalement on a qu'une balise <traduction...> englobante, donc on prend la premiere qu'on trouve
251                        if (spip_xml_match_nodes('/^traduction/', $xml_content, $matches)
252                          and $nodes = array_keys($matches)
253                          and $node = reset($nodes)) {
254                                return "<$node>";
255                        }
256                }
257        }
258        return '';
259}
260
261/**
262 * Retrouver la ligne de spip_tradlang_modules qui correspond a un dir_module/module, meme en cas de chanchement de repo (url/branches)
263 * Attention : ca veut dire que si on branche et qu'on veut traduire 2 branches d'un meme module
264 * il faut supprimer le fichier xml de la nouvelle branche pour qu'elle soit bien ajoutee a trad-lang
265 * et eviter qu'on pense que c'est un renommage
266 *
267 * @param $dir_module
268 * @param $module
269 * @return array|bool
270 */
271function salvatore_retrouver_tradlang_module($dir_module, $module) {
272        $base_dir_module = basename($dir_module);
273        if ($row_module = sql_fetsel('*', 'spip_tradlang_modules', 'dir_module = ' . sql_quote($base_dir_module))) {
274                return $row_module;
275        }
276        // peut-etre c'est un module qui a change d'url repo, et donc son dir_module a change ?
277        // TODO : ecrire dir_module dans dir=".." de la balise <traduction>
278        if ($t = salvatore_lire_gestionnaire_traduction($dir_module, $module)
279          and $old_dir_module = extraire_attribut($t, 'dir')
280          and $old_dir_module !== $base_dir_module){
281
282                if ($row_module = sql_fetsel('*', 'spip_tradlang_modules', 'dir_module = ' . sql_quote($old_dir_module))) {
283                        return $row_module;
284                }
285        }
286
287        return false;
288}
289
290/**
291 * Ajouter les credentials user/pass sur les urls de repo
292 * @param string $methode
293 * @param string $url_repository
294 * @param string $module
295 * @return string
296 */
297function salvatore_set_credentials($methode, $url_repository, $module){
298        global $domaines_exceptions, $domaines_exceptions_credentials,
299               $SVNUSER, $SVNPASSWD,
300               $GITUSER, $GITPASSWD;
301
302        // on ne sait pas mettre des credentials si c'est du ssh
303        if (strpos($url_repository, '://')!==false){
304                $user = $pass = false;
305                $parts = parse_url($url_repository);
306                if (empty($parts['user']) and empty($parts['pass'])){
307                        $host = $parts['host'];
308                        require_once(_DIR_ETC . 'salvatore_passwd.inc');
309
310                        if (!empty($domaines_exceptions)
311                                and is_array($domaines_exceptions)
312                                and in_array($host, $domaines_exceptions)){
313                                // on est dans une exception
314
315                                /**
316                                 * Est-ce que cette exception dispose de credentials (Github?)
317                                 */
318                                if (is_array($domaines_exceptions_credentials)
319                                        and !empty($domaines_exceptions_credentials[$host])){
320                                        $user = $domaines_exceptions_credentials[$host]['user'];
321                                        $pass = $domaines_exceptions_credentials[$host]['pass'];
322                                }
323
324                        } else {
325                                // un truc perso pour un module en particulier ?
326                                if (isset(${$module . '_user'})){
327                                        $user = ${$module . '_user'};
328                                        $pass = ${$module . '_passwd'};
329                                } elseif ($methode==='svn' and isset($SVNUSER)) {
330                                        $user = $SVNUSER;
331                                        $pass = $SVNPASSWD;
332                                } elseif ($methode==='git' and isset($GITUSER)) {
333                                        $user = $GITUSER;
334                                        $pass = $GITPASSWD;
335                                }
336                        }
337
338                        if ($user and $pass){
339                                $url_repository = str_replace("://$host", "://" . urlencode($user) . ":" . urlencode($pass) . "@$host", $url_repository);
340                        }
341                }
342
343        }
344
345        return $url_repository;
346}
347
348
349/**
350 * Verifier qu'un repertoire existe
351 * @param $dir
352 * @throws Exception
353 */
354function salvatore_check_dir($dir){
355        if (!is_dir($dir)){
356                throw new Exception("Erreur : le répertoire $dir n'existe pas");
357        }
358}
359
360/**
361 * Verifier qu'un fichier existe
362 * @param $file
363 * @throws Exception
364 */
365function salvatore_check_file($file){
366        if (!file_exists($file)){
367                throw new Exception("Erreur : Le fichier $file est introuvable");
368        }
369}
370
371/**
372 * Loger
373 * @param string $msg
374 * @param string|array $display_function
375 */
376function salvatore_log($msg = '', $display_function = null){
377        static $function = null;
378
379        if ($display_function and is_callable($display_function)){
380                $function = $display_function;
381        }
382
383        if (defined('_DEBUG_TRAD_LANG')
384                and _DEBUG_TRAD_LANG
385                and $msg){
386                if ($function){
387                        call_user_func($function, rtrim($msg));
388                } else {
389                        // fallback : utiliser echo mais enlever les balises de formatage symphony
390                        $msg = str_replace(["<info>", "</info>", "<error>", "</error>", "<comment>", "</comment>", "<question>", "</question>", "</>"], "", $msg);
391                        echo rtrim($msg) . "\n";
392                }
393        }
394}
395
396/**
397 * Echec sur erreur : on envoie un mail si possible et on echoue en lançant une exception
398 * @param $sujet
399 * @param $corps
400 * @throws Exception
401 */
402function salvatore_fail($sujet, $corps){
403        $corps = rtrim($corps) . "\n\n";
404        salvatore_envoyer_mail($sujet, $corps);
405        throw new Exception($corps);
406}
407
408/**
409 * @param string $sujet
410 * @param string $corps
411 */
412function salvatore_envoyer_mail($sujet = 'Erreur', $corps = ''){
413        if (defined('_EMAIL_ERREURS') and _EMAIL_ERREURS
414                and defined('_EMAIL_SALVATORE') and _EMAIL_SALVATORE){
415                $envoyer_mail = charger_fonction('envoyer_mail', 'inc');
416                $destinataire = _EMAIL_ERREURS;
417                $from = _EMAIL_SALVATORE;
418                $envoyer_mail($destinataire, $sujet, $corps, $from);
419                salvatore_log("Un email a été envoyé à l'adresse : " . _EMAIL_ERREURS . "\n");
420        }
421}
422
423
424/**
425 * Verifier que la base de salvatore a bien ete mise a jour
426 * pour ajouter le dir_module qui est la cle unique a la place de module
427 * lancer
428 * spip salvatore:upgrade --traductions=...
429 * avec le bon fichier de traduction pour mettre à jour la base de salvatore avant de pouvoir lancer a nouveau le lecteur ou l'ecriveur
430 */
431function salvatore_verifier_base_upgradee() {
432
433        $schema_declare = filtre_info_plugin_dist('tradlang', 'schema');
434        $schema_base = $GLOBALS['meta']['tradlang_base_version'];
435        if ($schema_base !== $schema_declare) {
436                throw new Exception("Schema de base pas a jour ($schema_base vs $schema_declare). Lancez la commande \nspip salvatore:upgrade --help");
437        }
438
439        $trouver_table = charger_fonction('trouver_table', 'base');
440        $desc = $trouver_table('spip_tradlang_modules');
441
442        // est-ce que le champ a ete cree ?
443        if (!isset($desc['field']['dir_module'])) {
444                throw new Exception("Pas de champ dir_module dans la base spip_tradlang_modules. Lancez la commande \nspip salvatore:upgrade --help");
445        }
446
447        // est-ce que tous les modules en base on bien eu un dir_module affecte (et ni vide ni =module qui est la valeur par defaut lors de l'upgrade de base)
448        $nb = sql_countsel('spip_tradlang_modules', "dir_module='' OR dir_module=module");
449        if ($nb>0) {
450                throw new Exception("Le champ dir_module de spip_tradlang_modules n'est pas renseigne pour tous les modules. Lancez la commande \nspip salvatore:upgrade --help");
451        }
452
453}
Note: See TracBrowser for help on using the repository browser.