diff --git a/salvatore/lecteur.php b/salvatore/lecteur.php index 9bae4c55e99e8623643de141233feafabecfea1e..735167dc74bcc7b7625f902bf1d50fc7ca95a38f 100644 --- a/salvatore/lecteur.php +++ b/salvatore/lecteur.php @@ -83,6 +83,7 @@ function salvatore_lire($liste_sources, $force_reload = false, $dir_modules = nu * On regarde quelle est la date de dernière modification du fichier de langue principale */ $last_update = filemtime($fichier_lang_principal); + $type_export = salvatore_retrouver_type_export($fichier_lang_principal); if ($row_module = salvatore_retrouver_tradlang_module($dir_module, $module)) { $id_tradlang_module = (int) $row_module['id_tradlang_module']; @@ -93,8 +94,17 @@ function salvatore_lire($liste_sources, $force_reload = false, $dir_modules = nu if ($row_module['lang_mere'] !== $source['lang']) { sql_updateq('spip_tradlang_modules', ['lang_mere' => $source['lang']], 'id_tradlang_module=' . (int) $id_tradlang_module); salvatore_log('lang_mere mise a jour : ' . $row_module['lang_mere'] . ' => ' . $source['lang']); + $last_update = time(); $row_module['lang_mere'] = $source['lang']; + } + /** + * Si le type d’export de fichier a changé, on le modifie + */ + if ($row_module['type_export'] !== $type_export) { + sql_updateq('spip_tradlang_modules', ['type_export' => $type_export], 'id_tradlang_module=' . (int) $id_tradlang_module); + salvatore_log('type_export mise a jour : ' . $row_module['type_export'] . ' => ' . $type_export); $last_update = time(); + $row_module['type_export'] = $type_export; } /** * Si le dir_module a change, on le met a jour @@ -121,7 +131,6 @@ function salvatore_lire($liste_sources, $force_reload = false, $dir_modules = nu if (!$row_module || $force_reload || $last_update > $refresh_time) { $priorite = ''; - $modifs = 0; if (defined('_TRAD_PRIORITE_DEFAUT')) { $priorite = _TRAD_PRIORITE_DEFAUT; } @@ -136,6 +145,7 @@ function salvatore_lire($liste_sources, $force_reload = false, $dir_modules = nu 'nom_mod' => calculer_nom_module($source['module'], $source['dir_module']), 'lang_prefix' => $source['module'], 'lang_mere' => $source['lang'], + 'type_export' => $type_export, 'priorite' => $priorite, ]; $id_tradlang_module = sql_insertq('spip_tradlang_modules', $insert); @@ -144,16 +154,14 @@ function salvatore_lire($liste_sources, $force_reload = false, $dir_modules = nu */ if (!(int) $id_tradlang_module) { salvatore_fail("[Lecteur] Erreur sur $module", 'Echec insertion dans spip_tradlang_modules ' . json_encode($insert, JSON_THROW_ON_ERROR)); - } - else { + } else { salvatore_log("Insertion en base #$id_tradlang_module"); } $new_module = true; } $force_reload = true; - } - // Pas de mise a jour recente du fichier maitre deja en base - else { + } else { + // Pas de mise a jour recente du fichier maitre deja en base salvatore_log("On ne modifie rien : fichier original $fichier_lang_principal inchangé depuis " . date('Y-m-d H:i:s', $last_update)); $id_tradlang_module = (int) $row_module['id_tradlang_module']; @@ -169,8 +177,7 @@ function salvatore_lire($liste_sources, $force_reload = false, $dir_modules = nu $lang = salvatore_get_lang_from($module, $fichier_lang); if (!in_array($lang, $langues_en_base)) { $langues_a_ajouter[] = ['lang' => $lang, 'fichier' => $fichier_lang]; - } - else { + } else { // inutile de regarder ce fichier $langues_a_jour[] = $lang; } @@ -198,8 +205,7 @@ function salvatore_lire($liste_sources, $force_reload = false, $dir_modules = nu if ($tradlang_verifier_langue_base) { $tradlang_verifier_langue_base($id_tradlang_module, $lang); salvatore_log('|-- Synchro de la langue ' . $lang . ' pour le module ' . $source['module']); - } - else { + } else { salvatore_log("<error>|-- Pas de Fonction de synchro inexistante pour synchroniser lang $lang</error>"); } } @@ -241,6 +247,41 @@ function salvatore_lire($liste_sources, $force_reload = false, $dir_modules = nu } } +/** @return array{commentaires: array<string,string>, chaines: array<string,string>} */ +function salvatore_importer_module_langue_chaines(string $fichier_lang): ?array { + // type spip ou spip5 ? + $type_export = salvatore_retrouver_type_export($fichier_lang); + // charger le fichier et ses commentaires + $chaines = null; + if ($type_export === 'spip') { + $commentaires = salvatore_charger_commentaires_fichier_langue_spip($fichier_lang); + $chaines = salvatore_importer_module_langue_chaines_spip($fichier_lang); + } elseif ($type_export === 'spip5') { + $commentaires = salvatore_charger_commentaires_fichier_langue_spip5($fichier_lang); + $chaines = salvatore_importer_module_langue_chaines_spip5($fichier_lang); + } + if ($chaines === null || !is_array($chaines)) { + return null; + } + return [ + 'commentaires' => $commentaires, + 'chaines' => $chaines, + ]; +} + +function salvatore_importer_module_langue_chaines_spip(string $fichier_lang): ?array { + $idx = $GLOBALS['idx_lang'] = 'i18n_' . crc32($fichier_lang) . '_tmp'; + $GLOBALS[$idx] = null; + include $fichier_lang; + $chaines = $GLOBALS[$idx]; // on a vu certains fichiers faire des betises et modifier idx_lang + return $chaines; +} + +function salvatore_importer_module_langue_chaines_spip5(string $fichier_lang): ?array { + $chaines = include $fichier_lang; + return is_array($chaines) ? $chaines : null; +} + /** * Import d'un fichier de langue dans la base * @@ -254,28 +295,22 @@ function salvatore_lire($liste_sources, $force_reload = false, $dir_modules = nu * @param bool $new_module * true signifie qu'on est en train d'importer un nouveau module * @param array $liste_md5_master - * @return string + * @return string|false */ function salvatore_importer_module_langue($id_tradlang_module, $source, $fichier_lang, $is_master, $new_module, &$liste_md5_master) { salvatore_log("!\n+ Import de $fichier_lang\n"); - $idx = $GLOBALS['idx_lang'] = 'i18n_' . crc32($fichier_lang) . '_tmp'; - - $lang = salvatore_get_lang_from($source['module'], $fichier_lang); $module = $source['module']; + $lang = salvatore_get_lang_from($module, $fichier_lang); + $desc = salvatore_importer_module_langue_chaines($fichier_lang); - // charger le fichier et ses commentaires - $GLOBALS[$idx] = null; - $commentaires = salvatore_charger_commentaires_fichier_langue($fichier_lang); - - include $fichier_lang; - $chaines = $GLOBALS[$idx]; // on a vu certains fichiers faire des betises et modifier idx_lang - - if (is_null($chaines)) { + if ($desc === null) { $erreur = "Erreur, fichier $fichier_lang mal forme"; salvatore_log("<error>$erreur</error>"); salvatore_envoyer_mail("[Lecteur] Erreur sur $module", $erreur); return false; } + $commentaires = $desc['commentaires']; + $chaines = $desc['chaines']; /** * Nettoyer le contenu de ses <MODIF>,<NEW> et <PLUS_UTILISE> @@ -405,8 +440,7 @@ function salvatore_importer_module_langue($id_tradlang_module, $source, $fichier sql_updateq('spip_tradlangs', $maj, 'id_tradlang=' . (int) $trad['id_tradlang']); } $recuperees++; - } - else { + } else { salvatore_fail('[Lecteur] Echec insertion', 'Echec insertion en base : ' . json_encode($set, JSON_THROW_ON_ERROR)); } } @@ -487,8 +521,7 @@ function salvatore_importer_module_langue($id_tradlang_module, $source, $fichier $md5 = md5($chaines[$id]); if ($md5 === $existant[$id]) { $inchangees++; - } - else { + } else { // * modifiee ? => UPDATE salvatore_log("Chaine $id modifiee $md5 != " . $existant[$id]); @@ -559,16 +592,76 @@ function salvatore_importer_module_langue($id_tradlang_module, $source, $fichier /** - * Chargement des commentaires de fichier de langue + * Chargement des commentaires de fichier de langue SPIP >= 5 + * + * Le fichier est chargé en mode texte pour récupérer les commentaires dans lesquels sont situés les statuts + * + * @param string $fichier_lang Le chemin du fichier de langue + * @return array $liste_trad Un tableau id/chaine + */ +function salvatore_charger_commentaires_fichier_langue_spip5($fichier_lang) { + + $contenu = file_get_contents($fichier_lang); + $tokens = PhpToken::tokenize($contenu); + + $comments = []; + + // allons jusqu'au debut du tableau + while (count($tokens)) { + $token = array_shift($tokens); + if ($token->is(T_RETURN)) { + while ($token = array_shift($tokens)) { + if ($token->is(T_WHITESPACE)) { + continue; + } elseif ($token->is('[')) { + break 2; + } + break; + } + } + } + + $last_tring = ''; + $index = ''; + while (count($tokens)) { + $token = array_shift($tokens); + switch ($token->id) { + case T_CONSTANT_ENCAPSED_STRING: + $last_tring = $token->text; + break; + case T_DOUBLE_ARROW: + $index = trim($last_tring, "'\""); + break; + case T_WHITESPACE: + // si c'est une nouvelle ligne, on est plus interesse par le commentaire + if (str_contains($token->text, "\n") || str_contains($token->text, "\r")) { + $index = ''; + } + break; + case T_COMMENT: + if ($index && strpos($token->text, '#') === 0) { + $comments[$index] = trim(substr($token->text, 1)); + } + break; + } + } + + return $comments; +} + + +/** + * Chargement des commentaires de fichier de langue SPIP < 5 * Le fichier est chargé en mode texte pour récupérer les commentaires dans lesquels sont situés les statuts * * @param string $fichier_lang Le chemin du fichier de langue * @return array $liste_trad Un tableau id/chaine */ -function salvatore_charger_commentaires_fichier_langue($fichier_lang) { +function salvatore_charger_commentaires_fichier_langue_spip($fichier_lang) { $contenu = file_get_contents($fichier_lang); $tokens = token_get_all($contenu); + $comments = []; // allons jusqu'au debut du tableau