1 | <?php |
---|
2 | |
---|
3 | if (!defined('_ECRIRE_INC_VERSION')) return; |
---|
4 | |
---|
5 | // Les REGEXP de recherche de l'item de langue |
---|
6 | // (voir le fichier regexp.txt pour des exemples) |
---|
7 | |
---|
8 | // -- pour les fichiers .html et .php |
---|
9 | // sans detection de _L mais avec variables PHP eventuelles dans l'argument de _T |
---|
10 | define("_LANGONET_TROUVER_ITEM_HP", |
---|
11 | "#" . |
---|
12 | "(?:<:|_[TU]\(['\"])" . // designation (<: pour squelette, T|U pour PHP) |
---|
13 | "(?:([a-z0-9_]+):)?" . // nom du module eventuel |
---|
14 | "(" . "(?:\\$|[\"\']\s*\.\s*\\$*)?" . // delimiteur ' ou " pour T|U |
---|
15 | "[A-Za-z0-9@_&;,.?!\s()-]+" . // item nu, pas forcement normalise |
---|
16 | ")" . |
---|
17 | "(" . "(?:{(?:[^\|=>]*=[^\|>]*)})?" . // argument entre accolades |
---|
18 | "(?:(?:\|[^>]*)?)" . // filtre |
---|
19 | "(?:['\"]\s*\.\s*[^\s]+)?" . // delimiteur ' ou " pour T|U |
---|
20 | ")" . |
---|
21 | "#iS" |
---|
22 | ); |
---|
23 | |
---|
24 | // -- pour les fichiers .xml |
---|
25 | define("_LANGONET_TROUVER_ITEM_X", ",<[a-z0-9_]+>[\n|\t|\s]*([a-z0-9_]+):([a-z0-9_]+)[\n|\t|\s]*</[a-z0-9_]+()>,iS"); |
---|
26 | |
---|
27 | /** |
---|
28 | * Verification de l'utilisation des items de langue |
---|
29 | * |
---|
30 | * @param string $rep |
---|
31 | * @param string $module |
---|
32 | * @param string $langue |
---|
33 | * @param string $ou_langue |
---|
34 | * @param string $ou_fichier |
---|
35 | * @param string $verification |
---|
36 | * @return array |
---|
37 | */ |
---|
38 | |
---|
39 | // $rep => nom du repertoire parent de lang/ |
---|
40 | // $module => prefixe du fichier de langue |
---|
41 | // $langue => index du nom de langue |
---|
42 | // $ou_lang => chemin vers le fichier de langue a verifier |
---|
43 | // $ou_fichier => racine de l'arborescence a verifier |
---|
44 | // $verification => type de verification a effectuer |
---|
45 | function inc_langonet_verifier_items($rep, $module, $langue, $ou_langue, $ou_fichier, $verification) { |
---|
46 | |
---|
47 | // Initialisation du tableau des resultats |
---|
48 | // Si une erreur se produit lors du deroulement de la fonction, le tableau contient le libelle |
---|
49 | // de l'erreur dans $resultats['erreur']. |
---|
50 | // Sinon, cet index n'existe pas |
---|
51 | $item_md5 = $fichier_non = $resultats = array(); |
---|
52 | |
---|
53 | // On charge le fichier de langue a verifier |
---|
54 | // si il existe dans l'arborescence $ou_langue |
---|
55 | // (evite le mecanisme standard de surcharge SPIP) |
---|
56 | include_spip('inc/traduire'); |
---|
57 | include_spip('inc/langonet_verifier_l'); |
---|
58 | $var_source = "i18n_".$module."_".$langue; |
---|
59 | if (empty($GLOBALS[$var_source])) { |
---|
60 | $GLOBALS['idx_lang'] = $var_source; |
---|
61 | include(_DIR_RACINE.$ou_langue.$module.'_'.$langue.'.php'); |
---|
62 | } |
---|
63 | |
---|
64 | // On cherche l'ensemble des items utilises dans l'arborescence $ou_fichier |
---|
65 | $utilises = array('items' => array(), 'suffixes' => array(), 'modules' => array()); |
---|
66 | // On ignore les ultimes sous-repertoires charsets/ , |
---|
67 | // lang/ , req/ . On ne scanne que les fichiers php, html ou xml |
---|
68 | // (voir le fichier regexp.txt). |
---|
69 | $files = preg_files(_DIR_RACINE.$ou_fichier, '(?<!/charsets|/lang|/req)(/[^/]*\.(html|php|xml|yaml))$'); |
---|
70 | foreach ($files as $_fichier) { |
---|
71 | $re = strpos($_fichier, '.xml') ? _LANGONET_TROUVER_ITEM_X : _LANGONET_TROUVER_ITEM_HP; |
---|
72 | foreach ($contenu = file($_fichier) as $ligne => $texte) { |
---|
73 | if (preg_match_all($re, $texte, $m, PREG_SET_ORDER)) { |
---|
74 | foreach ($m as $occ) { |
---|
75 | $suffixe = preg_replace(',\s*,', '', $occ[2]); |
---|
76 | // On traite les cas particuliers ou l'item est entierement une expression ou une variable: |
---|
77 | if ((substr($suffixe, 0, 1) == "$") OR (substr($suffixe, 0, 2) == "'.") OR (substr($suffixe, 0, 2) == '".')) { |
---|
78 | $suffixe = str_replace('$', '\$', $suffixe); |
---|
79 | } else $suffixe = $occ[3]; |
---|
80 | $index = langonet_index_l($occ[2], $utilises['items']); |
---|
81 | $utilises['items'][$index] = $occ[2]; |
---|
82 | $utilises['modules'][$index] = $occ[1]; |
---|
83 | $item_tous[$index][$_fichier][$ligne][] = trim($occ[0]); |
---|
84 | // l'item est-il dynamique, hormis tableau d'arguments ou filtre ? |
---|
85 | // (si oui c'est sale et on pourra pas faire grand chose) |
---|
86 | $utilises['suffixes'][$index] = ($suffixe AND (strpos('|{', $suffixe[0] !== false))); |
---|
87 | } |
---|
88 | } |
---|
89 | } |
---|
90 | } |
---|
91 | |
---|
92 | if ($verification == 'definition') { |
---|
93 | // On construit la liste de tous les items definis |
---|
94 | // dans tous les fichiers de langue presents sur le site. |
---|
95 | // Par economie, on se limite au scan des '/lang/xxxx_fr.php' |
---|
96 | foreach (preg_files(_DIR_RACINE, '/lang/[^/]+_fr\.php$') as $_fichier) { |
---|
97 | foreach ($contenu = file($_fichier) as $ligne => $texte) { |
---|
98 | if (preg_match_all("#^[\s\t]*['\"]([a-z0-9_]+)['\"][\s\t]*=>#i", $texte, $matches)) { |
---|
99 | foreach ($matches[1] as $cet_item) { |
---|
100 | $tous_lang[$cet_item][] = $_fichier; |
---|
101 | } |
---|
102 | } |
---|
103 | } |
---|
104 | } |
---|
105 | // On construit la liste des items utilises mais non definis |
---|
106 | foreach ($utilises['items'] as $_cle => $_valeur) { |
---|
107 | if (!$GLOBALS[$var_source][$_valeur]) { |
---|
108 | if (!$utilises['suffixes'][$_cle]) { |
---|
109 | if ($utilises['modules'][$_cle] == $module) { |
---|
110 | // L'item est vraiment non defini et c'est une erreur |
---|
111 | $item_non[] = $_valeur; |
---|
112 | if (is_array($item_tous[$_cle])) { |
---|
113 | $fichier_non[$_cle] = $item_tous[$_cle]; |
---|
114 | } |
---|
115 | } |
---|
116 | else { |
---|
117 | // L'item est a priori defini dans un autre module. Le fait qu'il ne soit pas |
---|
118 | // defini dans le fichier en cours de verification n'est pas forcement une erreur. |
---|
119 | // On l'identifie donc a part |
---|
120 | $definition_ok = false; |
---|
121 | $definitions = array(); |
---|
122 | if (array_key_exists($_valeur, $tous_lang)) { |
---|
123 | $definitions = $tous_lang[$_valeur]; |
---|
124 | while ((list($_index, $_fichier) = each($definitions)) AND !$definition_ok) { |
---|
125 | preg_match(',/lang/([^/]+)_fr\.php$,i', $_fichier, $module_trouve); |
---|
126 | if ($module_trouve[1]) { |
---|
127 | if ($module_trouve[1] == $utilises['modules'][$_cle]) { |
---|
128 | $definition_ok = true; |
---|
129 | } |
---|
130 | else { |
---|
131 | $definition_ok = ((($module_trouve[1]=='spip') OR ($module_trouve[1]=='ecrire') OR ($module_trouve[1]=='public')) AND (!$utilises['modules'][$_cle])); |
---|
132 | } |
---|
133 | } |
---|
134 | } |
---|
135 | } |
---|
136 | if ($definition_ok) { |
---|
137 | $item_non_mais[] = $_valeur; |
---|
138 | if (is_array($item_tous[$_cle])) { |
---|
139 | $fichier_non_mais[$_cle] = $item_tous[$_cle]; |
---|
140 | } |
---|
141 | if ($definitions) |
---|
142 | $definition_non_mais[$_valeur] = $definitions; |
---|
143 | } |
---|
144 | else { |
---|
145 | $item_non_mais_nok[] = $_cle; |
---|
146 | if (is_array($item_tous[$_cle])) { |
---|
147 | $fichier_non_mais_nok[$_cle] = $item_tous[$_cle]; |
---|
148 | // Si pas normalise, c'est une auto-definition |
---|
149 | if (!preg_match(',^\w+$,', $_valeur)) { |
---|
150 | $item_md5[$_cle] = $_valeur; |
---|
151 | } |
---|
152 | } |
---|
153 | if ($definitions) |
---|
154 | $definition_non_mais_nok[$_cle] = $definitions; |
---|
155 | } |
---|
156 | } |
---|
157 | } |
---|
158 | else { |
---|
159 | // L'item est defini dynamiquement (i.e. a l'execution) |
---|
160 | // Il ne peut etre trouve directement dans le fichier de |
---|
161 | // langue, donc on verifie que des items ressemblant |
---|
162 | // existent dans le fichier de langue |
---|
163 | $item_trouve = false; |
---|
164 | foreach($GLOBALS[$var_source] as $_item => $_traduction) { |
---|
165 | if (substr($_item, 0, strlen($_valeur)) == $_valeur) { |
---|
166 | $item_peut_etre[] = $_valeur; |
---|
167 | if (is_array($item_tous[$_cle])) { |
---|
168 | $fichier_peut_etre[$_item] = $item_tous[$_cle]; |
---|
169 | } |
---|
170 | $item_trouve = true; |
---|
171 | } |
---|
172 | } |
---|
173 | // Si on a pas trouve d'item pouvant correspondre c'est peut-etre que |
---|
174 | // cet item est en fait une variable ou une expression. |
---|
175 | // On ajoute ces cas aussi aux incertains (pas essentiel) |
---|
176 | if (!$item_trouve) { |
---|
177 | $_item = ltrim($_valeur, '\'".\\'); |
---|
178 | $item_peut_etre[] = $_item; |
---|
179 | if (is_array($item_tous[$_cle])) { |
---|
180 | $fichier_peut_etre[$_item] = $item_tous[$_cle]; |
---|
181 | } |
---|
182 | } |
---|
183 | } |
---|
184 | } |
---|
185 | } |
---|
186 | } |
---|
187 | else { |
---|
188 | // On construit la liste des items definis mais plus utilises |
---|
189 | if ($GLOBALS[$var_source]) { |
---|
190 | foreach ($GLOBALS[$var_source] as $_item => $_traduction) { |
---|
191 | if (!in_array ($_item, $utilises['items'])) { |
---|
192 | // L'item est soit non utilise, soit utilise dans un contexte variable |
---|
193 | $contexte_variable = false; |
---|
194 | foreach($utilises['items'] as $_cle => $_valeur) { |
---|
195 | if ($utilises['suffixes'][$_cle]) { |
---|
196 | if (substr($_item, 0, strlen($_valeur)) == $_valeur) { |
---|
197 | $contexte_variable = true; |
---|
198 | break; |
---|
199 | } |
---|
200 | } |
---|
201 | } |
---|
202 | if (!$contexte_variable) { |
---|
203 | // L'item est vraiment non utilise |
---|
204 | $item_non[] = $_item; |
---|
205 | } |
---|
206 | else { |
---|
207 | // L'item est utilise dans un contexte variable |
---|
208 | $item_peut_etre[] = $_item; |
---|
209 | if (is_array($item_tous[$_valeur])) { |
---|
210 | $fichier_peut_etre[$_item] = $item_tous[$_valeur]; |
---|
211 | } |
---|
212 | } |
---|
213 | } |
---|
214 | } |
---|
215 | } |
---|
216 | } |
---|
217 | |
---|
218 | // On prepare le tableau des resultats |
---|
219 | $resultats['module'] = $module; |
---|
220 | $resultats['ou_fichier'] = $ou_fichier; |
---|
221 | $resultats['langue'] = $ou_langue.$module.'_'.$langue.'.php'; |
---|
222 | $resultats['item_non'] = $item_non; |
---|
223 | $resultats['item_non_mais'] = $item_non_mais; |
---|
224 | $resultats['item_non_mais_nok'] = $item_non_mais_nok; |
---|
225 | $resultats['fichier_non'] = $fichier_non; |
---|
226 | $resultats['fichier_non_mais'] = $fichier_non_mais; |
---|
227 | $resultats['fichier_non_mais_nok'] = $fichier_non_mais_nok; |
---|
228 | $resultats['definition_non_mais'] = $definition_non_mais; |
---|
229 | $resultats['definition_non_mais_nok'] = $definition_non_mais_nok; |
---|
230 | $resultats['item_peut_etre'] = $item_peut_etre; |
---|
231 | $resultats['fichier_peut_etre'] = $fichier_peut_etre; |
---|
232 | $resultats['item_md5'] = $item_md5; |
---|
233 | |
---|
234 | return $resultats; |
---|
235 | } |
---|
236 | |
---|
237 | ?> |
---|