From fe36375a36ec4f816eb07b41630b6c9fa7ff12c8 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 19 Sep 2013 18:29:08 +0200 Subject: [ticket/11700] Fix extension loading with namespaces class loader now expects all classes to be prefixed with a backslash when resolving paths PHPBB3-11700 --- phpBB/phpbb/class_loader.php | 11 ++++++++-- phpBB/phpbb/controller/helper.php | 2 +- phpBB/phpbb/controller/resolver.php | 8 ++++---- phpBB/phpbb/event/kernel_exception_subscriber.php | 4 ++-- phpBB/phpbb/event/kernel_request_subscriber.php | 6 +++--- phpBB/phpbb/event/kernel_terminate_subscriber.php | 2 +- tests/acp_board/auth_provider/valid.php | 4 +++- tests/bootstrap.php | 2 +- tests/class_loader/class_loader_test.php | 24 +++++++++++----------- tests/controller/controller_test.php | 8 ++++---- tests/controller/ext/foo/config/services.yml | 2 +- tests/controller/ext/foo/controller.php | 4 +++- tests/extension/ext/bar/my/hidden_class.php | 4 +++- tests/extension/ext/foo/acp/fail_info.php | 2 +- tests/functional/extension_controller_test.php | 2 +- tests/functional/extension_module_test.php | 4 ++-- .../fixtures/ext/foo/bar/acp/main_info.php | 6 ++++-- .../fixtures/ext/foo/bar/acp/main_module.php | 4 +++- .../fixtures/ext/foo/bar/config/services.yml | 2 +- .../fixtures/ext/foo/bar/controller/controller.php | 5 ++++- .../fixtures/ext/foo/bar/event/permission.php | 4 +++- .../fixtures/ext/foo/bar/event/user_setup.php | 4 +++- tests/functional/fixtures/ext/foo/bar/ext.php | 4 +++- 23 files changed, 72 insertions(+), 46 deletions(-) diff --git a/phpBB/phpbb/class_loader.php b/phpBB/phpbb/class_loader.php index bcd05e5853..769f28b4f1 100644 --- a/phpBB/phpbb/class_loader.php +++ b/phpBB/phpbb/class_loader.php @@ -55,7 +55,12 @@ class class_loader * @param \phpbb\cache\driver\driver_interface $cache An implementation of the phpBB cache interface. */ public function __construct($namespace, $path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null) - { + { + if ($namespace[0] !== '\\') + { + $namespace = '\\' . $namespace; + } + $this->namespace = $namespace; $this->path = $path; $this->php_ext = $php_ext; @@ -105,7 +110,8 @@ class class_loader * Resolves a phpBB class name to a relative path which can be included. * * @param string $class The class name to resolve, must be in the - * namespace the loader was constructed with + * namespace the loader was constructed with. + * Has to begin with \ * @return string|bool A relative path to the file containing the * class or false if looking it up failed. */ @@ -144,6 +150,7 @@ class class_loader */ public function load_class($class) { + $class = '\\' . $class; if (substr($class, 0, strlen($this->namespace)) === $this->namespace) { $path = $this->resolve_path($class); diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index 6e45374643..07483a91eb 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -91,7 +91,7 @@ class helper page_footer(true, false, false); - return new \Response($this->template->assign_display('body'), $status_code); + return new Response($this->template->assign_display('body'), $status_code); } /** diff --git a/phpBB/phpbb/controller/resolver.php b/phpBB/phpbb/controller/resolver.php index dad2ebd06b..1cc8981105 100644 --- a/phpBB/phpbb/controller/resolver.php +++ b/phpBB/phpbb/controller/resolver.php @@ -95,12 +95,12 @@ class resolver implements ControllerResolverInterface * the style paths for the extension (the ext author can change them * if necessary). */ - $controller_dir = explode('_', get_class($controller_object)); + $controller_dir = explode('\\', get_class($controller_object)); - // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... - if (!is_null($this->template) && isset($controller_dir[3]) && $controller_dir[1] === 'ext') + // 0 vendor, 1 extension name, ... + if (!is_null($this->template) && isset($controller_dir[1])) { - $controller_style_dir = 'ext/' . $controller_dir[2] . '/' . $controller_dir[3] . '/styles'; + $controller_style_dir = 'ext/' . $controller_dir[0] . '/' . $controller_dir[1] . '/styles'; if (is_dir($controller_style_dir)) { diff --git a/phpBB/phpbb/event/kernel_exception_subscriber.php b/phpBB/phpbb/event/kernel_exception_subscriber.php index 7199f47ae8..09103680e8 100644 --- a/phpBB/phpbb/event/kernel_exception_subscriber.php +++ b/phpBB/phpbb/event/kernel_exception_subscriber.php @@ -55,7 +55,7 @@ class kernel_exception_subscriber implements EventSubscriberInterface * @param GetResponseForExceptionEvent $event * @return null */ - public function on_kernel_exception(\GetResponseForExceptionEvent $event) + public function on_kernel_exception(GetResponseForExceptionEvent $event) { page_header($this->user->lang('INFORMATION')); @@ -74,7 +74,7 @@ class kernel_exception_subscriber implements EventSubscriberInterface $status_code = $exception instanceof HttpException ? $exception->getStatusCode() : 500; - $response = new \Response($this->template->assign_display('body'), $status_code); + $response = new Response($this->template->assign_display('body'), $status_code); $event->setResponse($response); } diff --git a/phpBB/phpbb/event/kernel_request_subscriber.php b/phpBB/phpbb/event/kernel_request_subscriber.php index 9691be7ca5..a629dd8440 100644 --- a/phpBB/phpbb/event/kernel_request_subscriber.php +++ b/phpBB/phpbb/event/kernel_request_subscriber.php @@ -65,14 +65,14 @@ class kernel_request_subscriber implements EventSubscriberInterface * @param GetResponseEvent $event * @return null */ - public function on_kernel_request(\GetResponseEvent $event) + public function on_kernel_request(GetResponseEvent $event) { $request = $event->getRequest(); - $context = new \RequestContext(); + $context = new RequestContext(); $context->fromRequest($request); $matcher = phpbb_get_url_matcher($this->finder, $context, $this->root_path, $this->php_ext); - $router_listener = new \RouterListener($matcher, $context); + $router_listener = new RouterListener($matcher, $context); $router_listener->onKernelRequest($event); } diff --git a/phpBB/phpbb/event/kernel_terminate_subscriber.php b/phpBB/phpbb/event/kernel_terminate_subscriber.php index aea9d7cc44..de441da102 100644 --- a/phpBB/phpbb/event/kernel_terminate_subscriber.php +++ b/phpBB/phpbb/event/kernel_terminate_subscriber.php @@ -31,7 +31,7 @@ class kernel_terminate_subscriber implements EventSubscriberInterface * @param PostResponseEvent $event * @return null */ - public function on_kernel_terminate(\PostResponseEvent $event) + public function on_kernel_terminate(PostResponseEvent $event) { exit_handler(); } diff --git a/tests/acp_board/auth_provider/valid.php b/tests/acp_board/auth_provider/valid.php index cfc3c24833..13ec1e3250 100644 --- a/tests/acp_board/auth_provider/valid.php +++ b/tests/acp_board/auth_provider/valid.php @@ -7,7 +7,9 @@ * */ -class phpbb_auth_provider_acp_board_valid extends \phpbb\auth\provider\base +namespace phpbb\auth\provider\acp; + +class board_valid extends \phpbb\auth\provider\base { public function login($username, $password) { diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 43efecce3b..afb586435c 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -18,7 +18,7 @@ require_once $phpbb_root_path . 'phpbb/class_loader.' . $phpEx; $phpbb_class_loader_mock = new \phpbb\class_loader('phpbb_mock_', $phpbb_root_path . '../tests/mock/', "php"); $phpbb_class_loader_mock->register(); -$phpbb_class_loader_ext = new \phpbb\class_loader('phpbb_ext_', $phpbb_root_path . 'ext/', "php"); +$phpbb_class_loader_ext = new \phpbb\class_loader('\\', $phpbb_root_path . 'ext/', "php"); $phpbb_class_loader_ext->register(); $phpbb_class_loader = new \phpbb\class_loader('phpbb\\', $phpbb_root_path . 'phpbb/', "php"); $phpbb_class_loader->register(); diff --git a/tests/class_loader/class_loader_test.php b/tests/class_loader/class_loader_test.php index 255b634bd6..6e551f658a 100644 --- a/tests/class_loader/class_loader_test.php +++ b/tests/class_loader/class_loader_test.php @@ -36,22 +36,22 @@ class phpbb_class_loader_test extends PHPUnit_Framework_TestCase $this->assertEquals( $prefix . 'class_name.php', - $class_loader->resolve_path('phpbb\\class_name'), + $class_loader->resolve_path('\\phpbb\\class_name'), 'Top level class' ); $this->assertEquals( $prefix . 'dir/class_name.php', - $class_loader->resolve_path('phpbb\\dir\\class_name'), + $class_loader->resolve_path('\\phpbb\\dir\\class_name'), 'Class in a directory' ); $this->assertEquals( $prefix . 'dir/subdir/class_name.php', - $class_loader->resolve_path('phpbb\\dir\\subdir\\class_name'), + $class_loader->resolve_path('\\phpbb\\dir\\subdir\\class_name'), 'Class in a sub-directory' ); $this->assertEquals( $prefix . 'dir2/dir2.php', - $class_loader->resolve_path('phpbb\\dir2\\dir2'), + $class_loader->resolve_path('\\phpbb\\dir2\\dir2'), 'Class with name of dir within dir' ); } @@ -59,8 +59,8 @@ class phpbb_class_loader_test extends PHPUnit_Framework_TestCase public function test_resolve_cached() { $cache_map = array( - 'class_loader_phpbb__' => array('phpbb\\a\\cached_name' => 'a/cached_name'), - 'class_loader___' => array('phpbb\\ext\\foo' => 'foo'), + 'class_loader___phpbb__' => array('\\phpbb\\a\\cached_name' => 'a/cached_name'), + 'class_loader___' => array('\\phpbb\\ext\\foo' => 'foo'), ); $cache = new phpbb_mock_cache($cache_map); @@ -72,26 +72,26 @@ class phpbb_class_loader_test extends PHPUnit_Framework_TestCase $this->assertEquals( $prefix . 'dir/class_name.php', - $class_loader->resolve_path('phpbb\\dir\\class_name'), + $class_loader->resolve_path('\\phpbb\\dir\\class_name'), 'Class in a directory' ); - $this->assertFalse($class_loader->resolve_path('phpbb\\ext\\foo')); - $this->assertFalse($class_loader_ext->resolve_path('phpbb\\a\\cached_name')); + $this->assertFalse($class_loader->resolve_path('\\phpbb\\ext\\foo')); + $this->assertFalse($class_loader_ext->resolve_path('\\phpbb\\a\\cached_name')); $this->assertEquals( $prefix . 'a/cached_name.php', - $class_loader->resolve_path('phpbb\\a\\cached_name'), + $class_loader->resolve_path('\\phpbb\\a\\cached_name'), 'Cached class found' ); $this->assertEquals( $prefix . 'foo.php', - $class_loader_ext->resolve_path('phpbb\\ext\\foo'), + $class_loader_ext->resolve_path('\\phpbb\\ext\\foo'), 'Cached class found in alternative loader' ); - $cache_map['class_loader_phpbb__']['phpbb\\dir\\class_name'] = 'dir/class_name'; + $cache_map['class_loader___phpbb__']['\\phpbb\\dir\\class_name'] = 'dir/class_name'; $cache->check($this, $cache_map); } } diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php index 9445ea53d4..10fced05a2 100644 --- a/tests/controller/controller_test.php +++ b/tests/controller/controller_test.php @@ -53,11 +53,11 @@ class phpbb_controller_controller_test extends phpbb_test_case // Autoloading classes within the tests folder does not work // so I'll include them manually. - if (!class_exists('phpbb_ext_foo_controller')) + if (!class_exists('foo\\controller')) { include(__DIR__.'/ext/foo/controller.php'); } - if (!class_exists('phpbb_controller_foo')) + if (!class_exists('phpbb\\controller\\foo')) { include(__DIR__.'/phpbb/controller/foo.php'); } @@ -66,11 +66,11 @@ class phpbb_controller_controller_test extends phpbb_test_case $symfony_request = new Request(); $symfony_request->attributes->set('_controller', 'foo.controller:handle'); - $this->assertEquals($resolver->getController($symfony_request), array(new phpbb_ext_foo_controller, 'handle')); + $this->assertEquals($resolver->getController($symfony_request), array(new foo\controller, 'handle')); $symfony_request = new Request(); $symfony_request->attributes->set('_controller', 'core_foo.controller:bar'); - $this->assertEquals($resolver->getController($symfony_request), array(new phpbb_controller_foo, 'bar')); + $this->assertEquals($resolver->getController($symfony_request), array(new phpbb\controller\foo, 'bar')); } } diff --git a/tests/controller/ext/foo/config/services.yml b/tests/controller/ext/foo/config/services.yml index ce0e18c610..9ed67d5bc2 100644 --- a/tests/controller/ext/foo/config/services.yml +++ b/tests/controller/ext/foo/config/services.yml @@ -1,3 +1,3 @@ services: foo.controller: - class: phpbb_ext_foo_controller + class: foo\controller diff --git a/tests/controller/ext/foo/controller.php b/tests/controller/ext/foo/controller.php index cfc5c20622..ce2233b3c9 100644 --- a/tests/controller/ext/foo/controller.php +++ b/tests/controller/ext/foo/controller.php @@ -1,8 +1,10 @@ 'phpbb_ext_foo_acp_fail_module', + 'filename' => 'foo\acp\fail_module', 'title' => 'Foobar', 'version' => '3.1.0-dev', 'modes' => array( diff --git a/tests/functional/extension_controller_test.php b/tests/functional/extension_controller_test.php index dc6d9c0f65..41bd48c204 100644 --- a/tests/functional/extension_controller_test.php +++ b/tests/functional/extension_controller_test.php @@ -78,7 +78,7 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c $this->phpbb_extension_manager->enable('foo/bar'); $crawler = self::request('GET', 'app.php/foo/baz', array(), false); $this->assert_response_html(500); - $this->assertContains('Missing value for argument #1: test in class phpbb_ext_foo_bar_controller:baz', $crawler->filter('body')->text()); + $this->assertContains('Missing value for argument #1: test in class foo\bar\controller\controller:baz', $crawler->filter('body')->text()); $this->phpbb_extension_manager->purge('foo/bar'); } diff --git a/tests/functional/extension_module_test.php b/tests/functional/extension_module_test.php index c31a892ce9..0c9e0b1654 100644 --- a/tests/functional/extension_module_test.php +++ b/tests/functional/extension_module_test.php @@ -69,7 +69,7 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case $modules->update_module_data($parent_data, true); $module_data = array( - 'module_basename' => 'phpbb_ext_foo_bar_acp_main_module', + 'module_basename' => 'foo\\bar\\acp\\main_module', 'module_enabled' => 1, 'module_display' => 1, 'parent_id' => $parent_data['module_id'], @@ -90,7 +90,7 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case { $this->login(); $this->admin_login(); - $crawler = self::request('GET', 'adm/index.php?i=phpbb_ext_foo_bar_acp_main_module&mode=mode&sid=' . $this->sid); + $crawler = self::request('GET', 'adm/index.php?i=foo\\bar\\acp\\main_module&mode=mode&sid=' . $this->sid); $this->assertContains("Bertie rulez!", $crawler->filter('#main')->text()); $this->phpbb_extension_manager->purge('foo/bar'); } diff --git a/tests/functional/fixtures/ext/foo/bar/acp/main_info.php b/tests/functional/fixtures/ext/foo/bar/acp/main_info.php index 21e38b09b5..2ad6d08503 100644 --- a/tests/functional/fixtures/ext/foo/bar/acp/main_info.php +++ b/tests/functional/fixtures/ext/foo/bar/acp/main_info.php @@ -8,6 +8,8 @@ * */ +namespace foo\bar\acp; + /** * @ignore */ @@ -16,12 +18,12 @@ if (!defined('IN_PHPBB')) exit; } -class phpbb_ext_foo_bar_acp_main_info +class main_info { function module() { return array( - 'filename' => 'phpbb_ext_foo_bar_acp_main_module', + 'filename' => 'foo\bar\acp\main_module', 'title' => 'ACP_FOOBAR_TITLE', 'version' => '1.0.0', 'modes' => array( diff --git a/tests/functional/fixtures/ext/foo/bar/acp/main_module.php b/tests/functional/fixtures/ext/foo/bar/acp/main_module.php index c4ab69fb38..c59b3c6820 100644 --- a/tests/functional/fixtures/ext/foo/bar/acp/main_module.php +++ b/tests/functional/fixtures/ext/foo/bar/acp/main_module.php @@ -8,6 +8,8 @@ * */ +namespace foo\bar\acp; + /** * @ignore */ @@ -16,7 +18,7 @@ if (!defined('IN_PHPBB')) exit; } -class phpbb_ext_foo_bar_acp_main_module +class main_module { var $u_action; diff --git a/tests/functional/fixtures/ext/foo/bar/config/services.yml b/tests/functional/fixtures/ext/foo/bar/config/services.yml index 33ced55af9..3bca4c6567 100644 --- a/tests/functional/fixtures/ext/foo/bar/config/services.yml +++ b/tests/functional/fixtures/ext/foo/bar/config/services.yml @@ -1,6 +1,6 @@ services: foo_bar.controller: - class: phpbb_ext_foo_bar_controller + class: foo\bar\controller\controller arguments: - @controller.helper - @template diff --git a/tests/functional/fixtures/ext/foo/bar/controller/controller.php b/tests/functional/fixtures/ext/foo/bar/controller/controller.php index 41b2be350b..259d548299 100644 --- a/tests/functional/fixtures/ext/foo/bar/controller/controller.php +++ b/tests/functional/fixtures/ext/foo/bar/controller/controller.php @@ -1,7 +1,10 @@