[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
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\di; 15 16 use phpbb\filesystem\filesystem; 17 use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; 18 use Symfony\Component\Config\ConfigCache; 19 use Symfony\Component\Config\FileLocator; 20 use Symfony\Component\DependencyInjection\ContainerBuilder; 21 use Symfony\Component\DependencyInjection\Dumper\PhpDumper; 22 use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; 23 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; 24 use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; 25 use Symfony\Component\Filesystem\Exception\IOException; 26 use Symfony\Component\Finder\Finder; 27 use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; 28 29 class container_builder 30 { 31 /** 32 * @var string The environment to use. 33 */ 34 protected $environment; 35 36 /** 37 * @var string phpBB Root Path 38 */ 39 protected $phpbb_root_path; 40 41 /** 42 * @var string php file extension 43 */ 44 protected $php_ext; 45 46 /** 47 * The container under construction 48 * 49 * @var ContainerBuilder 50 */ 51 protected $container; 52 53 /** 54 * @var \phpbb\db\driver\driver_interface 55 */ 56 protected $dbal_connection = null; 57 58 /** 59 * Indicates whether extensions should be used (default to true). 60 * 61 * @var bool 62 */ 63 protected $use_extensions = true; 64 65 /** 66 * Defines a custom path to find the configuration of the container (default to $this->phpbb_root_path . 'config') 67 * 68 * @var string 69 */ 70 protected $config_path = null; 71 72 /** 73 * Indicates whether the container should be dumped to the filesystem (default to true). 74 * 75 * If DEBUG_CONTAINER is set this option is ignored and a new container is build. 76 * 77 * @var bool 78 */ 79 protected $use_cache = true; 80 81 /** 82 * Indicates if the container should be compiled automatically (default to true). 83 * 84 * @var bool 85 */ 86 protected $compile_container = true; 87 88 /** 89 * Custom parameters to inject into the container. 90 * 91 * Default to: 92 * array( 93 * 'core.root_path', $this->phpbb_root_path, 94 * 'core.php_ext', $this->php_ext, 95 * ); 96 * 97 * @var array 98 */ 99 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 $autoload_cache = new ConfigCache($this->get_autoload_filename(), defined('DEBUG')); 147 if (!$autoload_cache->isFresh()) 148 { 149 // autoload cache should be refreshed 150 $this->load_extensions(); 151 } 152 153 require($this->get_autoload_filename()); 154 } 155 156 require($config_cache->getPath()); 157 $this->container = new \phpbb_cache_container(); 158 } 159 else 160 { 161 $this->container_extensions = array(new extension\core($this->get_config_path())); 162 163 if ($this->use_extensions) 164 { 165 $this->load_extensions(); 166 } 167 168 // Inject the config 169 if ($this->config_php_file) 170 { 171 $this->container_extensions[] = new extension\config($this->config_php_file); 172 } 173 174 $this->container = $this->create_container($this->container_extensions); 175 176 // Easy collections through tags 177 $this->container->addCompilerPass(new pass\collection_pass()); 178 179 // Event listeners "phpBB style" 180 $this->container->addCompilerPass(new RegisterListenersPass('dispatcher', 'event.listener_listener', 'event.listener')); 181 182 // Event listeners "Symfony style" 183 $this->container->addCompilerPass(new RegisterListenersPass('dispatcher')); 184 185 if ($this->use_extensions) 186 { 187 $this->register_ext_compiler_pass(); 188 } 189 190 $filesystem = new filesystem(); 191 $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path()))); 192 $loader->load($this->container->getParameter('core.environment') . '/config.yml'); 193 194 $this->inject_custom_parameters(); 195 196 if ($this->compile_container) 197 { 198 $this->container->compile(); 199 200 if ($this->use_cache) 201 { 202 $this->dump_container($config_cache); 203 } 204 } 205 } 206 207 if ($this->compile_container && $this->config_php_file) 208 { 209 $this->container->set('config.php', $this->config_php_file); 210 } 211 212 $this->inject_dbal_driver(); 213 214 return $this->container; 215 } 216 catch (\Exception $e) 217 { 218 // Don't try to recover if we are in the development environment 219 if ($this->get_environment() === 'development') 220 { 221 throw $e; 222 } 223 224 if ($this->build_exception === null) 225 { 226 $this->build_exception = $e; 227 228 return $this 229 ->without_extensions() 230 ->without_cache() 231 ->with_custom_parameters(array_merge($this->custom_parameters, [ 232 'container_exception' => $e, 233 ])) 234 ->get_container(); 235 } 236 else 237 { 238 // Rethrow the original exception if it's still failing 239 throw $this->build_exception; 240 } 241 } 242 } 243 244 /** 245 * Enable the extensions. 246 * 247 * @param string $environment The environment to use 248 * @return $this 249 */ 250 public function with_environment($environment) 251 { 252 $this->environment = $environment; 253 254 return $this; 255 } 256 257 /** 258 * Enable the extensions. 259 * 260 * @return $this 261 */ 262 public function with_extensions() 263 { 264 $this->use_extensions = true; 265 266 return $this; 267 } 268 269 /** 270 * Disable the extensions. 271 * 272 * @return $this 273 */ 274 public function without_extensions() 275 { 276 $this->use_extensions = false; 277 278 return $this; 279 } 280 281 /** 282 * Enable the caching of the container. 283 * 284 * If DEBUG_CONTAINER is set this option is ignored and a new container is build. 285 * 286 * @return $this 287 */ 288 public function with_cache() 289 { 290 $this->use_cache = true; 291 292 return $this; 293 } 294 295 /** 296 * Disable the caching of the container. 297 * 298 * @return $this 299 */ 300 public function without_cache() 301 { 302 $this->use_cache = false; 303 304 return $this; 305 } 306 307 /** 308 * Set the cache directory. 309 * 310 * @param string $cache_dir The cache directory. 311 * @return $this 312 */ 313 public function with_cache_dir($cache_dir) 314 { 315 $this->cache_dir = $cache_dir; 316 317 return $this; 318 } 319 320 /** 321 * Enable the compilation of the container. 322 * 323 * @return $this 324 */ 325 public function with_compiled_container() 326 { 327 $this->compile_container = true; 328 329 return $this; 330 } 331 332 /** 333 * Disable the compilation of the container. 334 * 335 * @return $this 336 */ 337 public function without_compiled_container() 338 { 339 $this->compile_container = false; 340 341 return $this; 342 } 343 344 /** 345 * Set a custom path to find the configuration of the container. 346 * 347 * @param string $config_path 348 * @return $this 349 */ 350 public function with_config_path($config_path) 351 { 352 $this->config_path = $config_path; 353 354 return $this; 355 } 356 357 /** 358 * Set custom parameters to inject into the container. 359 * 360 * @param array $custom_parameters 361 * @return $this 362 */ 363 public function with_custom_parameters($custom_parameters) 364 { 365 $this->custom_parameters = $custom_parameters; 366 367 return $this; 368 } 369 370 /** 371 * Set custom parameters to inject into the container. 372 * 373 * @param \phpbb\config_php_file $config_php_file 374 * @return $this 375 */ 376 public function with_config(\phpbb\config_php_file $config_php_file) 377 { 378 $this->config_php_file = $config_php_file; 379 380 return $this; 381 } 382 383 /** 384 * Returns the path to the container configuration (default: root_path/config) 385 * 386 * @return string 387 */ 388 protected function get_config_path() 389 { 390 return $this->config_path ?: $this->phpbb_root_path . 'config'; 391 } 392 393 /** 394 * Returns the path to the cache directory (default: root_path/cache/environment). 395 * 396 * @return string Path to the cache directory. 397 */ 398 protected function get_cache_dir() 399 { 400 return $this->cache_dir ?: $this->phpbb_root_path . 'cache/' . $this->get_environment() . '/'; 401 } 402 403 /** 404 * Load the enabled extensions. 405 */ 406 protected function load_extensions() 407 { 408 if ($this->config_php_file !== null) 409 { 410 // Build an intermediate container to load the ext list from the database 411 $container_builder = new container_builder($this->phpbb_root_path, $this->php_ext); 412 $ext_container = $container_builder 413 ->without_cache() 414 ->without_extensions() 415 ->with_config($this->config_php_file) 416 ->with_config_path($this->get_config_path()) 417 ->with_environment('production') 418 ->without_compiled_container() 419 ->get_container() 420 ; 421 422 $ext_container->register('cache.driver', '\\phpbb\\cache\\driver\\dummy'); 423 $ext_container->compile(); 424 425 $extensions = $ext_container->get('ext.manager')->all_enabled(); 426 427 // Load each extension found 428 $autoloaders = '<?php 429 /** 430 * Loads all extensions custom auto-loaders. 431 * 432 * This file has been auto-generated 433 * by phpBB while loading the extensions. 434 */ 435 436 '; 437 foreach ($extensions as $ext_name => $path) 438 { 439 $extension_class = '\\' . str_replace('/', '\\', $ext_name) . '\\di\\extension'; 440 441 if (!class_exists($extension_class)) 442 { 443 $extension_class = '\\phpbb\\extension\\di\\extension_base'; 444 } 445 446 $this->container_extensions[] = new $extension_class($ext_name, $path); 447 448 // Load extension autoloader 449 $filename = $path . 'vendor/autoload.php'; 450 if (file_exists($filename)) 451 { 452 $autoloaders .= "require('{$filename}');\n"; 453 } 454 } 455 456 $configCache = new ConfigCache($this->get_autoload_filename(), false); 457 $configCache->write($autoloaders); 458 459 require($this->get_autoload_filename()); 460 } 461 else 462 { 463 // To load the extensions we need the database credentials. 464 // Automatically disable the extensions if we don't have them. 465 $this->use_extensions = false; 466 } 467 } 468 469 /** 470 * Dump the container to the disk. 471 * 472 * @param ConfigCache $cache The config cache 473 */ 474 protected function dump_container($cache) 475 { 476 try 477 { 478 $dumper = new PhpDumper($this->container); 479 $proxy_dumper = new ProxyDumper(); 480 $dumper->setProxyDumper($proxy_dumper); 481 482 $cached_container_dump = $dumper->dump(array( 483 'class' => 'phpbb_cache_container', 484 'base_class' => 'Symfony\\Component\\DependencyInjection\\ContainerBuilder', 485 )); 486 487 $cache->write($cached_container_dump, $this->container->getResources()); 488 } 489 catch (IOException $e) 490 { 491 // Don't fail if the cache isn't writeable 492 } 493 } 494 495 /** 496 * Create the ContainerBuilder object 497 * 498 * @param array $extensions Array of Container extension objects 499 * @return ContainerBuilder object 500 */ 501 protected function create_container(array $extensions) 502 { 503 $container = new ContainerBuilder(new ParameterBag($this->get_core_parameters())); 504 $container->setProxyInstantiator(new proxy_instantiator($this->get_cache_dir())); 505 506 $extensions_alias = array(); 507 508 foreach ($extensions as $extension) 509 { 510 $container->registerExtension($extension); 511 $extensions_alias[] = $extension->getAlias(); 512 } 513 514 $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions_alias)); 515 516 return $container; 517 } 518 519 /** 520 * Inject the customs parameters into the container 521 */ 522 protected function inject_custom_parameters() 523 { 524 foreach ($this->custom_parameters as $key => $value) 525 { 526 $this->container->setParameter($key, $value); 527 } 528 } 529 530 /** 531 * Inject the dbal connection driver into container 532 */ 533 protected function inject_dbal_driver() 534 { 535 if (empty($this->config_php_file)) 536 { 537 return; 538 } 539 540 $config_data = $this->config_php_file->get_all(); 541 if (!empty($config_data)) 542 { 543 if ($this->dbal_connection === null) 544 { 545 $dbal_driver_class = $this->config_php_file->convert_30_dbms_to_31($this->config_php_file->get('dbms')); 546 /** @var \phpbb\db\driver\driver_interface $dbal_connection */ 547 $this->dbal_connection = new $dbal_driver_class(); 548 $this->dbal_connection->sql_connect( 549 $this->config_php_file->get('dbhost'), 550 $this->config_php_file->get('dbuser'), 551 $this->config_php_file->get('dbpasswd'), 552 $this->config_php_file->get('dbname'), 553 $this->config_php_file->get('dbport'), 554 false, 555 defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK 556 ); 557 } 558 $this->container->set('dbal.conn.driver', $this->dbal_connection); 559 } 560 } 561 562 /** 563 * Returns the core parameters. 564 * 565 * @return array An array of core parameters 566 */ 567 protected function get_core_parameters() 568 { 569 return array_merge( 570 array( 571 'core.root_path' => $this->phpbb_root_path, 572 'core.php_ext' => $this->php_ext, 573 'core.environment' => $this->get_environment(), 574 'core.debug' => defined('DEBUG') ? DEBUG : false, 575 'core.cache_dir' => $this->get_cache_dir(), 576 ), 577 $this->get_env_parameters() 578 ); 579 } 580 581 /** 582 * Gets the environment parameters. 583 * 584 * Only the parameters starting with "PHPBB__" are considered. 585 * 586 * @return array An array of parameters 587 */ 588 protected function get_env_parameters() 589 { 590 $parameters = array(); 591 foreach ($_SERVER as $key => $value) 592 { 593 if (0 === strpos($key, 'PHPBB__')) 594 { 595 $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value; 596 } 597 } 598 599 return $parameters; 600 } 601 602 /** 603 * Get the filename under which the dumped container will be stored. 604 * 605 * @return string Path for dumped container 606 */ 607 protected function get_container_filename() 608 { 609 $container_params = [ 610 'phpbb_root_path' => $this->phpbb_root_path, 611 'use_extensions' => $this->use_extensions, 612 'config_path' => $this->config_path, 613 ]; 614 615 return $this->get_cache_dir() . 'container_' . md5(implode(',', $container_params)) . '.' . $this->php_ext; 616 } 617 618 /** 619 * Get the filename under which the dumped extensions autoloader will be stored. 620 * 621 * @return string Path for dumped extensions autoloader 622 */ 623 protected function get_autoload_filename() 624 { 625 $container_params = [ 626 'phpbb_root_path' => $this->phpbb_root_path, 627 'use_extensions' => $this->use_extensions, 628 'config_path' => $this->config_path, 629 ]; 630 631 return $this->get_cache_dir() . 'autoload_' . md5(implode(',', $container_params)) . '.' . $this->php_ext; 632 } 633 634 /** 635 * Return the name of the current environment. 636 * 637 * @return string 638 */ 639 protected function get_environment() 640 { 641 return $this->environment ?: PHPBB_ENVIRONMENT; 642 } 643 644 private function register_ext_compiler_pass() 645 { 646 $finder = new Finder(); 647 $finder 648 ->name('*_pass.php') 649 ->path('di/pass') 650 ->files() 651 ->ignoreDotFiles(true) 652 ->ignoreUnreadableDirs(true) 653 ->ignoreVCS(true) 654 ->followLinks() 655 ->in($this->phpbb_root_path . 'ext') 656 ; 657 658 /** @var \SplFileInfo $pass */ 659 foreach ($finder as $pass) 660 { 661 $filename = $pass->getPathname(); 662 $filename = substr($filename, 0, -strlen('.' . $pass->getExtension())); 663 $filename = str_replace(DIRECTORY_SEPARATOR, '/', $filename); 664 $className = preg_replace('#^.*ext/#', '', $filename); 665 $className = '\\' . str_replace('/', '\\', $className); 666 667 if (class_exists($className) && in_array('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface', class_implements($className), true)) 668 { 669 $this->container->addCompilerPass(new $className()); 670 } 671 } 672 } 673 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |