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

container_builder.php

Zuletzt modifiziert: 09.10.2024, 12:52 - Dateigröße: 15.18 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\di;
 015   
 016  use phpbb\filesystem\filesystem;
 017  use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
 018  use Symfony\Component\Config\ConfigCache;
 019  use Symfony\Component\Config\FileLocator;
 020  use Symfony\Component\DependencyInjection\ContainerBuilder;
 021  use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
 022  use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
 023  use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
 024  use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
 025  use Symfony\Component\Filesystem\Exception\IOException;
 026  use Symfony\Component\Finder\Finder;
 027  use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
 028   
 029  class container_builder
 030  {
 031      /**
 032       * @var string The environment to use.
 033       */
 034      protected $environment;
 035   
 036      /**
 037       * @var string phpBB Root Path
 038       */
 039      protected $phpbb_root_path;
 040   
 041      /**
 042       * @var string php file extension
 043       */
 044      protected $php_ext;
 045   
 046      /**
 047       * The container under construction
 048       *
 049       * @var ContainerBuilder
 050       */
 051      protected $container;
 052   
 053      /**
 054       * @var \phpbb\db\driver\driver_interface
 055       */
 056      protected $dbal_connection = null;
 057   
 058      /**
 059       * Indicates whether extensions should be used (default to true).
 060       *
 061       * @var bool
 062       */
 063      protected $use_extensions = true;
 064   
 065      /**
 066       * Defines a custom path to find the configuration of the container (default to $this->phpbb_root_path . 'config')
 067       *
 068       * @var string
 069       */
 070      protected $config_path = null;
 071   
 072      /**
 073       * Indicates whether the container should be dumped to the filesystem (default to true).
 074       *
 075       * If DEBUG_CONTAINER is set this option is ignored and a new container is build.
 076       *
 077       * @var bool
 078       */
 079      protected $use_cache = true;
 080   
 081      /**
 082       * Indicates if the container should be compiled automatically (default to true).
 083       *
 084       * @var bool
 085       */
 086      protected $compile_container = true;
 087   
 088      /**
 089       * Custom parameters to inject into the container.
 090       *
 091       * Default to:
 092       *     array(
 093       *         'core.root_path', $this->phpbb_root_path,
 094       *         'core.php_ext', $this->php_ext,
 095       * );
 096       *
 097       * @var array
 098       */
 099      protected $custom_parameters = [];
 100   
 101      /**
 102       * @var \phpbb\config_php_file
 103       */
 104      protected $config_php_file;
 105   
 106      /**
 107       * @var string
 108       */
 109      protected $cache_dir;
 110   
 111      /**
 112       * @var array
 113       */
 114      private $container_extensions;
 115   
 116      /** @var \Exception */
 117      private $build_exception;
 118   
 119      /**
 120       * Constructor
 121       *
 122       * @param string $phpbb_root_path Path to the phpbb includes directory.
 123       * @param string $php_ext php file extension
 124       */
 125      public function __construct($phpbb_root_path, $php_ext)
 126      {
 127          $this->phpbb_root_path = $phpbb_root_path;
 128          $this->php_ext = $php_ext;
 129      }
 130   
 131      /**
 132       * Build and return a new Container respecting the current configuration
 133       *
 134       * @return \phpbb_cache_container|ContainerBuilder
 135       */
 136      public function get_container()
 137      {
 138          try
 139          {
 140              $container_filename = $this->get_container_filename();
 141              $config_cache = new ConfigCache($container_filename, defined('DEBUG'));
 142              if ($this->use_cache && $config_cache->isFresh())
 143              {
 144                  if ($this->use_extensions)
 145                  {
 146                      require($this->get_autoload_filename());
 147                  }
 148   
 149                  require($config_cache->getPath());
 150                  $this->container = new \phpbb_cache_container();
 151              }
 152              else
 153              {
 154                  $this->container_extensions = array(new extension\core($this->get_config_path()));
 155   
 156                  if ($this->use_extensions)
 157                  {
 158                      $this->load_extensions();
 159                  }
 160   
 161                  // Inject the config
 162                  if ($this->config_php_file)
 163                  {
 164                      $this->container_extensions[] = new extension\config($this->config_php_file);
 165                  }
 166   
 167                  $this->container = $this->create_container($this->container_extensions);
 168   
 169                  // Easy collections through tags
 170                  $this->container->addCompilerPass(new pass\collection_pass());
 171   
 172                  // Event listeners "phpBB style"
 173                  $this->container->addCompilerPass(new RegisterListenersPass('dispatcher', 'event.listener_listener', 'event.listener'));
 174   
 175                  // Event listeners "Symfony style"
 176                  $this->container->addCompilerPass(new RegisterListenersPass('dispatcher'));
 177   
 178                  if ($this->use_extensions)
 179                  {
 180                      $this->register_ext_compiler_pass();
 181                  }
 182   
 183                  $filesystem = new filesystem();
 184                  $loader     = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path())));
 185                  $loader->load($this->container->getParameter('core.environment') . '/config.yml');
 186   
 187                  $this->inject_custom_parameters();
 188   
 189                  if ($this->compile_container)
 190                  {
 191                      $this->container->compile();
 192   
 193                      if ($this->use_cache)
 194                      {
 195                          $this->dump_container($config_cache);
 196                      }
 197                  }
 198              }
 199   
 200              if ($this->compile_container && $this->config_php_file)
 201              {
 202                  $this->container->set('config.php', $this->config_php_file);
 203              }
 204   
 205              $this->inject_dbal_driver();
 206   
 207              return $this->container;
 208          }
 209          catch (\Exception $e)
 210          {
 211              // Don't try to recover if we are in the development environment
 212              if ($this->get_environment() === 'development')
 213              {
 214                  throw $e;
 215              }
 216   
 217              if ($this->build_exception === null)
 218              {
 219                  $this->build_exception = $e;
 220   
 221                  return $this
 222                      ->without_extensions()
 223                      ->without_cache()
 224                      ->with_custom_parameters(array_merge($this->custom_parameters, [
 225                          'container_exception' => $e,
 226                      ]))
 227                      ->get_container();
 228              }
 229              else
 230              {
 231                  // Rethrow the original exception if it's still failing
 232                  throw $this->build_exception;
 233              }
 234          }
 235      }
 236   
 237      /**
 238       * Enable the extensions.
 239       *
 240       * @param string $environment The environment to use
 241       * @return $this
 242       */
 243      public function with_environment($environment)
 244      {
 245          $this->environment = $environment;
 246   
 247          return $this;
 248      }
 249   
 250      /**
 251       * Enable the extensions.
 252       *
 253       * @return $this
 254       */
 255      public function with_extensions()
 256      {
 257          $this->use_extensions = true;
 258   
 259          return $this;
 260      }
 261   
 262      /**
 263       * Disable the extensions.
 264       *
 265       * @return $this
 266       */
 267      public function without_extensions()
 268      {
 269          $this->use_extensions = false;
 270   
 271          return $this;
 272      }
 273   
 274      /**
 275       * Enable the caching of the container.
 276       *
 277       * If DEBUG_CONTAINER is set this option is ignored and a new container is build.
 278       *
 279       * @return $this
 280       */
 281      public function with_cache()
 282      {
 283          $this->use_cache = true;
 284   
 285          return $this;
 286      }
 287   
 288      /**
 289       * Disable the caching of the container.
 290       *
 291       * @return $this
 292       */
 293      public function without_cache()
 294      {
 295          $this->use_cache = false;
 296   
 297          return $this;
 298      }
 299   
 300      /**
 301       * Set the cache directory.
 302       *
 303       * @param string $cache_dir The cache directory.
 304       * @return $this
 305       */
 306      public function with_cache_dir($cache_dir)
 307      {
 308          $this->cache_dir = $cache_dir;
 309   
 310          return $this;
 311      }
 312   
 313      /**
 314       * Enable the compilation of the container.
 315       *
 316       * @return $this
 317       */
 318      public function with_compiled_container()
 319      {
 320          $this->compile_container = true;
 321   
 322          return $this;
 323      }
 324   
 325      /**
 326       * Disable the compilation of the container.
 327       *
 328       * @return $this
 329       */
 330      public function without_compiled_container()
 331      {
 332          $this->compile_container = false;
 333   
 334          return $this;
 335      }
 336   
 337      /**
 338       * Set a custom path to find the configuration of the container.
 339       *
 340       * @param string $config_path
 341       * @return $this
 342       */
 343      public function with_config_path($config_path)
 344      {
 345          $this->config_path = $config_path;
 346   
 347          return $this;
 348      }
 349   
 350      /**
 351       * Set custom parameters to inject into the container.
 352       *
 353       * @param array $custom_parameters
 354       * @return $this
 355       */
 356      public function with_custom_parameters($custom_parameters)
 357      {
 358          $this->custom_parameters = $custom_parameters;
 359   
 360          return $this;
 361      }
 362   
 363      /**
 364       * Set custom parameters to inject into the container.
 365       *
 366       * @param \phpbb\config_php_file $config_php_file
 367       * @return $this
 368       */
 369      public function with_config(\phpbb\config_php_file $config_php_file)
 370      {
 371          $this->config_php_file = $config_php_file;
 372   
 373          return $this;
 374      }
 375   
 376      /**
 377       * Returns the path to the container configuration (default: root_path/config)
 378       *
 379       * @return string
 380       */
 381      protected function get_config_path()
 382      {
 383          return $this->config_path ?: $this->phpbb_root_path . 'config';
 384      }
 385   
 386      /**
 387       * Returns the path to the cache directory (default: root_path/cache/environment).
 388       *
 389       * @return string Path to the cache directory.
 390       */
 391      protected function get_cache_dir()
 392      {
 393          return $this->cache_dir ?: $this->phpbb_root_path . 'cache/' . $this->get_environment() . '/';
 394      }
 395   
 396      /**
 397       * Load the enabled extensions.
 398       */
 399      protected function load_extensions()
 400      {
 401          if ($this->config_php_file !== null)
 402          {
 403              // Build an intermediate container to load the ext list from the database
 404              $container_builder = new container_builder($this->phpbb_root_path, $this->php_ext);
 405              $ext_container = $container_builder
 406                  ->without_cache()
 407                  ->without_extensions()
 408                  ->with_config($this->config_php_file)
 409                  ->with_config_path($this->get_config_path())
 410                  ->with_environment('production')
 411                  ->without_compiled_container()
 412                  ->get_container()
 413              ;
 414   
 415              $ext_container->register('cache.driver', '\\phpbb\\cache\\driver\\dummy');
 416              $ext_container->compile();
 417   
 418              $extensions = $ext_container->get('ext.manager')->all_enabled();
 419   
 420              // Load each extension found
 421              $autoloaders = '<?php
 422  /**
 423   * Loads all extensions custom auto-loaders.
 424   *
 425   * This file has been auto-generated
 426   * by phpBB while loading the extensions.
 427   */
 428   
 429  ';
 430              foreach ($extensions as $ext_name => $path)
 431              {
 432                  $extension_class = '\\' . str_replace('/', '\\', $ext_name) . '\\di\\extension';
 433   
 434                  if (!class_exists($extension_class))
 435                  {
 436                      $extension_class = '\\phpbb\\extension\\di\\extension_base';
 437                  }
 438   
 439                  $this->container_extensions[] = new $extension_class($ext_name, $path);
 440   
 441                  // Load extension autoloader
 442                  $filename = $path . 'vendor/autoload.php';
 443                  if (file_exists($filename))
 444                  {
 445                      $autoloaders .= "require('{$filename}');\n";
 446                  }
 447              }
 448   
 449              $configCache = new ConfigCache($this->get_autoload_filename(), false);
 450              $configCache->write($autoloaders);
 451   
 452              require($this->get_autoload_filename());
 453          }
 454          else
 455          {
 456              // To load the extensions we need the database credentials.
 457              // Automatically disable the extensions if we don't have them.
 458              $this->use_extensions = false;
 459          }
 460      }
 461   
 462      /**
 463       * Dump the container to the disk.
 464       *
 465       * @param ConfigCache $cache The config cache
 466       */
 467      protected function dump_container($cache)
 468      {
 469          try
 470          {
 471              $dumper = new PhpDumper($this->container);
 472              $proxy_dumper = new ProxyDumper();
 473              $dumper->setProxyDumper($proxy_dumper);
 474   
 475              $cached_container_dump = $dumper->dump(array(
 476                  'class'      => 'phpbb_cache_container',
 477                  'base_class' => 'Symfony\\Component\\DependencyInjection\\ContainerBuilder',
 478              ));
 479   
 480              $cache->write($cached_container_dump, $this->container->getResources());
 481          }
 482          catch (IOException $e)
 483          {
 484              // Don't fail if the cache isn't writeable
 485          }
 486      }
 487   
 488      /**
 489       * Create the ContainerBuilder object
 490       *
 491       * @param array $extensions Array of Container extension objects
 492       * @return ContainerBuilder object
 493       */
 494      protected function create_container(array $extensions)
 495      {
 496          $container = new ContainerBuilder(new ParameterBag($this->get_core_parameters()));
 497          $container->setProxyInstantiator(new proxy_instantiator($this->get_cache_dir()));
 498   
 499          $extensions_alias = array();
 500   
 501          foreach ($extensions as $extension)
 502          {
 503              $container->registerExtension($extension);
 504              $extensions_alias[] = $extension->getAlias();
 505          }
 506   
 507          $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions_alias));
 508   
 509          return $container;
 510      }
 511   
 512      /**
 513       * Inject the customs parameters into the container
 514       */
 515      protected function inject_custom_parameters()
 516      {
 517          foreach ($this->custom_parameters as $key => $value)
 518          {
 519              $this->container->setParameter($key, $value);
 520          }
 521      }
 522   
 523      /**
 524       * Inject the dbal connection driver into container
 525       */
 526      protected function inject_dbal_driver()
 527      {
 528          if (empty($this->config_php_file))
 529          {
 530              return;
 531          }
 532   
 533          $config_data = $this->config_php_file->get_all();
 534          if (!empty($config_data))
 535          {
 536              if ($this->dbal_connection === null)
 537              {
 538                  $dbal_driver_class = $this->config_php_file->convert_30_dbms_to_31($this->config_php_file->get('dbms'));
 539                  /** @var \phpbb\db\driver\driver_interface $dbal_connection */
 540                  $this->dbal_connection = new $dbal_driver_class();
 541                  $this->dbal_connection->sql_connect(
 542                      $this->config_php_file->get('dbhost'),
 543                      $this->config_php_file->get('dbuser'),
 544                      $this->config_php_file->get('dbpasswd'),
 545                      $this->config_php_file->get('dbname'),
 546                      $this->config_php_file->get('dbport'),
 547                      false,
 548                      defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK
 549                  );
 550              }
 551              $this->container->set('dbal.conn.driver', $this->dbal_connection);
 552          }
 553      }
 554   
 555      /**
 556       * Returns the core parameters.
 557       *
 558       * @return array An array of core parameters
 559       */
 560      protected function get_core_parameters()
 561      {
 562          return array_merge(
 563              array(
 564                  'core.root_path'     => $this->phpbb_root_path,
 565                  'core.php_ext'       => $this->php_ext,
 566                  'core.environment'   => $this->get_environment(),
 567                  'core.debug'         => defined('DEBUG') ? DEBUG : false,
 568                  'core.cache_dir'     => $this->get_cache_dir(),
 569              ),
 570              $this->get_env_parameters()
 571          );
 572      }
 573   
 574      /**
 575       * Gets the environment parameters.
 576       *
 577       * Only the parameters starting with "PHPBB__" are considered.
 578       *
 579       * @return array An array of parameters
 580       */
 581      protected function get_env_parameters()
 582      {
 583          $parameters = array();
 584          foreach ($_SERVER as $key => $value)
 585          {
 586              if (0 === strpos($key, 'PHPBB__'))
 587              {
 588                  $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value;
 589              }
 590          }
 591   
 592          return $parameters;
 593      }
 594   
 595      /**
 596       * Get the filename under which the dumped container will be stored.
 597       *
 598       * @return string Path for dumped container
 599       */
 600      protected function get_container_filename()
 601      {
 602          $container_params = [
 603              'phpbb_root_path' => $this->phpbb_root_path,
 604              'use_extensions' => $this->use_extensions,
 605              'config_path' => $this->config_path,
 606          ];
 607   
 608          return $this->get_cache_dir() . 'container_' . md5(implode(',', $container_params)) . '.' . $this->php_ext;
 609      }
 610   
 611      /**
 612       * Get the filename under which the dumped extensions autoloader will be stored.
 613       *
 614       * @return string Path for dumped extensions autoloader
 615       */
 616      protected function get_autoload_filename()
 617      {
 618          $container_params = [
 619              'phpbb_root_path' => $this->phpbb_root_path,
 620              'use_extensions' => $this->use_extensions,
 621              'config_path' => $this->config_path,
 622          ];
 623   
 624          return $this->get_cache_dir() . 'autoload_' . md5(implode(',', $container_params)) . '.' . $this->php_ext;
 625      }
 626   
 627      /**
 628       * Return the name of the current environment.
 629       *
 630       * @return string
 631       */
 632      protected function get_environment()
 633      {
 634          return $this->environment ?: PHPBB_ENVIRONMENT;
 635      }
 636   
 637      private function register_ext_compiler_pass()
 638      {
 639          $finder = new Finder();
 640          $finder
 641              ->name('*_pass.php')
 642              ->path('di/pass')
 643              ->files()
 644              ->ignoreDotFiles(true)
 645              ->ignoreUnreadableDirs(true)
 646              ->ignoreVCS(true)
 647              ->followLinks()
 648              ->in($this->phpbb_root_path . 'ext')
 649          ;
 650   
 651          /** @var \SplFileInfo $pass */
 652          foreach ($finder as $pass)
 653          {
 654              $filename = $pass->getPathname();
 655              $filename = substr($filename, 0, -strlen('.' . $pass->getExtension()));
 656              $filename = str_replace(DIRECTORY_SEPARATOR, '/', $filename);
 657              $className = preg_replace('#^.*ext/#', '', $filename);
 658              $className = '\\' . str_replace('/', '\\', $className);
 659   
 660              if (class_exists($className) && in_array('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface', class_implements($className), true))
 661              {
 662                  $this->container->addCompilerPass(new $className());
 663              }
 664          }
 665      }
 666  }
 667