source: spip-zone/_plugins_/langonet/trunk/inc/verifier_items.php @ 92853

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

Cas 3.5
On vérifie si le raccourci est dans un module de spip par défaut (spip, public, ecrire, local) mais pas dans le module en cours de vérification, il y a de grande chance que ce soit ok mais on le notifie

Je ne sais pas si c'est le meilleur endroit pour mettre cela mais cela a le mérite de mettre les items définis dans local / spip / public / ecrire dans les items de langue définis aussi dans un autre module et non pas dans les items de langue probablement non définis

File size: 26.4 KB
Line 
1<?php
2
3if (!defined('_ECRIRE_INC_VERSION')) return;
4
5// Items de langue dans les fichiers PHP
6// déclaration d'items dans base/module.php
7if (!defined('_LANGONET_ITEM_PHP_OBJET'))
8        define("_LANGONET_ITEM_PHP_OBJET", '%=>\s*[\'"](?:([a-z0-9_]+):)([^\/ \']*)[\'"]%Sm');
9// Fontions PHP _T ou _U avec apostrophe
10if (!defined('_LANGONET_ITEM_PHP_TRADA'))
11        define("_LANGONET_ITEM_PHP_TRADA", '%_[TU]\s*[(]\s*\'(?:([a-z0-9_]+):)?([^\']*)\'\s*([^.,)]*[^)]*)%Sm');
12// Fontions PHP _T ou _U avec guillemet
13if (!defined('_LANGONET_ITEM_PHP_TRADG'))
14        define("_LANGONET_ITEM_PHP_TRADG", '%_[TU]\s*[(]\s*"(?:([a-z0-9_]+):)?([^"]*)"\s*([^.,)]*[^)]*)%Sm');
15
16// Items de langue dans les fichiers HTML
17
18// balise <:module:raccourci:> et toutes les formes admises avec paramètres et filtres
19if (!defined('_LANGONET_ITEM_HTML_BALISE'))
20        define("_LANGONET_ITEM_HTML_BALISE", "%<:(?:([a-z0-9_-]+):)?((?:[^:<>|{]+(?:<[^>]*>)?)*)([^:>]*):>%sm");
21// Fonction |singulier_ou_pluriel{arg1, arg2, nb} pour chaque argument. Le nb est indispensable pour la détection de
22// l'arg2
23if (!defined('_LANGONET_ITEM_HTML_FILTRE_PLURIEL_1'))
24        define("_LANGONET_ITEM_HTML_FILTRE_PLURIEL_1", "%\|singulier_ou_pluriel{(?:[\s]*(?:(?:#[A-Z_0-9]+{)*)(?:([a-z0-9_-]+):)?([a-z0-9_]+))([^,]*),%sm");
25if (!defined('_LANGONET_ITEM_HTML_FILTRE_PLURIEL_2'))
26        define("_LANGONET_ITEM_HTML_FILTRE_PLURIEL_2", "%\|singulier_ou_pluriel{[^,]*,(?:[\s]*(?:(?:#[A-Z_0-9]+{)*)(?:([a-z0-9_-]+):)?([a-z0-9_]+))([^,]*),%sm");
27// Fonction _T
28if (!defined('_LANGONET_ITEM_HTML_FILTRE_T'))
29        define("_LANGONET_ITEM_HTML_FILTRE_T", "%#[A-Z_0-9]+{(?:([a-z0-9_-]+):)?([a-z0-9_]+)}((?:\|\w+(?:{[^.]*})?)*)\|_T%Usm");
30
31// Items de langue dans les fichiers YAML
32if (!defined('_LANGONET_ITEM_YAML'))
33        define("_LANGONET_ITEM_YAML", ",<:(?:([a-z0-9_-]+):)?([a-z0-9_]+):>,sm");
34
35// Items de langue dans les fichiers XML
36// -- pour plugin.xml
37if (!defined('_LANGONET_ITEM_PLUGINXML'))
38        define("_LANGONET_ITEM_PLUGINXML", ",<titre>\s*(?:([a-z0-9_-]+):)?([a-z0-9_]+)\s*</titre>,ism");
39// -- pour paquet.xml
40if (!defined('_LANGONET_ITEM_PAQUETXML'))
41        define("_LANGONET_ITEM_PAQUETXML", ",titre=['\"](?:([a-z0-9_-]+):)?([a-z0-9_]+)['\"],ism");
42// -- pour les autres fichiers XML
43// TODO : comment faire marcher le fait que le tag est le même (contenu) et que les quotes aussi (attribut)
44// TODO : comment faire aussi pour ne pas capturer ces portions
45if (!defined('_LANGONET_ITEM_XML_CONTENU'))
46        define("_LANGONET_ITEM_XML_CONTENU", ",<\w+>\s*(?:<:)*(?:([a-z0-9_-]+):)([a-z0-9_]+)(?::>)*\s*</\w+>,ism");
47if (!defined('_LANGONET_ITEM_XML_ATTRIBUT'))
48        define("_LANGONET_ITEM_XML_ATTRIBUT", ",\w+=['\"](?:([a-z0-9_-]+):)([a-z0-9_]+)['\"],ism");
49
50$GLOBALS['langonet_regexp'] = array(
51        'paquet.xml' => array(_LANGONET_ITEM_PAQUETXML),
52        'plugin.xml' => array(_LANGONET_ITEM_PLUGINXML),
53        'xml' => array(
54                                _LANGONET_ITEM_XML_CONTENU,
55                                _LANGONET_ITEM_XML_ATTRIBUT
56        ),
57        'yaml' => array(_LANGONET_ITEM_YAML),
58        'html' => array(
59                                _LANGONET_ITEM_HTML_BALISE,
60                                _LANGONET_ITEM_HTML_FILTRE_PLURIEL_1,
61                                _LANGONET_ITEM_HTML_FILTRE_PLURIEL_2,
62                                _LANGONET_ITEM_HTML_FILTRE_T
63        ),
64        'php' => array(
65                                _LANGONET_ITEM_PHP_OBJET,
66                                _LANGONET_ITEM_PHP_TRADA,
67                                _LANGONET_ITEM_PHP_TRADG
68        )
69);
70
71/**
72 * Verification des items de langue non définis ou obsolètes
73 *
74 * @param string        $module         prefixe du fichier de langue
75 * @param string        $langue         index du nom de langue
76 * @param string        $ou_langue              chemin vers le fichier de langue à vérifier
77 * @param array         $ou_fichiers    tableau des racines d'arborescence à vérifier
78 * @param string        $verification   type de verification à effectuer
79 * @return array
80 */
81function inc_verifier_items($module, $langue, $ou_langue, $ou_fichiers, $verification) {
82
83        // On constitue la liste des fichiers pouvant être susceptibles de contenir des items de langue.
84        // Pour cela on boucle sur chacune des arborescences choisies.
85        // - les ultimes sous-repertoires charsets/ , lang/ , req/ sont ignorés.
86        // - seuls les fichiers php, html, xml ou yaml sont considérés.
87        $fichiers = array();
88        foreach($ou_fichiers as $_arborescence) {
89                $fichiers = array_merge(
90                                                $fichiers,
91                                                preg_files(_DIR_RACINE.$_arborescence, '(?<!/charsets|/lang|/req)(/[^/]*\.(xml|yaml|html|php))$'));
92        }
93
94        // On collecte l'ensemble des occurrences d'utilisation d'items de langue dans la liste des fichiers
95        // précédemment constituée.
96        $utilises = collecter_occurrences($fichiers);
97
98        // On sauvegarde l'index de langue global si il existe car on va le modifier pendant le traitement.
99        include_spip('inc/outiller');
100        sauvegarder_index_langue_global();
101
102        // On charge le fichier de langue a lister si il existe dans l'arborescence $chemin
103        // (evite le mecanisme standard de surcharge SPIP)
104        list($traductions, $fichier_langue) = charger_module_langue($module, $langue, $ou_langue);
105
106        // On restaure l'index de langue global si besoin
107        restaurer_index_langue_global();
108
109        // Traitement des occurrences d'erreurs et d'avertissements et constitution de la structure de résultats
110        if ($verification == 'definition') {
111                // Les chaines definies sont dans les fichiers definis par la RegExp ci-dessous
112                // Autrement dit les fichiers francais du repertoire lang/ sont la reference
113                $fichiers_langue = preg_files(_DIR_RACINE, '/lang/[^/]+_fr\.php$');
114                $resultats = reperer_items_non_definis($utilises, $module, $traductions, $fichiers_langue);
115        }
116        elseif ($traductions) {
117                $resultats = reperer_items_non_utilises($utilises, $module, $traductions);
118        }
119
120        // Compléments de la structure de résultats
121        $resultats['module'] = $module;
122        $resultats['langue'] = $fichier_langue;
123        $resultats['ou_fichier'] = $ou_fichiers;
124
125        return $resultats;
126}
127
128
129/**
130 * Cherche l'ensemble des occurrences d'utilisation d'items de langue dans la liste des fichiers fournie.
131 * Cette recherche se fait ligne par ligne, ce qui ne permet pas de trouver les items sur plusieurs lignes.
132 *
133 * @param $fichiers
134 * @return array
135 */
136function collecter_occurrences($fichiers) {
137
138        $utilises = array(
139                                        'raccourcis' => array(),
140                                        'modules' => array(),
141                                        'items' => array(),
142                                        'occurrences' => array(),
143                                        'suffixes' => array(),
144                                        'variables' => array(),
145                                        'debug' => array()
146        );
147
148        foreach ($fichiers as $_fichier) {
149                if ($contenu = file_get_contents($_fichier)) {
150                        $type_fichier = identifier_type_fichier($_fichier);
151                        if (isset($GLOBALS['langonet_regexp'][$type_fichier])) {
152                                $regexps = $GLOBALS['langonet_regexp'][$type_fichier];
153                                // On stocke aussi le fichier à scanner sous forme d'un tableau de lignes afin de rechercher
154                                // les numéros de ligne et de colonne des occurrences
155                                $lignes = file($_fichier);
156                                foreach ($regexps as $_regexp) {
157                                        if (preg_match_all($_regexp, $contenu, $matches, PREG_OFFSET_CAPTURE)) {
158                                                foreach ($matches[0] as $_cle => $_expression) {
159                                                        $occurrence[0] = $_expression[0];
160                                                        $occurrence[1] = $matches[1][$_cle][0];
161                                                        $occurrence[2] = $matches[2][$_cle][0];
162                                                        $occurrence[3] = isset($matches[3]) ? $matches[3][$_cle][0] : '';
163                                                        // Recherche de la ligne et de la colonne à partir de l'offset global de début
164                                                        // de l'expression
165                                                        list($ligne, $no_ligne, $no_colonne) = rechercher_ligne($_expression[1], $lignes);
166                                                        $occurrence[4] = $no_colonne;
167                                                        $utilises = memoriser_occurrence($utilises, $occurrence, $_fichier, $no_ligne, $ligne, $_regexp);
168                                                }
169                                        }
170                                }
171                        }
172                        else {
173                                spip_log("Ce type de fichier n'est pas scanné : $type_fichier ($_fichier)", "langonet");
174                        }
175                }
176        }
177
178        return $utilises;
179}
180
181
182/**
183 * Identifie le type de fichier dans lequel chercher les occurrences d'utilisation d'items
184 * de langue.
185 *
186 * @param string        $fichier
187 *              Chemin complet du fichier à scanner
188 *
189 * @return string
190 *              Extension du fichier parmi 'xml', 'yaml', 'html' et 'php' ou le nom du fichier de description
191 *              du plugin 'paquet.xml' ou 'plugin.xml'.
192 */
193function identifier_type_fichier($fichier) {
194        // On initialise le type avec l'extension du fichier
195        $informations = pathinfo($fichier);
196        $type = strtolower($informations['extension']);
197
198        // Pour les fichiers XML on précise si le fichier est un paquet.xml ou un plugin.xml
199        if ($type == 'xml')
200                if (($informations['basename'] == 'paquet.xml')
201                OR ($informations['basename'] == 'plugin.xml'))
202                        $type = strtolower($informations['basename']);
203
204        return $type;
205}
206
207
208function rechercher_ligne($offset, $lignes) {
209
210        $no_ligne = $no_colonne = 0;
211        $ligne = $lignes[0];
212
213        $somme_ligne = 0;
214        foreach ($lignes as $_no_ligne => $_ligne) {
215                $longueur_ligne = strlen($_ligne);
216                $somme_ligne += $longueur_ligne;
217                if ($somme_ligne > $offset) {
218                        // on a trouvé la ligne
219                        $ligne = $_ligne;
220                        $no_ligne = $_no_ligne;
221                        // il faut déterminer la colonne
222                        $no_colonne = $longueur_ligne - ($somme_ligne-$offset);
223                        break;
224                }
225        }
226
227        return array($ligne, $no_ligne, $no_colonne);
228}
229
230/**
231 * Memorise selon une structure prédéfinie chaque occurrence d'utilisation d'un item.
232 * Cette fonction analyse au passage si l'item est dynamique ou pas (_T avec $ ou concatenation).
233 *
234 * @param array         $utilisations
235 *              Tableau des occurrences d'utilisation des items de langues construit à chaque appel
236 *              de la fonction.
237 * @param array         $occurrence
238 *              Tableau définissant l'occurrence d'utilisation en cours de mémorisation. Une occurrence
239 *              est composée des index :
240 *
241 *              - 0 : le texte de l'expression matchant le pattern
242 *              - 1 : le module de langue (peut être vide)
243 *              - 2 : le raccourci de l'item de langue tel que détecté
244 *              - 3 : suite du texte du raccourci (dénote une occurrence partiellement ou totalement variable)
245 *              - 4 : numéro de colonne de l'occurrence
246 *
247 * @param string        $fichier
248 *              Fichier dont est issu l'occurrence en cours de mémorisation.
249 * @param string        $no_ligne
250 *              Numéro de ligne à laquelle l'occurrence en cours de mémorisation a été trouvée.
251 * @param string        $ligne
252 *              Ligne complète dans laquelle l'occurence en cours de mémorisation a été trouvée.
253 * @param string        $regexp
254 *      Expression régulière utilisée pour trouver l'occurrence d'utilisation en cours de
255 *              mémorisation.
256 *
257 * @return array
258 *              Le tableau des occurrences mis à jour avec l'occurrence passée en argument
259 */
260function memoriser_occurrence($utilisations, $occurrence, $fichier, $no_ligne, $ligne, $regexp) {
261        include_spip('inc/outiller');
262
263        list(, $module, $raccourci_regexp, $suite,) = $occurrence;
264        $suite = trim($suite);
265
266        $raccourci_partiellement_variable = false;
267        $raccourci_totalement_variable = false;
268
269        // Dans le cas du PHP, les expressions peuvent donner un raccourci variable dans $raccouci_regexp
270        // ou une suite qui ne correspond qu'au paramètres supplémentaires de _T ou _U.
271        // Dans ce cas, il faut nettoyer ces variables
272        if (in_array($regexp, $GLOBALS['langonet_regexp']['php'])) {
273                // Nettoyage de la variable $suite (à faire en premier)
274                $offset_virgule = strpos(trim($suite), ',');
275                if ($offset_virgule !== false) {
276                        $suite = trim(substr($suite, 0, $offset_virgule));
277                }
278                // Nettoyage de la variable $raccourci_regexp
279                if ($raccourci_regexp
280                AND preg_match('#^([a-z0-9_]*)(.*)$#im', $raccourci_regexp, $matches)) {
281                        if (!$matches[1]) {
282                                $raccourci_totalement_variable = true;
283                                $raccourci_regexp = $matches[2];
284                        }
285                        elseif ($matches[2]) {
286                                $raccourci_partiellement_variable = true;
287                                $raccourci_regexp = $matches[1];
288                                $suite = $matches[2];
289                        }
290                }
291        }
292
293        // Rechercher si l'occurrence trouvée est dynamique (existence d'un suffixe ou pas)
294        // -- on commence par traiter le cas ou le raccourci est vide car détecté comme une suite
295        if ($suite AND !$raccourci_regexp) {
296                // Cas de la nouvelle écriture variable du raccourci <:xxx:{=#ENV{yyy}}:> ou d'une variable PHP
297                // -- on rétablit le raccourci à partir de la suite qui n'en est pas une.
298                $raccourci_regexp = $suite;
299                $suite = '';
300                $raccourci_totalement_variable = true;
301        }
302        // -- on continue en détectant les suites qui sont de vrais suffixes d'un raccourci incomplet
303        if ($suite
304        AND !$raccourci_partiellement_variable
305        AND (($regexp == _LANGONET_ITEM_HTML_FILTRE_T)
306                OR ($regexp == _LANGONET_ITEM_HTML_FILTRE_PLURIEL_1)
307                OR ($regexp == _LANGONET_ITEM_HTML_FILTRE_PLURIEL_2)
308                OR in_array($regexp, $GLOBALS['langonet_regexp']['php']))       ) {
309                        // Cas HTML ou PHP dynamique
310                        $raccourci_partiellement_variable = true;
311        }
312
313        if ($raccourci_totalement_variable) {
314                // Si le raccourci est totalement variable il l'est a fortiori partiellement
315                $raccourci_partiellement_variable = true;
316        }
317
318        // TODO : vérifier si avec les traitements précédents extraire_argument est encore nécessaire
319        list($raccourci, ) = extraire_arguments($raccourci_regexp);
320        list($raccourci_unique, ) = calculer_raccourci_unique($raccourci_regexp, $utilisations['raccourcis']);
321        // TODO : si un raccourci est identique dans deux modules différents on va écraser l'index existant
322
323        $occurrence[] = $ligne;
324
325        $item = ($module ? "$module:$raccourci_unique" : $raccourci_unique);
326        $utilisations['raccourcis'][$item] = $raccourci;
327        $utilisations['modules'][$item] = $module;
328        $utilisations['items'][$item] = ($module ? "$module:$raccourci" : $raccourci);
329        $utilisations['occurrences'][$item][$fichier][$no_ligne][] = $occurrence;
330        $utilisations['suffixes'][$item] = $raccourci_partiellement_variable;
331        $utilisations['variables'][$item] = $raccourci_totalement_variable;
332
333        // Construction d'une liste plate pour debug
334        $occurrence[] = $no_ligne;
335        $utilisations['debug'][] = $occurrence;
336
337        return $utilisations;
338}
339
340
341///  gerer les args
342/// La RegExp utilisee ci-dessous est defini dans phraser_html ainsi:
343/// define('NOM_DE_BOUCLE', "[0-9]+|[-_][-_.a-zA-Z0-9]*");
344/// define('NOM_DE_CHAMP', "#((" . NOM_DE_BOUCLE . "):)?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)(\*{0,2})");
345
346/**
347 * @param string        $raccourci_regexp
348 *
349 * @return array
350 */
351function extraire_arguments($raccourci_regexp) {
352        include_spip('public/phraser_html');
353        $arguments = '';
354        if (preg_match_all('/' . NOM_DE_CHAMP . '/S', $raccourci_regexp, $matches, PREG_SET_ORDER)) {
355                foreach($matches as $_match) {
356                  $nom = strtolower($_match[4]);
357                  $raccourci_regexp = str_replace($_match[0], "@$nom@", $raccourci_regexp);
358                  $arguments[]= "$nom=" . $_match[0];
359                }
360                $arguments = '{' . join(',',$arguments) . '}';
361        }
362
363        return array($raccourci_regexp, $arguments);
364}
365
366
367/**
368 * Détection des items de langue obsolètes d'un module.
369 * Cette fonction renvoie un tableau composé des items obsolètes et des items potentiellement obsolètes.
370 *
371 * @param array         $utilisations
372 *              Tableau des occurrences d'utilisation d'items de langue dans le code de l'arborescence choisie.
373 * @param string        $module
374 *              Nom du module de langue en cours de vérification.
375 * @param array         $items_module
376 *              Liste des items de langues contenus dans le module de langue en cours de vérification. L'index est
377 *              le raccourci, la valeur la traduction brute.
378 *
379 * @return array
380 *              Tableau des items obsolètes ou potentiellement obsolètes. Ce tableau associatif possède une structure
381 *              à deux index :
382 *
383 *              - 'occurrences_non' : liste des items obsolètes;
384 *              - 'occurrences_non_mais' : liste des items a priori obsolètes pour le module vérifié mais utilisés avec un autre module;
385 *              - 'occurrences_peut-etre' : liste des items potentiellement obsolètes (contexte d'utilisation dynamique).
386 */
387function reperer_items_non_utilises($utilisations, $module, $items_module) {
388        $item_non = $item_non_mais = $item_peut_etre = array();
389
390        // On boucle sur la liste des items de langue ($items_module) du module en cours de vérification ($module).
391        // On teste chaque item pour trouver une utilisation
392        foreach ($items_module as $_raccourci => $_traduction) {
393                // Il faut absolument tester l'item complet soit module:raccourci car sinon
394                // on pourrait accepter comme ok un raccourci identique utilisé avec un autre module.
395                // Pour cela la valeur de chaque index des sous-tableaux $utilisations est l'item complet
396                // (module:raccourci).
397                $item = "$module:$_raccourci";
398                $index_variable = '';
399                if (!in_array($item, $utilisations['items'])) {
400                        // L'item est soit
401                        // 1- non utilisé avec le module en cours de vérification
402                        // 2- non utilisé avec le module en cours de vérification mais utilisé avec un autre module
403                        // 3- utilise dans un contexte variable
404
405                        // On cherche si l'item est détectable dans un contexte variable
406                        foreach($utilisations['raccourcis'] as $_cle => $_valeur) {
407                                if ($utilisations['suffixes'][$_cle]) {
408                                        if (substr($_raccourci, 0, strlen($_valeur)) == $_valeur) {
409                                                $index_variable = $_cle;
410                                                break;
411                                        }
412                                }
413                        }
414
415                        if (!$index_variable) {
416                                if ($items_suspects = array_keys($utilisations['raccourcis'], $_raccourci)) {
417                                        // Cas 2- : l'item est utilise avec un module différent que celui en cours
418                                        // de vérification ce qui peut révéler une erreur.
419                                        // On renvoie les occurrences en cause pour affichage complet en reconstruisant le
420                                        // tableau afin qu'il soit de même format que celui des items peut_etre.
421                                        $occurrences_suspectes = array_intersect_key($utilisations['occurrences'], array_flip($items_suspects));
422                                        foreach ($occurrences_suspectes as $_occurrences) {
423                                                foreach ($_occurrences as $_fichier => $_ligne) {
424                                                        foreach ($_ligne as $_no_ligne => $_occurrence) {
425                                                                if (!isset($item_non_mais[$_raccourci][$_fichier])) {
426                                                                        // Première occurrence dans ce fichier
427                                                                        $item_non_mais[$_raccourci][$_fichier] = $_ligne;
428                                                                } elseif (!isset($item_non_mais[$_raccourci][$_fichier][$_no_ligne])) {
429                                                                        // Cette ligne n'a pas encore d'occurrence
430                                                                        $item_non_mais[$_raccourci][$_fichier][$_no_ligne] = $_occurrence;
431                                                                } else {
432                                                                        // Cette ligne avait déjà une occurrence
433                                                                        $item_non_mais[$_raccourci][$_fichier][$_no_ligne] = array_merge($item_non_mais[$_raccourci][$_fichier][$_no_ligne], $_occurrence);
434                                                                }
435                                                        }
436                                                }
437                                        }
438                                } else {
439                                        // Cas 1- : on renvoie uniquement la traduction afin de l'afficher dans les résultats.
440                                        $item_non[$_raccourci][] = $_traduction;
441                                }
442                        } else {
443                                // Cas 3- : l'item est utilise dans un contexte variable, on renvoie l'occurrence complète
444                                $item_peut_etre[$_raccourci] = $utilisations['occurrences'][$index_variable];
445                        }
446                }
447        }
448
449        return array(
450                        'occurrences_non' => $item_non,
451                        'occurrences_non_mais' => $item_non_mais,
452                        'occurrences_peut_etre' => $item_peut_etre,
453                        );
454}
455
456
457/**
458 * Détection des items de langue utilises mais apparamment non definis.
459 * Cette fonction renvoie un tableau composé des items manquants et des items potentiellement manquants.
460 *
461 * @param array         $utilisations
462 *              Tableau des occurrences d'utilisation d'items de langue dans le code de l'arborescence choisie.
463 * @param string        $module
464 *              Nom du module de langue en cours de vérification.
465 * @param array         $items_module
466 *              Liste des items de langues contenus dans le module de langue en cours de vérification. L'index est
467 *              le raccourci, la valeur la traduction brute.
468 * @param array         $fichiers_langue
469 *              Liste des fichiers de langue 'fr' présent sur site et dans lesquels il est possible de trouver
470 *              certains items de langue.
471 *
472 * @return array
473 */
474function reperer_items_non_definis($utilisations, $module, $items_module=array(), $fichiers_langue=array()) {
475
476        // Constitution du tableau de tous les items de langue fr disponibles sur le site et stockage de la liste
477        // des modules scannés
478        $tous_lang = $modules_tous_lang = array();
479        foreach ($fichiers_langue as $_fichier) {
480                $module_tous_lang = preg_match(',/lang/([^/]+)_fr\.php$,i', $_fichier, $m) ? $m[1] : '';
481                foreach ($contenu = file($_fichier) as $_texte) {
482                        if (preg_match_all("#^[\s\t]*['\"]([a-z0-9_]+)['\"][\s\t]*=>(.*)$#i", $_texte, $items, PREG_SET_ORDER)) {
483                                foreach ($items as $_item) {
484                                        // $_item[1] représente le raccourci
485                                        $tous_lang[$_item[1]][] = array(0 => $_fichier, 1 => $module_tous_lang);
486                                }
487                        }
488                }
489                $modules_tous_lang[] = $module_tous_lang;
490        }
491
492        $item_non = $item_non_mais = $item_peut_etre = $item_oui_mais = $complement = array();
493        foreach ($utilisations['raccourcis'] as $_cle => $_raccourci) {
494                $module_utilise = $utilisations['modules'][$_cle];
495                // Il faut absolument tester l'item complet soit module:raccourci car sinon
496                // on pourrait vérifier un raccourci identique d'un autre module.
497                if (!isset($items_module[$_raccourci]) OR ($module_utilise != $module)) {
498                        $complement[$_raccourci] = array();
499                        if (!$utilisations['suffixes'][$_cle]) {
500                                // L'item est explicite, il n'est ni totalement variable ni suffixé par une partie variable
501                                if ($module_utilise == $module) {
502                                        // Cas 1: item forcément indefini alors que le module est bien celui en cours de vérification
503                                        // => c'est une erreur !
504                                        $item_non[$_raccourci] = $utilisations['occurrences'][$_cle];
505                                } else {
506                                        // On vérifie si le raccourci appartient au module en cours de vérification.
507                                        $raccourci_dans_module = false;
508                                        if (isset($items_module[$_raccourci])) {
509                                                $raccourci_dans_module = true;
510                                        }
511
512                                        // On vérifie si le raccourci appartient au module utilisé par l'occurrence en cours.
513                                        $module_utilise_verifiable = false;
514                                        $raccourci_dans_module_utilise = false;
515                                        if ($module_utilise != "" && in_array($module_utilise, $modules_tous_lang)) {
516                                                $module_utilise_verifiable = true;
517                                                if (array_key_exists($_raccourci, $tous_lang)) {
518                                                        foreach ($tous_lang[$_raccourci] as $_item_tous_lang) {
519                                                                // $_item_tous_lang[1] contient toujours le nom du module exact à savoir
520                                                                // pour le core spip, public ou ecrire
521                                                                if (!$_item_tous_lang[1]) continue;
522                                                                $raccourci_dans_module_utilise =
523                                                                        $module_utilise ?
524                                                                        ($_item_tous_lang[1] == $module_utilise) :
525                                                                        (($_item_tous_lang[1]=='spip') OR ($_item_tous_lang[1]=='ecrire') OR ($_item_tous_lang[1]=='public'));
526                                                                if ($raccourci_dans_module_utilise) {
527                                                                        break;
528                                                                }
529                                                        }
530                                                }
531                                        }
532
533                                        $options = array('module' => $module, 'module_utilise' => $module_utilise);
534                                        if ($raccourci_dans_module) {
535                                                // Cas 2 : le raccourci est dans le module en cours de vérification.
536                                                // On donne la priorité au module en cours de vérification. Si le raccourci fait
537                                                // partie de ce module on considère qu'il est plus probable que l'utilisation qui en
538                                                // est faite soit erronée.
539                                                // Néanmoins, si le raccourci est aussi présent dans le module utilisé par l'occurrence
540                                                // en cours de vérification on le précise car cela diminue la probabilité d'une erreur.
541                                                $item_non_mais[$_raccourci] = $utilisations['occurrences'][$_cle];
542                                                $complement[$_raccourci][0] = _T('langonet:complement_definis_non_mais_cas2', $options);
543                                                $complement[$_raccourci][1] =
544                                                        $raccourci_dans_module_utilise ?
545                                                        _T('langonet:complement_definis_non_mais_cas2_1', $options) :
546                                                        ($module_utilise_verifiable ?
547                                                                _T('langonet:complement_definis_non_mais_cas2_2', $options) :
548                                                                _T('langonet:complement_definis_non_mais_cas2_3', $options));
549                                        } else {
550                                                if ($raccourci_dans_module_utilise) {
551                                                        // Cas 3 : le raccourci est bien dans le module utilisé mais pas dans le module en cours
552                                                        // de vérification. Il y a de grande chance que ce soit ok mais on le notifie
553                                                        $item_oui_mais[$_raccourci] = $utilisations['occurrences'][$_cle];
554                                                } else {
555                                                        $item_ok = false;
556                                                        if($module_utilise == ""){
557                                                                /**
558                                                                 * Cas 3.5
559                                                                 * On vérifie si le raccourci est dans un module de spip par défaut (spip, public, ecrire, local)
560                                                                 * mais pas dans le module en cours de vérification, il y a de grande chance que ce soit ok mais on le notifie
561                                                                 */
562                                                                $modules_vides = array('local','public','spip','ecrire'); // Les modules par défaut de SPIP
563                                                                if (array_key_exists($_raccourci, $tous_lang)) {
564                                                                        foreach ($tous_lang[$_raccourci] as $_item_tous_lang) {
565                                                                                // $_item_tous_lang[1] contient toujours le nom du module exact à savoir
566                                                                                // pour le core spip, public ou ecrire
567                                                                                if (!$_item_tous_lang[1]) continue;
568                                                                                if(in_array($_item_tous_lang[1],$modules_vides)){
569                                                                                        $item_oui_mais[$_raccourci] = $utilisations['occurrences'][$_cle];
570                                                                                        $item_ok = true;
571                                                                                }
572                                                                        }
573                                                                }
574                                                        }
575                                                        if(!$item_ok){
576                                                                // Cas 4 : le raccourci n'est ni dans le module en cours de vérification, ni dans le
577                                                                // module de l'occurrence de vérification. Il est donc non défini mais on ne sait pas
578                                                                // si cela concerne le module en cours ou pas.
579       
580                                                                // Si pas normalise, c'est une auto-definition
581                                                                // Si l'index est deja pris pour un autre texte
582                                                                // (48 caracteres initiaux communs)
583                                                                // forcer un suffixe md5
584                                                                // TODO : a priori ce code devrait être obsolete
585                                                                $md5 = $_raccourci;
586                                                                if (!preg_match(',^\w+$,', $_raccourci)) {
587                                                                        if (isset($tous_lang[$_raccourci])
588                                                                        AND !preg_match("%^\s*'$_raccourci',?\s*$%", $tous_lang[$_cle][0][2])) {
589                                                                                $md5 .= '_' . md5($_raccourci);
590                                                                        }
591                                                                }
592                                                                $item_non_mais[$_raccourci] = $utilisations['occurrences'][$_cle];
593                                                                $complement[$_raccourci][0] = _T('langonet:complement_definis_non_mais_cas4', $options);
594                                                                $complement[$_raccourci][1] = $module_utilise_verifiable ? '' : _T('langonet:complement_definis_non_mais_cas4_1', $options);
595                                                        }
596                                                }
597                                        }
598                                }
599                        } else {
600                                if ($utilisations['variables'][$_cle]) {
601                                        // Cas 5 : le raccourci est totalement variable, il n'est pas possible de trouver un
602                                        // raccourci rapprochant dans le module en cours de vérification
603                                        $raccourci_variable = ltrim($_raccourci, '\'".\\');
604                                        $item_peut_etre[$raccourci_variable] = $utilisations['occurrences'][$_cle];
605                                        $complement[$raccourci_variable][0] = _T('langonet:complement_definis_peut_etre_cas5');
606                                } else {
607                                        // Cas 6 : le raccourci est partiellement variable
608                                        // => on cherche un item du module en cours de vérification qui pourrait en approcher
609                                        //    (commence par le raccourci).
610                                        $item_approchant = '';
611                                        foreach($items_module as $_item => $_traduction) {
612                                                if (substr($_item, 0, strlen($_raccourci)) == $_raccourci) {
613                                                        $item_approchant = $_item;
614                                                }
615                                        }
616                                        $item_peut_etre[$_raccourci] = $utilisations['occurrences'][$_cle];
617                                        $complement[$_raccourci][0] = _T('langonet:complement_definis_peut_etre_cas6');
618                                        $complement[$_raccourci][1] =
619                                                ($item_approchant == '') ?
620                                                _T('langonet:complement_definis_peut_etre_cas6_1', array('module' => $module)) :
621                                                _T('langonet:complement_definis_peut_etre_cas6_2', array('module' => $module, 'item' => $item_approchant));
622                                }
623                        }
624                }
625        }
626
627        return array(
628                        'occurrences_non' => $item_non,
629                        'occurrences_non_mais' => $item_non_mais,
630                        'occurrences_oui_mais' => $item_oui_mais,
631                        'occurrences_peut_etre' => $item_peut_etre,
632                        'complements' => $complement,
633                        );
634}
635
636?>
Note: See TracBrowser for help on using the repository browser.