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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
finder.php
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