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