source: extensions/plugin_lang_analysis/include/functions.inc.php @ 28896

Last change on this file since 28896 was 28876, checked in by mistic100, 10 years ago

improve display of files list

File size: 7.8 KB
RevLine 
[23421]1<?php
2defined('PLA_PATH') or die('Hacking attempt!');
3
4/**
[28876]5 * List files of a plugin
6 * @param string $id, plugin id
7 * @return nested array of paths relative to plugin root
8 *    Keys are numeric for files or directory name
9 *    Values are file name or array of more entries
[23421]10 */
11function list_plugin_files($id, $path=null)
12{
13  if (empty($path))
14  {
15    $path = '/';
16  }
17 
18  if ($path == '/language/')
19  {
[28876]20    return null;
[23421]21  }
22 
23  if (strlen($path)-strrpos($path, '_data/') == 6)
24  {
[28876]25    return null;
[23421]26  }
27 
[23467]28  if (($handle = @opendir(PHPWG_PLUGINS_PATH.$id.$path)) === false)
[23421]29  {
[28876]30    return null;
[23421]31  }
32 
33  $data = array();
34 
35  while ($entry = readdir($handle))
36  {
37    if ($entry=='.' || $entry=='..' || $entry=='.svn' || $entry=='index.php') continue;
38   
39    if (is_dir(PHPWG_PLUGINS_PATH.$id.$path.$entry))
40    {
[28876]41      $data[$entry.'/'] = list_plugin_files($id, $path.$entry.'/');
[23421]42    }
43    else
44    {
45      $ext = strtolower(get_extension($entry));
46      if (in_array($ext, array('php', 'tpl')))
47      {
[28876]48        $data[] = $entry;
[23421]49      }
50    }
51  }
52 
53  closedir($handle);
54 
[28876]55  uksort($data, 'custom_folder_sort');
56 
57  return array_filter($data);
[23421]58}
59
60/**
[28876]61 * Merges the result of *list_plugin_files* and data from cache
62 * Needs the result of *list_plugin_languages_files* and *get_loaded_in_main* in global scope
63 *
64 * @param array &$files
65 * @param array $saved_files
66 * @return nested array of files with metadata
67 *    Keys are numeric for files or directory name
68 *    Values are file metadata (filename, is_admin, ignore, lang_files) or array of more entries
69 */
70function populate_plugin_files(&$files, $saved_files, $root='/', $is_admin=false)
71{
72  global $language_files, $default_lang_files;
73 
74  foreach ($files as $id => &$file)
75  {
76    if (is_array($file))
77    {
78      populate_plugin_files($file,
79        isset($saved_files[$id]) ? $saved_files[$id] : array(),
80        $root.$id,
81        strpos($id, 'admin') !== false || $is_admin
82        );
83    }
84    else if (isset($saved_files[ $file ]))
85    {
86      $id = $file;
87      $file = $saved_files[ $id ];
88      $file['filename'] = $id;
89      $file['lang_files'] = array_intersect($file['lang_files'], array_keys($language_files));
90    }
91    else
92    {
93      $id = $file;
94      $file = array(
95        'filename' => $id,
96        'is_admin' => strpos($id, 'admin') !== false || $is_admin,
97        'ignore' => false,
98        'lang_files' => $default_lang_files,
99        );
100    }
101  }
102  unset($file);
103}
104
105/**
106 * Sanitize the result of config form for direct usage and cache
107 * @param array &$files
108 * @return nested array of files with metadata
109 *    Keys are file name or directory name
110 *    Values are file metadata (is_admin, ignore, lang_files) or array of more entries
111 */
112function clean_files_from_config(&$files)
113{
114  foreach ($files as $id => &$file)
115  {
116    if (!isset($file['ignore']))
117    {
118      clean_files_from_config($file);
119    }
120    // security against max_input_vars overflow
121    else if (isset($file['is_admin']) && isset($file['ignore']) && isset($file['lang_files']))
122    {
123      $file['is_admin'] = get_boolean($file['is_admin']);
124      $file['ignore'] = get_boolean($file['ignore']);
125      $file['lang_files'] = array_keys(array_filter($file['lang_files'], 'get_boolean'));
126    }
127  }
128  unset($file);
129}
130
131/**
132 * Custom sort callback for files and directories
133 * Alphabetic order with files before directories
134 */
135function custom_folder_sort($a, $b)
136{
137  if (is_int($a) && is_int($b))
138  {
139    return $a-$b;
140  }
141  else if (is_string($a) && is_string($b))
142  {
143    return strnatcasecmp($a, $b);
144  }
145  else if (is_string($a) && is_int($b))
146  {
147    return 1;
148  }
149  else
150  {
151    return -1;
152  }
153}
154
155/**
[23467]156 * list language files of a plugin
157 * @param: string $id, plugin id
158 * @return: array, keys are basenames, values are paths relative to plugin root
159 */
160function list_plugin_languages_files($id)
161{
162  $path = '/language/en_UK/';
163 
164  if (($handle = @opendir(PHPWG_PLUGINS_PATH.$id.$path)) === false)
165  {
166    return array();
167  }
168 
169  $data = array();
170 
171  while ($entry = readdir($handle))
172  {
173    if ($entry=='.' || $entry=='..' || $entry=='.svn' || $entry=='index.php') continue;
174   
175    if (!is_dir(PHPWG_PLUGINS_PATH.$id.$path.$entry))
176    {
[28876]177      if (get_extension($entry) == 'php')
[23467]178      {
179        $data[ basename($entry, '.php') ] = $path.$entry;
180      }
181    }
182  }
183 
184  closedir($handle);
185 
186  return $data;
187}
188
189/**
[28876]190 * Construct the list of all used strings in the plugin files
191 * @param string $plugin
192 * @param array $files
193 * @return array multidimensional
194 */
195function analyze_files($plugin, $files, &$strings = array(), $path='')
196{
197  foreach ($files as $id => $file)
198  {
199    if (!isset($file['ignore']))
200    {
201      analyze_files($plugin, $file, $strings, $path.$id);
202    }
203    else
204    {
205      if ($file['ignore']) continue;
206
207      $file_strings = analyze_file($plugin.'/'.$path.$id);
208     
209      foreach ($file_strings as $string => $lines)
210      {
211        $strings[ $string ]['files'][ $path.$id ] = $file + array('lines' => $lines);
212      }
213    }
214  }
215 
216  return $strings;
217}
218
219/**
[23421]220 * list translated strings of a file
[23467]221 * @param: string $path, file $path relative to main plugins folder
222 * @return: array, keys are language strings, values are arrays of lines
[23421]223 */
224function analyze_file($path)
225{
226  $lines = file(PHPWG_PLUGINS_PATH.$path, FILE_IGNORE_NEW_LINES);
227 
228  $strings = array();
229 
230  foreach ($lines as $i => $line)
231  {
232    // l10n
[28862]233    if (preg_match_all('#l10n\\(\s*["\']{1}(.*?)["\']{1}\s*[,)]{1}#', $line, $matches))
[23421]234    {
235      for ($j=0; $j<count($matches[1]); ++$j)
236      {
237        $strings[ stripslashes($matches[1][$j]) ][] = $i+1;
238      }
239    }
240    // translate
[28876]241    if (preg_match_all('#\\{\\\\?["\']{1}(.*?)\\\\?["\']{1}\\|@?translate#', $line, $matches))
[23421]242    {
243      for ($j=0; $j<count($matches[1]); ++$j)
244      {
245        $strings[ stripslashes($matches[1][$j]) ][] = $i+1;
246      }
247    }
[23584]248    // translate_dec
[28876]249    if (preg_match_all('#translate_dec:\\\\?["\']{1}(.*?)\\\\?["\']{1}:\\\\?["\']{1}(.*?)\\\\?["\']{1}}#', $line, $matches))
[23584]250    {
251      for ($j=0; $j<count($matches[1]); ++$j)
252      {
253        $strings[ stripslashes($matches[1][$j]) ][] = $i+1;
254        $strings[ stripslashes($matches[2][$j]) ][] = $i+1;
255      }
256    }
[23421]257    // l10n_dec on one line
[28862]258    if (preg_match_all('#l10n_dec\\(\s*["\']{1}(.*?)["\']{1}\s*,\s*["\']{1}(.*?)["\']{1}#', $line, $matches))
[23421]259    {
260      for ($j=0; $j<count($matches[1]); ++$j)
261      {
262        $strings[ stripslashes($matches[1][$j]) ][] = $i+1;
263        $strings[ stripslashes($matches[2][$j]) ][] = $i+1;
264      }
265    }
266    // l10n_dec on two or three lines
267    else if (strpos($line, 'l10n_dec')!==false)
268    {
269      $three_lines = $lines[$i];
270      if (isset($lines[$i+1]))
271      {
272        $three_lines.= ' '.$lines[$i+1];
273        if (isset($lines[$i+2])) $three_lines.= ' '.$lines[$i+2];
274      }
275     
[28862]276      if (preg_match_all('#l10n_dec\\(\s*["\']{1}(.*?)["\']{1}\s*,\s*["\']{1}(.*?)["\']{1}#', $three_lines, $matches))
[23421]277      {
278        for ($j=0; $j<count($matches[1]); ++$j)
279        {
280          $strings[ stripslashes($matches[1][$j]) ][] = $i+1;
281          $strings[ stripslashes($matches[2][$j]) ][] = $i+1;
282        }
283      }
284    }
[26059]285    // l10n_args
[28862]286    if (preg_match_all('#get_l10n_args\\(\s*["\']{1}(.*?)["\']{1}\s*[,)]{1}#', $line, $matches))
[26059]287    {
288      for ($j=0; $j<count($matches[1]); ++$j)
289      {
290        $strings[ stripslashes($matches[1][$j]) ][] = $i+1;
291      }
292    }
[23421]293  }
294 
295  return $strings;
296}
297
298/**
[23467]299 * get language files loaded in main.inc.php
300 * @param: string $id, plugin id
301 * @return: array of file basenames
302 */
303function get_loaded_in_main($id)
304{
305  $content = file_get_contents(PHPWG_PLUGINS_PATH.$id.'/main.inc.php');
306 
307  $files = array();
308 
[28876]309  if (preg_match_all('#load_language\\(\s*["\']{1}(.*?)["\']{1}#', $content, $matches))
[23467]310  {
311    $files = $matches[1];
312  }
313 
314  return $files;
315}
316
317/**
[23421]318 * load a language file
319 */
320function load_language_file($path)
321{
322  @include($path);
323  if (!isset($lang)) return array();
324  return $lang;
[28876]325}
Note: See TracBrowser for help on using the repository browser.