diff --git a/phpBB/config/default/container/services.yml b/phpBB/config/default/container/services.yml index 9e2af7df23..29774211ff 100644 --- a/phpBB/config/default/container/services.yml +++ b/phpBB/config/default/container/services.yml @@ -116,6 +116,7 @@ services: - '@dbal.conn' - '@config' - '@filesystem' + - '@router' - '%tables.ext%' - '%core.root_path%' - '%core.php_ext%' diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 1ce8425fff..09de7950c4 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -30,9 +30,11 @@ class manager protected $cache; protected $php_ext; protected $extensions; + protected $recently_changed_ext_status; protected $extension_table; protected $phpbb_root_path; protected $cache_name; + protected $router; /** * Creates a manager and loads information from database @@ -47,7 +49,7 @@ class manager * @param \phpbb\cache\service $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\service $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\routing\router $router, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\service $cache = null, $cache_name = '_ext') { $this->cache = $cache; $this->cache_name = $cache_name; @@ -56,6 +58,7 @@ class manager $this->db = $db; $this->extension_table = $extension_table; $this->filesystem = $filesystem; + $this->router = $router; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; @@ -238,6 +241,12 @@ class manager 'ext_state' => serialize($state), ); + if ($active) + { + $this->recently_changed_ext_status[$name] = false; + $this->router->without_cache(); + } + $this->update_state($name, $extension_data, $this->is_configured($name) ? 'update' : 'insert'); if ($active) @@ -287,6 +296,12 @@ class manager $state = $extension->disable_step($old_state); $active = ($state !== false); + if (!$active) + { + $this->recently_changed_ext_status[$name] = true; + $this->router->without_cache(); + } + $extension_data = array( 'ext_active' => $active, 'ext_state' => serialize($state), @@ -499,6 +514,13 @@ class manager */ public function is_enabled($name) { + // The extension has just been enabled and so is not loaded. When asking if it is enabled or + // not we should answer no to stay consistent with the status at the beginning of the request. + if (isset($this->recently_changed_ext_status[$name])) + { + return $this->recently_changed_ext_status[$name]; + } + return isset($this->extensions[$name]['ext_active']) && $this->extensions[$name]['ext_active']; } @@ -510,6 +532,13 @@ class manager */ public function is_disabled($name) { + // The extension has just been disabled and so is still loaded. When asking if it is disabled or + // not we should answer yes to stay consistent with the status at the beginning of the request. + if (isset($this->recently_changed_ext_status[$name])) + { + return $this->recently_changed_ext_status[$name]; + } + return isset($this->extensions[$name]['ext_active']) && !$this->extensions[$name]['ext_active']; } diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index f19886fb0b..45c1aadcf8 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -80,6 +80,11 @@ class router implements RouterInterface */ protected $cache_dir; + /** + * @var bool + */ + protected $use_cache; + /** * Construct method * @@ -97,6 +102,7 @@ class router implements RouterInterface $this->php_ext = $php_ext; $this->context = new RequestContext(); $this->cache_dir = $cache_dir; + $this->use_cache = true; } /** @@ -176,6 +182,22 @@ class router implements RouterInterface return $this->get_matcher()->match($pathinfo); } + /** + * Enables the use of a cached URL generator and matcher + */ + public function with_cache() + { + $this->use_cache = true; + } + + /** + * Disables the use of a cached URL generator and matcher + */ + public function without_cache() + { + $this->use_cache = false; + } + /** * Gets the UrlMatcher instance associated with this Router. * @@ -198,6 +220,12 @@ class router implements RouterInterface */ protected function create_dumped_url_matcher() { + if (!$this->use_cache) + { + $this->create_new_url_matcher(); + return; + } + try { $cache = new ConfigCache("{$this->cache_dir}url_matcher.{$this->php_ext}", defined('DEBUG')); @@ -253,6 +281,12 @@ class router implements RouterInterface */ protected function create_dumped_url_generator() { + if (!$this->use_cache) + { + $this->create_new_url_generator(); + return; + } + try { $cache = new ConfigCache("{$this->cache_dir}url_generator.{$this->php_ext}", defined('DEBUG')); diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index df0c2506ed..a383ec3ab0 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -80,6 +80,7 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->db, $this->config, new phpbb\filesystem\filesystem(), + new phpbb_mock_dummy_router(), 'phpbb_ext', __DIR__ . '/../../phpBB/', 'php', diff --git a/tests/extension/manager_test.php b/tests/extension/manager_test.php index 1675c27ede..bb615d7ac4 100644 --- a/tests/extension/manager_test.php +++ b/tests/extension/manager_test.php @@ -30,6 +30,7 @@ class phpbb_extension_manager_test extends phpbb_database_test_case { parent::setUp(); + $this->db = null; $this->extension_manager = $this->create_extension_manager(); } @@ -95,7 +96,12 @@ class phpbb_extension_manager_test extends phpbb_database_test_case $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); $this->extension_manager->enable('vendor2/bar'); - $this->assertEquals(array('vendor2/bar', 'vendor2/foo'), array_keys($this->extension_manager->all_enabled())); + + // We should not display the extension as being enabled in the same request + $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); + // With a different request we should see the extension as being disabled + $this->assertEquals(array('vendor2/bar', 'vendor2/foo'), array_keys($this->create_extension_manager()->all_enabled())); + $this->assertEquals(array('vendor/moo', 'vendor2/bar', 'vendor2/foo'), array_keys($this->extension_manager->all_configured())); $this->assertEquals(4, vendor2\bar\ext::$state); @@ -119,7 +125,12 @@ class phpbb_extension_manager_test extends phpbb_database_test_case $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); $this->extension_manager->disable('vendor2/foo'); - $this->assertEquals(array(), array_keys($this->extension_manager->all_enabled())); + + // We should still display the extension as being enabled in the current request + $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); + // With a different request we should see the extension as being disabled + $this->assertEquals(array(), array_keys($this->create_extension_manager()->all_enabled())); + $this->assertEquals(array('vendor/moo', 'vendor2/foo'), array_keys($this->extension_manager->all_configured())); $this->assertTrue(vendor2\foo\ext::$disabled); @@ -147,7 +158,6 @@ class phpbb_extension_manager_test extends phpbb_database_test_case protected function create_extension_manager($with_cache = true) { - $config = new \phpbb\config\config(array('version' => PHPBB_VERSION)); $db = $this->new_dbal(); $factory = new \phpbb\db\tools\factory(); @@ -177,6 +187,7 @@ class phpbb_extension_manager_test extends phpbb_database_test_case $db, $config, new \phpbb\filesystem\filesystem(), + new phpbb_mock_dummy_router(), 'phpbb_ext', __DIR__ . '/', $php_ext, diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index 682882c3fc..6aafb5dd65 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -98,6 +98,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $this->db, $this->config, new \phpbb\filesystem\filesystem(), + new phpbb_mock_dummy_router(), 'phpbb_ext', $this->phpbb_root_path, $this->phpEx, diff --git a/tests/mock/dummy_router.php b/tests/mock/dummy_router.php new file mode 100644 index 0000000000..5da71abc9f --- /dev/null +++ b/tests/mock/dummy_router.php @@ -0,0 +1,31 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +class phpbb_mock_dummy_router extends phpbb_mock_router +{ + public function __construct() + { + } + + public function get_matcher() + { + $this->create_new_url_matcher(); + return parent::get_matcher(); + } + + public function get_generator() + { + $this->create_new_url_generator(); + return parent::get_generator(); + } +} diff --git a/tests/mock/extension_manager.php b/tests/mock/extension_manager.php index 0d6d110647..8d6d4469bb 100644 --- a/tests/mock/extension_manager.php +++ b/tests/mock/extension_manager.php @@ -11,6 +11,7 @@ * */ + class phpbb_mock_extension_manager extends \phpbb\extension\manager { public function __construct($phpbb_root_path, $extensions = array(), $container = null) @@ -25,5 +26,6 @@ class phpbb_mock_extension_manager extends \phpbb\extension\manager $this->container = $container; $this->config = new \phpbb\config\config(array()); $this->user = new \phpbb\user($lang,'\phpbb\datetime'); + $this->router = new phpbb_mock_dummy_router(); } } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 8b43bfd756..819d08e812 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -261,6 +261,7 @@ class phpbb_functional_test_case extends phpbb_test_case $db, $config, new phpbb\filesystem\filesystem(), + new phpbb_mock_dummy_router(), self::$config['table_prefix'] . 'ext', __DIR__ . '/', $phpEx,