[ Index ]

PHP Cross Reference of phpBB-3.2.0-deutsch

title

Body

[close]

/phpbb/ -> finder.php (source)

   1  <?php
   2  /**
   3  *
   4  * This file is part of the phpBB Forum Software package.
   5  *
   6  * @copyright (c) phpBB Limited <https://www.phpbb.com>
   7  * @license GNU General Public License, version 2 (GPL-2.0)
   8  *
   9  * For full copyright and license information, please see
  10  * the docs/CREDITS.txt file.
  11  *
  12  */
  13  
  14  namespace phpbb;
  15  
  16  /**
  17  * The finder provides a simple way to locate files in the core and a set of extensions
  18  */
  19  class finder
  20  {
  21      protected $extensions;
  22      protected $filesystem;
  23      protected $phpbb_root_path;
  24      protected $cache;
  25      protected $php_ext;
  26  
  27      /**
  28      * The cache variable name used to store $this->cached_queries in $this->cache.
  29      *
  30      * Allows the use of multiple differently configured finders with the same cache.
  31      * @var string
  32      */
  33      protected $cache_name;
  34  
  35      /**
  36      * An associative array, containing all search parameters set in methods.
  37      * @var    array
  38      */
  39      protected $query;
  40  
  41      /**
  42      * A map from md5 hashes of serialized queries to their previously retrieved
  43      * results.
  44      * @var    array
  45      */
  46      protected $cached_queries;
  47  
  48      /**
  49      * Creates a new finder instance with its dependencies
  50      *
  51      * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem instance
  52      * @param string $phpbb_root_path Path to the phpbb root directory
  53      * @param \phpbb\cache\service $cache A cache instance or null
  54      * @param string $php_ext php file extension
  55      * @param string $cache_name The name of the cache variable, defaults to
  56      *                           _ext_finder
  57      */
  58  	public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path = '', \phpbb\cache\service $cache = null, $php_ext = 'php', $cache_name = '_ext_finder')
  59      {
  60          $this->filesystem = $filesystem;
  61          $this->phpbb_root_path = $phpbb_root_path;
  62          $this->cache = $cache;
  63          $this->php_ext = $php_ext;
  64          $this->cache_name = $cache_name;
  65  
  66          $this->query = array(
  67              'core_path' => false,
  68              'core_suffix' => false,
  69              'core_prefix' => false,
  70              'core_directory' => false,
  71              'extension_suffix' => false,
  72              'extension_prefix' => false,
  73              'extension_directory' => false,
  74          );
  75          $this->extensions = array();
  76  
  77          $this->cached_queries = ($this->cache) ? $this->cache->get($this->cache_name) : false;
  78      }
  79  
  80      /**
  81      * Set the array of extensions
  82      *
  83      * @param array $extensions        A list of extensions that should be searched aswell
  84      * @param bool $replace_list        Should the list be emptied before adding the extensions
  85      * @return \phpbb\finder This object for chaining calls
  86      */
  87  	public function set_extensions(array $extensions, $replace_list = true)
  88      {
  89          if ($replace_list)
  90          {
  91              $this->extensions = array();
  92          }
  93  
  94          foreach ($extensions as $ext_name)
  95          {
  96              $this->extensions[$ext_name] = $this->phpbb_root_path . 'ext/' . $ext_name . '/';
  97          }
  98          return $this;
  99      }
 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  }


Generated: Sun Feb 19 19:47:08 2017 Cross-referenced by PHPXref 0.7.1