Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

finder.php

Zuletzt modifiziert: 09.10.2024, 12:51 - Dateigröße: 14.83 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb;
015   
016  /**
017  * The finder provides a simple way to locate files in the core and a set of extensions
018  */
019  class finder
020  {
021      protected $extensions;
022      protected $filesystem;
023      protected $phpbb_root_path;
024      protected $cache;
025      protected $php_ext;
026   
027      /**
028      * The cache variable name used to store $this->cached_queries in $this->cache.
029      *
030      * Allows the use of multiple differently configured finders with the same cache.
031      * @var string
032      */
033      protected $cache_name;
034   
035      /**
036      * An associative array, containing all search parameters set in methods.
037      * @var    array
038      */
039      protected $query;
040   
041      /**
042      * A map from md5 hashes of serialized queries to their previously retrieved
043      * results.
044      * @var    array
045      */
046      protected $cached_queries;
047   
048      /**
049      * Creates a new finder instance with its dependencies
050      *
051      * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem instance
052      * @param string $phpbb_root_path Path to the phpbb root directory
053      * @param \phpbb\cache\service $cache A cache instance or null
054      * @param string $php_ext php file extension
055      * @param string $cache_name The name of the cache variable, defaults to
056      *                           _ext_finder
057      */
058      public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path = '', \phpbb\cache\service $cache = null, $php_ext = 'php', $cache_name = '_ext_finder')
059      {
060          $this->filesystem = $filesystem;
061          $this->phpbb_root_path = $phpbb_root_path;
062          $this->cache = $cache;
063          $this->php_ext = $php_ext;
064          $this->cache_name = $cache_name;
065   
066          $this->query = array(
067              'core_path' => false,
068              'core_suffix' => false,
069              'core_prefix' => false,
070              'core_directory' => false,
071              'extension_suffix' => false,
072              'extension_prefix' => false,
073              'extension_directory' => false,
074          );
075          $this->extensions = array();
076   
077          $this->cached_queries = ($this->cache) ? $this->cache->get($this->cache_name) : false;
078      }
079   
080      /**
081      * Set the array of extensions
082      *
083      * @param array $extensions        A list of extensions that should be searched aswell
084      * @param bool $replace_list        Should the list be emptied before adding the extensions
085      * @return \phpbb\finder This object for chaining calls
086      */
087      public function set_extensions(array $extensions, $replace_list = true)
088      {
089          if ($replace_list)
090          {
091              $this->extensions = array();
092          }
093   
094          foreach ($extensions as $ext_name)
095          {
096              $this->extensions[$ext_name] = $this->phpbb_root_path . 'ext/' . $ext_name . '/';
097          }
098          return $this;
099      }
100   
101      /**
102      * Sets a core path to be searched in addition to extensions
103      *
104      * @param string $core_path The path relative to phpbb_root_path
105      * @return \phpbb\finder This object for chaining calls
106      */
107      public function core_path($core_path)
108      {
109          $this->query['core_path'] = $core_path;
110          return $this;
111      }
112   
113      /**
114      * Sets the suffix all files found in extensions and core must match.
115      *
116      * There is no default file extension, so to find PHP files only, you will
117      * have to specify .php as a suffix. However when using get_classes, the .php
118      * file extension is automatically added to suffixes.
119      *
120      * @param string $suffix A filename suffix
121      * @return \phpbb\finder This object for chaining calls
122      */
123      public function suffix($suffix)
124      {
125          $this->core_suffix($suffix);
126          $this->extension_suffix($suffix);
127          return $this;
128      }
129   
130      /**
131      * Sets a suffix all files found in extensions must match
132      *
133      * There is no default file extension, so to find PHP files only, you will
134      * have to specify .php as a suffix. However when using get_classes, the .php
135      * file extension is automatically added to suffixes.
136      *
137      * @param string $extension_suffix A filename suffix
138      * @return \phpbb\finder This object for chaining calls
139      */
140      public function extension_suffix($extension_suffix)
141      {
142          $this->query['extension_suffix'] = $extension_suffix;
143          return $this;
144      }
145   
146      /**
147      * Sets a suffix all files found in the core path must match
148      *
149      * There is no default file extension, so to find PHP files only, you will
150      * have to specify .php as a suffix. However when using get_classes, the .php
151      * file extension is automatically added to suffixes.
152      *
153      * @param string $core_suffix A filename suffix
154      * @return \phpbb\finder This object for chaining calls
155      */
156      public function core_suffix($core_suffix)
157      {
158          $this->query['core_suffix'] = $core_suffix;
159          return $this;
160      }
161   
162      /**
163      * Sets the prefix all files found in extensions and core must match
164      *
165      * @param string $prefix A filename prefix
166      * @return \phpbb\finder This object for chaining calls
167      */
168      public function prefix($prefix)
169      {
170          $this->core_prefix($prefix);
171          $this->extension_prefix($prefix);
172          return $this;
173      }
174   
175      /**
176      * Sets a prefix all files found in extensions must match
177      *
178      * @param string $extension_prefix A filename prefix
179      * @return \phpbb\finder This object for chaining calls
180      */
181      public function extension_prefix($extension_prefix)
182      {
183          $this->query['extension_prefix'] = $extension_prefix;
184          return $this;
185      }
186   
187      /**
188      * Sets a prefix all files found in the core path must match
189      *
190      * @param string $core_prefix A filename prefix
191      * @return \phpbb\finder This object for chaining calls
192      */
193      public function core_prefix($core_prefix)
194      {
195          $this->query['core_prefix'] = $core_prefix;
196          return $this;
197      }
198   
199      /**
200      * Sets a directory all files found in extensions and core must be contained in
201      *
202      * Automatically sets the core_directory if its value does not differ from
203      * the current directory.
204      *
205      * @param string $directory
206      * @return \phpbb\finder This object for chaining calls
207      */
208      public function directory($directory)
209      {
210          $this->core_directory($directory);
211          $this->extension_directory($directory);
212          return $this;
213      }
214   
215      /**
216      * Sets a directory all files found in extensions must be contained in
217      *
218      * @param string $extension_directory
219      * @return \phpbb\finder This object for chaining calls
220      */
221      public function extension_directory($extension_directory)
222      {
223          $this->query['extension_directory'] = $this->sanitise_directory($extension_directory);
224          return $this;
225      }
226   
227      /**
228      * Sets a directory all files found in the core path must be contained in
229      *
230      * @param string $core_directory
231      * @return \phpbb\finder This object for chaining calls
232      */
233      public function core_directory($core_directory)
234      {
235          $this->query['core_directory'] = $this->sanitise_directory($core_directory);
236          return $this;
237      }
238   
239      /**
240      * Removes occurances of /./ and makes sure path ends without trailing slash
241      *
242      * @param string $directory A directory pattern
243      * @return string A cleaned up directory pattern
244      */
245      protected function sanitise_directory($directory)
246      {
247          $directory = $this->filesystem->clean_path($directory);
248          $dir_len = strlen($directory);
249   
250          if ($dir_len > 1 && $directory[$dir_len - 1] === '/')
251          {
252              $directory = substr($directory, 0, -1);
253          }
254   
255          return $directory;
256      }
257   
258      /**
259      * Finds classes matching the configured options if they follow phpBB naming rules.
260      *
261      * The php file extension is automatically added to suffixes.
262      *
263      * Note: If a file is matched but contains a class name not following the
264      * phpBB naming rules an incorrect class name will be returned.
265      *
266      * @param bool $cache Whether the result should be cached
267      * @return array An array of found class names
268      */
269      public function get_classes($cache = true)
270      {
271          $this->query['extension_suffix'] .= '.' . $this->php_ext;
272          $this->query['core_suffix'] .= '.' . $this->php_ext;
273   
274          $files = $this->find($cache, false);
275   
276          return $this->get_classes_from_files($files);
277      }
278   
279      /**
280      * Get class names from a list of files
281      *
282      * @param array $files Array of files (from find())
283      * @return array Array of class names
284      */
285      public function get_classes_from_files($files)
286      {
287          $classes = array();
288          foreach ($files as $file => $ext_name)
289          {
290              $class = substr($file, 0, -strlen('.' . $this->php_ext));
291              if ($ext_name === '/' && preg_match('#^includes/#', $file))
292              {
293                  $class = preg_replace('#^includes/#', '', $class);
294                  $classes[] = 'phpbb_' . str_replace('/', '_', $class);
295              }
296              else
297              {
298                  $class = preg_replace('#^ext/#', '', $class);
299                  $classes[] = '\\' . str_replace('/', '\\', $class);
300              }
301          }
302          return $classes;
303      }
304   
305      /**
306      * Finds all directories matching the configured options
307      *
308      * @param bool $cache Whether the result should be cached
309      * @param bool $extension_keys Whether the result should have extension name as array key
310      * @return array An array of paths to found directories
311      */
312      public function get_directories($cache = true, $extension_keys = false)
313      {
314          return $this->find_with_root_path($cache, true, $extension_keys);
315      }
316   
317      /**
318      * Finds all files matching the configured options.
319      *
320      * @param bool $cache Whether the result should be cached
321      * @return array An array of paths to found files
322      */
323      public function get_files($cache = true)
324      {
325          return $this->find_with_root_path($cache, false);
326      }
327   
328      /**
329      * A wrapper around the general find which prepends a root path to results
330      *
331      * @param bool $cache Whether the result should be cached
332      * @param bool $is_dir Directories will be returned when true, only files
333      *                    otherwise
334      * @param bool $extension_keys If true, result will be associative array
335      *                    with extension name as key
336      * @return array An array of paths to found items
337      */
338      protected function find_with_root_path($cache = true, $is_dir = false, $extension_keys = false)
339      {
340          $items = $this->find($cache, $is_dir);
341   
342          $result = array();
343          foreach ($items as $item => $ext_name)
344          {
345              if ($extension_keys)
346              {
347                  $result[$ext_name] = $this->phpbb_root_path . $item;
348              }
349              else
350              {
351                  $result[] = $this->phpbb_root_path . $item;
352              }
353          }
354   
355          return $result;
356      }
357   
358      /**
359      * Finds all file system entries matching the configured options
360      *
361      * @param bool $cache Whether the result should be cached
362      * @param bool $is_dir Directories will be returned when true, only files
363      *                     otherwise
364      * @return array An array of paths to found items
365      */
366      public function find($cache = true, $is_dir = false)
367      {
368          $extensions = $this->extensions;
369          if ($this->query['core_path'])
370          {
371              $extensions['/'] = $this->phpbb_root_path . $this->query['core_path'];
372          }
373   
374          $files = array();
375          $file_list = $this->find_from_paths($extensions, $cache, $is_dir);
376   
377          foreach ($file_list as $file)
378          {
379              $files[$file['named_path']] = $file['ext_name'];
380          }
381   
382          return $files;
383      }
384   
385      /**
386      * Finds all file system entries matching the configured options for one
387      * specific extension
388      *
389      * @param string $extension_name Name of the extension
390      * @param string $extension_path Relative path to the extension root directory
391      * @param bool $cache Whether the result should be cached
392      * @param bool $is_dir Directories will be returned when true, only files
393      *                     otherwise
394      * @return array An array of paths to found items
395      */
396      public function find_from_extension($extension_name, $extension_path, $cache = true, $is_dir = false)
397      {
398          $extensions = array(
399              $extension_name => $extension_path,
400          );
401   
402          $files = array();
403          $file_list = $this->find_from_paths($extensions, $cache, $is_dir);
404   
405          foreach ($file_list as $file)
406          {
407              $files[$file['named_path']] = $file['ext_name'];
408          }
409   
410          return $files;
411      }
412   
413      /**
414      * Finds all file system entries matching the configured options from
415      * an array of paths
416      *
417      * @param array $extensions Array of extensions (name => full relative path)
418      * @param bool $cache Whether the result should be cached
419      * @param bool $is_dir Directories will be returned when true, only files
420      *                     otherwise
421      * @return array An array of paths to found items
422      */
423      public function find_from_paths($extensions, $cache = true, $is_dir = false)
424      {
425          $this->query['is_dir'] = $is_dir;
426          $query = md5(serialize($this->query) . serialize($extensions));
427   
428          if (!defined('DEBUG') && $cache && isset($this->cached_queries[$query]))
429          {
430              return $this->cached_queries[$query];
431          }
432   
433          $files = array();
434   
435          foreach ($extensions as $name => $path)
436          {
437              $ext_name = $name;
438   
439              if (!file_exists($path))
440              {
441                  continue;
442              }
443   
444              if ($name === '/')
445              {
446                  $location = $this->query['core_path'];
447                  $name = '';
448                  $suffix = $this->query['core_suffix'];
449                  $prefix = $this->query['core_prefix'];
450                  $directory = $this->query['core_directory'];
451              }
452              else
453              {
454                  $location = 'ext/';
455                  $name .= '/';
456                  $suffix = $this->query['extension_suffix'];
457                  $prefix = $this->query['extension_prefix'];
458                  $directory = $this->query['extension_directory'];
459              }
460   
461              // match only first directory if leading slash is given
462              if ($directory === '/')
463              {
464                  $directory_pattern = '^' . preg_quote(DIRECTORY_SEPARATOR, '#');
465              }
466              else if ($directory && $directory[0] === '/')
467              {
468                  if (!$is_dir)
469                  {
470                      $path .= substr($directory, 1);
471                  }
472                  $directory_pattern = '^' . preg_quote(str_replace('/', DIRECTORY_SEPARATOR, $directory) . DIRECTORY_SEPARATOR, '#');
473              }
474              else
475              {
476                  $directory_pattern = preg_quote(DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $directory) . DIRECTORY_SEPARATOR, '#');
477              }
478              if ($is_dir)
479              {
480                  $directory_pattern .= '$';
481              }
482              $directory_pattern = '#' . $directory_pattern . '#';
483   
484              if (is_dir($path))
485              {
486                  $iterator = new \RecursiveIteratorIterator(
487                      new \phpbb\recursive_dot_prefix_filter_iterator(
488                          new \RecursiveDirectoryIterator(
489                              $path,
490                              \FilesystemIterator::SKIP_DOTS
491                          )
492                      ),
493                      \RecursiveIteratorIterator::SELF_FIRST
494                  );
495   
496                  foreach ($iterator as $file_info)
497                  {
498                      $filename = $file_info->getFilename();
499   
500                      if ($file_info->isDir() == $is_dir)
501                      {
502                          if ($is_dir)
503                          {
504                              $relative_path = $iterator->getInnerIterator()->getSubPath() . DIRECTORY_SEPARATOR . basename($filename) . DIRECTORY_SEPARATOR;
505                              if ($relative_path[0] !== DIRECTORY_SEPARATOR)
506                              {
507                                  $relative_path = DIRECTORY_SEPARATOR . $relative_path;
508                              }
509                          }
510                          else
511                          {
512                              $relative_path = $iterator->getInnerIterator()->getSubPathname();
513                              if ($directory && $directory[0] === '/')
514                              {
515                                  $relative_path = str_replace('/', DIRECTORY_SEPARATOR, $directory) . DIRECTORY_SEPARATOR . $relative_path;
516                              }
517                              else
518                              {
519                                  $relative_path = DIRECTORY_SEPARATOR . $relative_path;
520                              }
521                          }
522   
523                          if ((!$suffix || substr($relative_path, -strlen($suffix)) === $suffix) &&
524                              (!$prefix || substr($filename, 0, strlen($prefix)) === $prefix) &&
525                              (!$directory || preg_match($directory_pattern, $relative_path)))
526                          {
527                              $files[] = array(
528                                  'named_path'    => str_replace(DIRECTORY_SEPARATOR, '/', $location . $name . substr($relative_path, 1)),
529                                  'ext_name'        => $ext_name,
530                                  'path'            => str_replace(array(DIRECTORY_SEPARATOR, $this->phpbb_root_path), array('/', ''), $file_info->getPath()) . '/',
531                                  'filename'        => $filename,
532                              );
533                          }
534                      }
535                  }
536              }
537          }
538   
539          if ($cache && $this->cache)
540          {
541              $this->cached_queries[$query] = $files;
542              $this->cache->put($this->cache_name, $this->cached_queries);
543          }
544   
545          return $files;
546      }
547  }
548