+ {% if CONTAINER_EXCEPTION !== false %}
+
+
+
+ {% endif %}
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index 3f64bc19f9..d710d984b7 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -26,7 +26,7 @@ function adm_page_header($page_title)
{
global $config, $user, $template;
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $SID, $_SID;
- global $phpbb_dispatcher;
+ global $phpbb_dispatcher, $phpbb_container;
if (defined('HEADER_INC'))
{
@@ -105,6 +105,8 @@ function adm_page_header($page_title)
'S_CONTENT_ENCODING' => 'UTF-8',
'S_CONTENT_FLOW_BEGIN' => ($user->lang['DIRECTION'] == 'ltr') ? 'left' : 'right',
'S_CONTENT_FLOW_END' => ($user->lang['DIRECTION'] == 'ltr') ? 'right' : 'left',
+
+ 'CONTAINER_EXCEPTION' => $phpbb_container->hasParameter('container_exception') ? $phpbb_container->getParameter('container_exception') : false,
));
// An array of http headers that phpbb will set. The following event may override these.
diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index a1e2d1ef40..4a70aafc6f 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -225,6 +225,9 @@ $lang = array_merge($lang, array(
'BACK' => 'Back',
+ 'CONTAINER_EXCEPTION' => 'phpBB encountered an error building the container due to an installed extension. For this reason, all extensions have been temporarily disabled. Please try purging your forum cache. All extensions will automatically be re-enabled once the container error is resolved. If this error continues, please visit phpBB.com for support.',
+ 'EXCEPTION' => 'Exception',
+
'COLOUR_SWATCH' => 'Web-safe colour swatch',
'CONFIG_UPDATED' => 'Configuration updated successfully.',
'CRON_LOCK_ERROR' => 'Could not obtain cron lock.',
diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php
index 8f175c966c..433847b285 100644
--- a/phpBB/phpbb/di/container_builder.php
+++ b/phpBB/phpbb/di/container_builder.php
@@ -90,7 +90,7 @@ class container_builder
*
* @var array
*/
- protected $custom_parameters = null;
+ protected $custom_parameters = [];
/**
* @var \phpbb\config_php_file
@@ -107,13 +107,16 @@ class container_builder
*/
private $container_extensions;
+ /** @var \Exception */
+ private $build_exception;
+
/**
* Constructor
*
* @param string $phpbb_root_path Path to the phpbb includes directory.
* @param string $php_ext php file extension
*/
- function __construct($phpbb_root_path, $php_ext)
+ public function __construct($phpbb_root_path, $php_ext)
{
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
@@ -126,67 +129,96 @@ class container_builder
*/
public function get_container()
{
- $container_filename = $this->get_container_filename();
- $config_cache = new ConfigCache($container_filename, defined('DEBUG'));
- if ($this->use_cache && $config_cache->isFresh())
+ try
{
- require($config_cache->getPath());
- $this->container = new \phpbb_cache_container();
- }
- else
- {
- $this->container_extensions = array(new extension\core($this->get_config_path()));
-
- if ($this->use_extensions)
+ $container_filename = $this->get_container_filename();
+ $config_cache = new ConfigCache($container_filename, defined('DEBUG'));
+ if ($this->use_cache && $config_cache->isFresh())
{
- $this->load_extensions();
+ require($config_cache->getPath());
+ $this->container = new \phpbb_cache_container();
}
-
- // Inject the config
- if ($this->config_php_file)
+ else
{
- $this->container_extensions[] = new extension\config($this->config_php_file);
- }
+ $this->container_extensions = array(new extension\core($this->get_config_path()));
- $this->container = $this->create_container($this->container_extensions);
-
- // Easy collections through tags
- $this->container->addCompilerPass(new pass\collection_pass());
-
- // Event listeners "phpBB style"
- $this->container->addCompilerPass(new RegisterListenersPass('dispatcher', 'event.listener_listener', 'event.listener'));
-
- // Event listeners "Symfony style"
- $this->container->addCompilerPass(new RegisterListenersPass('dispatcher'));
-
- if ($this->use_extensions)
- {
- $this->register_ext_compiler_pass();
- }
-
- $filesystem = new filesystem();
- $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path())));
- $loader->load($this->container->getParameter('core.environment') . '/config.yml');
-
- $this->inject_custom_parameters();
-
- if ($this->compile_container)
- {
- $this->container->compile();
-
- if ($this->use_cache)
+ if ($this->use_extensions)
{
- $this->dump_container($config_cache);
+ $this->load_extensions();
+ }
+
+ // Inject the config
+ if ($this->config_php_file)
+ {
+ $this->container_extensions[] = new extension\config($this->config_php_file);
+ }
+
+ $this->container = $this->create_container($this->container_extensions);
+
+ // Easy collections through tags
+ $this->container->addCompilerPass(new pass\collection_pass());
+
+ // Event listeners "phpBB style"
+ $this->container->addCompilerPass(new RegisterListenersPass('dispatcher', 'event.listener_listener', 'event.listener'));
+
+ // Event listeners "Symfony style"
+ $this->container->addCompilerPass(new RegisterListenersPass('dispatcher'));
+
+ if ($this->use_extensions)
+ {
+ $this->register_ext_compiler_pass();
+ }
+
+ $filesystem = new filesystem();
+ $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path())));
+ $loader->load($this->container->getParameter('core.environment') . '/config.yml');
+
+ $this->inject_custom_parameters();
+
+ if ($this->compile_container)
+ {
+ $this->container->compile();
+
+ if ($this->use_cache)
+ {
+ $this->dump_container($config_cache);
+ }
}
}
- }
- if ($this->compile_container && $this->config_php_file)
+ if ($this->compile_container && $this->config_php_file)
+ {
+ $this->container->set('config.php', $this->config_php_file);
+ }
+
+ return $this->container;
+ }
+ catch (\Exception $e)
{
- $this->container->set('config.php', $this->config_php_file);
- }
+ // Don't try to recover if we are in the development environment
+ if ($this->get_environment() === 'development')
+ {
+ throw $e;
+ }
- return $this->container;
+ if ($this->build_exception === null)
+ {
+ $this->build_exception = $e;
+
+ return $this
+ ->without_extensions()
+ ->without_cache()
+ ->with_custom_parameters(array_merge($this->custom_parameters, [
+ 'container_exception' => $e,
+ ]))
+ ->get_container();
+ }
+ else
+ {
+ // Rethrow the original exception if it's still failing
+ throw $this->build_exception;
+ }
+ }
}
/**
@@ -451,13 +483,11 @@ class container_builder
*/
protected function inject_custom_parameters()
{
- if ($this->custom_parameters !== null)
+ foreach ($this->custom_parameters as $key => $value)
{
- foreach ($this->custom_parameters as $key => $value)
- {
- $this->container->setParameter($key, $value);
- }
+ $this->container->setParameter($key, $value);
}
+
}
/**
{{ lang('CONTAINER_EXCEPTION') }}
+
{{ lang('EXCEPTION') }}{{ lang('COLON') }} {{ CONTAINER_EXCEPTION.getMessage() }}
+{{ CONTAINER_EXCEPTION.getTraceAsString() }}+