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

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

Indentation

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 * Gérer les arguments
342 *
343 * La RegExp utilisee ci-dessous est defini dans phraser_html ainsi:
344 * define('NOM_DE_BOUCLE', "[0-9]+|[-_][-_.a-zA-Z0-9]*");
345 * define('NOM_DE_CHAMP', "#((" . NOM_DE_BOUCLE . "):)?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)(\*{0,2})");
346 *
347 * @param string        $raccourci_regexp
348 * @return array
349 */
350function extraire_arguments($raccourci_regexp) {
351        include_spip('public/phraser_html');
352        $arguments = '';
353        if (preg_match_all('/' . NOM_DE_CHAMP . '/S', $raccourci_regexp, $matches, PREG_SET_ORDER)) {
354                foreach($matches as $_match) {
355                        $nom = strtolower($_match[4]);
356                        $raccourci_regexp = str_replace($_match[0], "@$nom@", $raccourci_regexp);
357                        $arguments[]= "$nom=" . $_match[0];
358                }
359                $arguments = '{' . join(',',$arguments) . '}';
360        }
361
362        return array($raccourci_regexp, $arguments);
363}
364
365
366/**
367 * Détection des items de langue obsolètes d'un module.
368 * Cette fonction renvoie un tableau composé des items obsolètes et des items potentiellement obsolètes.
369 *
370 * @param array         $utilisations
371 *              Tableau des occurrences d'utilisation d'items de langue dans le code de l'arborescence choisie.
372 * @param string        $module
373 *              Nom du module de langue en cours de vérification.
374 * @param array         $items_module
375 *              Liste des items de langues contenus dans le module de langue en cours de vérification. L'index est
376 *              le raccourci, la valeur la traduction brute.
377 *
378 * @return array
379 *              Tableau des items obsolètes ou potentiellement obsolètes. Ce tableau associatif possède une structure
380 *              à deux index :
381 *
382 *              - 'occurrences_non' : liste des items obsolètes;
383 *              - 'occurrences_non_mais' : liste des items a priori obsolètes pour le module vérifié mais utilisés avec un autre module;
384 *              - 'occurrences_peut-etre' : liste des items potentiellement obsolètes (contexte d'utilisation dynamique).
385 */
386function reperer_items_non_utilises($utilisations, $module, $items_module) {
387        $item_non = $item_non_mais = $item_peut_etre = array();
388
389        // On boucle sur la liste des items de langue ($items_module) du module en cours de vérification ($module).
390        // On teste chaque item pour trouver une utilisation
391        foreach ($items_module as $_raccourci => $_traduction) {
392                // Il faut absolument tester l'item complet soit module:raccourci car sinon
393                // on pourrait accepter comme ok un raccourci identique utilisé avec un autre module.
394                // Pour cela la valeur de chaque index des sous-tableaux $utilisations est l'item complet
395                // (module:raccourci).
396                $item = "$module:$_raccourci";
397                $index_variable = '';
398                if (!in_array($item, $utilisations['items'])) {
399                        // L'item est soit
400                        // 1- non utilisé avec le module en cours de vérification
401                        // 2- non utilisé avec le module en cours de vérification mais utilisé avec un autre module
402                        // 3- utilise dans un contexte variable
403
404                        // On cherche si l'item est détectable dans un contexte variable
405                        foreach($utilisations['raccourcis'] as $_cle => $_valeur) {
406                                if ($utilisations['suffixes'][$_cle]) {
407                                        if (substr($_raccourci, 0, strlen($_valeur)) == $_valeur) {
408                                                $index_variable = $_cle;
409                                                break;
410                                        }
411                                }
412                        }
413
414                        if (!$index_variable) {
415                                if ($items_suspects = array_keys($utilisations['raccourcis'], $_raccourci)) {
416                                        // Cas 2- : l'item est utilise avec un module différent que celui en cours
417                                        // de vérification ce qui peut révéler une erreur.
418                                        // On renvoie les occurrences en cause pour affichage complet en reconstruisant le
419                                        // tableau afin qu'il soit de même format que celui des items peut_etre.
420                                        $occurrences_suspectes = array_intersect_key($utilisations['occurrences'], array_flip($items_suspects));
421                                        foreach ($occurrences_suspectes as $_occurrences) {
422                                                foreach ($_occurrences as $_fichier => $_ligne) {
423                                                        foreach ($_ligne as $_no_ligne => $_occurrence) {
424                                                                if (!isset($item_non_mais[$_raccourci][$_fichier])) {
425                                                                        // Première occurrence dans ce fichier
426                                                                        $item_non_mais[$_raccourci][$_fichier] = $_ligne;
427                                                                } elseif (!isset($item_non_mais[$_raccourci][$_fichier][$_no_ligne])) {
428                                                                        // Cette ligne n'a pas encore d'occurrence
429                                                                        $item_non_mais[$_raccourci][$_fichier][$_no_ligne] = $_occurrence;
430                                                                } else {
431                                                                        // Cette ligne avait déjà une occurrence
432                                                                        $item_non_mais[$_raccourci][$_fichier][$_no_ligne] = array_merge($item_non_mais[$_raccourci][$_fichier][$_no_ligne], $_occurrence);
433                                                                }
434                                                        }
435                                                }
436                                        }
437                                } else {
438                                        // Cas 1- : on renvoie uniquement la traduction afin de l'afficher dans les résultats.
439                                        $item_non[$_raccourci][] = $_traduction;
440                                }
441                        } else {
442                                // Cas 3- : l'item est utilise dans un contexte variable, on renvoie l'occurrence complète
443                                $item_peut_etre[$_raccourci] = $utilisations['occurrences'][$index_variable];
444                        }
445                }
446        }
447
448        return array(
449                        'occurrences_non' => $item_non,
450                        'occurrences_non_mais' => $item_non_mais,
451                        'occurrences_peut_etre' => $item_peut_etre,
452                        );
453}
454
455
456/**
457 * Détection des items de langue utilises mais apparamment non definis.
458 * Cette fonction renvoie un tableau composé des items manquants et des items potentiellement manquants.
459 *
460 * @param array         $utilisations
461 *              Tableau des occurrences d'utilisation d'items de langue dans le code de l'arborescence choisie.
462 * @param string        $module
463 *              Nom du module de langue en cours de vérification.
464 * @param array         $items_module
465 *              Liste des items de langues contenus dans le module de langue en cours de vérification. L'index est
466 *              le raccourci, la valeur la traduction brute.
467 * @param array         $fichiers_langue
468 *              Liste des fichiers de langue 'fr' présent sur site et dans lesquels il est possible de trouver
469 *              certains items de langue.
470 *
471 * @return array
472 */
473function reperer_items_non_definis($utilisations, $module, $items_module=array(), $fichiers_langue=array()) {
474
475        // Constitution du tableau de tous les items de langue fr disponibles sur le site et stockage de la liste
476        // des modules scannés
477        $tous_lang = $modules_tous_lang = array();
478        foreach ($fichiers_langue as $_fichier) {
479                $module_tous_lang = preg_match(',/lang/([^/]+)_fr\.php$,i', $_fichier, $m) ? $m[1] : '';
480                foreach ($contenu = file($_fichier) as $_texte) {
481                        if (preg_match_all("#^[\s\t]*['\"]([a-z0-9_]+)['\"][\s\t]*=>(.*)$#i", $_texte, $items, PREG_SET_ORDER)) {
482                                foreach ($items as $_item) {
483                                        // $_item[1] représente le raccourci
484                                        $tous_lang[$_item[1]][] = array(0 => $_fichier, 1 => $module_tous_lang);
485                                }
486                        }
487                }
488                $modules_tous_lang[] = $module_tous_lang;
489        }
490
491        $item_non = $item_non_mais = $item_peut_etre = $item_oui_mais = $complement = array();
492        foreach ($utilisations['raccourcis'] as $_cle => $_raccourci) {
493                $module_utilise = $utilisations['modules'][$_cle];
494                // Il faut absolument tester l'item complet soit module:raccourci car sinon
495                // on pourrait vérifier un raccourci identique d'un autre module.
496                if (!isset($items_module[$_raccourci]) OR ($module_utilise != $module)) {
497                        $complement[$_raccourci] = array();
498                        if (!$utilisations['suffixes'][$_cle]) {
499                                // L'item est explicite, il n'est ni totalement variable ni suffixé par une partie variable
500                                if ($module_utilise == $module) {
501                                        // Cas 1: item forcément indefini alors que le module est bien celui en cours de vérification
502                                        // => c'est une erreur !
503                                        $item_non[$_raccourci] = $utilisations['occurrences'][$_cle];
504                                } else {
505                                        // On vérifie si le raccourci appartient au module en cours de vérification.
506                                        $raccourci_dans_module = false;
507                                        if (isset($items_module[$_raccourci])) {
508                                                $raccourci_dans_module = true;
509                                        }
510
511                                        // On vérifie si le raccourci appartient au module utilisé par l'occurrence en cours.
512                                        $module_utilise_verifiable = false;
513                                        $raccourci_dans_module_utilise = false;
514                                        if ($module_utilise != "" && in_array($module_utilise, $modules_tous_lang)) {
515                                                $module_utilise_verifiable = true;
516                                                if (array_key_exists($_raccourci, $tous_lang)) {
517                                                        foreach ($tous_lang[$_raccourci] as $_item_tous_lang) {
518                                                                // $_item_tous_lang[1] contient toujours le nom du module exact à savoir
519                                                                // pour le core spip, public ou ecrire
520                                                                if (!$_item_tous_lang[1]) continue;
521                                                                $raccourci_dans_module_utilise =
522                                                                        $module_utilise ?
523                                                                        ($_item_tous_lang[1] == $module_utilise) :
524                                                                        (($_item_tous_lang[1]=='spip') OR ($_item_tous_lang[1]=='ecrire') OR ($_item_tous_lang[1]=='public'));
525                                                                if ($raccourci_dans_module_utilise) {
526                                                                        break;
527                                                                }
528                                                        }
529                                                }
530                                        }
531
532                                        $options = array('module' => $module, 'module_utilise' => $module_utilise);
533                                        if ($raccourci_dans_module) {
534                                                // Cas 2 : le raccourci est dans le module en cours de vérification.
535                                                // On donne la priorité au module en cours de vérification. Si le raccourci fait
536                                                // partie de ce module on considère qu'il est plus probable que l'utilisation qui en
537                                                // est faite soit erronée.
538                                                // Néanmoins, si le raccourci est aussi présent dans le module utilisé par l'occurrence
539                                                // en cours de vérification on le précise car cela diminue la probabilité d'une erreur.
540                                                $item_non_mais[$_raccourci] = $utilisations['occurrences'][$_cle];
541                                                $complement[$_raccourci][0] = _T('langonet:complement_definis_non_mais_cas2', $options);
542                                                $complement[$_raccourci][1] =
543                                                        $raccourci_dans_module_utilise ?
544                                                        _T('langonet:complement_definis_non_mais_cas2_1', $options) :
545                                                        ($module_utilise_verifiable ?
546                                                                _T('langonet:complement_definis_non_mais_cas2_2', $options) :
547                                                                _T('langonet:complement_definis_non_mais_cas2_3', $options));
548                                        } else {
549                                                if ($raccourci_dans_module_utilise) {
550                                                        // Cas 3 : le raccourci est bien dans le module utilisé mais pas dans le module en cours
551                                                        // de vérification. Il y a de grande chance que ce soit ok mais on le notifie
552                                                        $item_oui_mais[$_raccourci] = $utilisations['occurrences'][$_cle];
553                                                } else {
554                                                        $item_ok = false;
555                                                        if($module_utilise == ""){
556                                                                /**
557                                                                 * Cas 3.5
558                                                                 * On vérifie si le raccourci est dans un module de spip par défaut (spip, public, ecrire, local)
559                                                                 * mais pas dans le module en cours de vérification, il y a de grande chance que ce soit ok mais on le notifie
560                                                                 */
561                                                                $modules_vides = array('local','public','spip','ecrire'); // Les modules par défaut de SPIP
562                                                                if (array_key_exists($_raccourci, $tous_lang)) {
563                                                                        foreach ($tous_lang[$_raccourci] as $_item_tous_lang) {
564                                                                                // $_item_tous_lang[1] contient toujours le nom du module exact à savoir
565                                                                                // pour le core spip, public ou ecrire
566                                                                                if (!$_item_tous_lang[1]) continue;
567                                                                                if(in_array($_item_tous_lang[1],$modules_vides)){
568                                                                                        $item_oui_mais[$_raccourci] = $utilisations['occurrences'][$_cle];
569                                                                                        $item_ok = true;
570                                                                                }
571                                                                        }
572                                                                }
573                                                        }
574                                                        if(!$item_ok){
575                                                                // Cas 4 : le raccourci n'est ni dans le module en cours de vérification, ni dans le
576                                                                // module de l'occurrence de vérification. Il est donc non défini mais on ne sait pas
577                                                                // si cela concerne le module en cours ou pas.
578       
579                                                                // Si pas normalise, c'est une auto-definition
580                                                                // Si l'index est deja pris pour un autre texte
581                                                                // (48 caracteres initiaux communs)
582                                                                // forcer un suffixe md5
583                                                                // TODO : a priori ce code devrait être obsolete
584                                                                $md5 = $_raccourci;
585                                                                if (!preg_match(',^\w+$,', $_raccourci)) {
586                                                                        if (isset($tous_lang[$_raccourci])
587                                                                        AND !preg_match("%^\s*'$_raccourci',?\s*$%", $tous_lang[$_cle][0][2])) {
588                                                                                $md5 .= '_' . md5($_raccourci);
589                                                                        }
590                                                                }
591                                                                $item_non_mais[$_raccourci] = $utilisations['occurrences'][$_cle];
592                                                                $complement[$_raccourci][0] = _T('langonet:complement_definis_non_mais_cas4', $options);
593                                                                $complement[$_raccourci][1] = $module_utilise_verifiable ? '' : _T('langonet:complement_definis_non_mais_cas4_1', $options);
594                                                        }
595                                                }
596                                        }
597                                }
598                        } else {
599                                if ($utilisations['variables'][$_cle]) {
600                                        // Cas 5 : le raccourci est totalement variable, il n'est pas possible de trouver un
601                                        // raccourci rapprochant dans le module en cours de vérification
602                                        $raccourci_variable = ltrim($_raccourci, '\'".\\');
603                                        $item_peut_etre[$raccourci_variable] = $utilisations['occurrences'][$_cle];
604                                        $complement[$raccourci_variable][0] = _T('langonet:complement_definis_peut_etre_cas5');
605                                } else {
606                                        // Cas 6 : le raccourci est partiellement variable
607                                        // => on cherche un item du module en cours de vérification qui pourrait en approcher
608                                        //    (commence par le raccourci).
609                                        $item_approchant = '';
610                                        foreach($items_module as $_item => $_traduction) {
611                                                if (substr($_item, 0, strlen($_raccourci)) == $_raccourci) {
612                                                        $item_approchant = $_item;
613                                                }
614                                        }
615                                        $item_peut_etre[$_raccourci] = $utilisations['occurrences'][$_cle];
616                                        $complement[$_raccourci][0] = _T('langonet:complement_definis_peut_etre_cas6');
617                                        $complement[$_raccourci][1] =
618                                                ($item_approchant == '') ?
619                                                _T('langonet:complement_definis_peut_etre_cas6_1', array('module' => $module)) :
620                                                _T('langonet:complement_definis_peut_etre_cas6_2', array('module' => $module, 'item' => $item_approchant));
621                                }
622                        }
623                }
624        }
625
626        return array(
627                        'occurrences_non' => $item_non,
628                        'occurrences_non_mais' => $item_non_mais,
629                        'occurrences_oui_mais' => $item_oui_mais,
630                        'occurrences_peut_etre' => $item_peut_etre,
631                        'complements' => $complement,
632                        );
633}
634
635?>
Note: See TracBrowser for help on using the repository browser.