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