diff --git a/phpBB/includes/extension/controller_interface.php b/phpBB/includes/extension/controller_interface.php new file mode 100644 index 0000000000..bcc8972db4 --- /dev/null +++ b/phpBB/includes/extension/controller_interface.php @@ -0,0 +1,31 @@ +get_extension_path($name, true)); + } + + /** + * Check to see if a given extension is enabled + * + * @param string $name Extension name to check + * @return bool Depending on whether or not the extension is enabled + */ + public function enabled($name) + { + return isset($this->extensions[$name]) && $this->extensions[$name]['ext_active']; + } /** * Instantiates a phpbb_extension_finder. diff --git a/phpBB/index.php b/phpBB/index.php index f1243bb336..d71878a885 100644 --- a/phpBB/index.php +++ b/phpBB/index.php @@ -24,6 +24,39 @@ $user->session_begin(); $auth->acl($user->data); $user->setup('viewforum'); +// Handle the display of extension front pages +if ($ext = $request->variable('ext', '')) +{ + $class = 'phpbb_ext_' . str_replace('/', '_', $ext) . '_controller'; + + if (!$phpbb_extension_manager->available($ext)) + { + send_status_line(404, 'Not Found'); + trigger_error($user->lang('EXTENSION_DOES_NOT_EXIST', $ext)); + } + else if (!$phpbb_extension_manager->enabled($ext)) + { + send_status_line(404, 'Not Found'); + trigger_error($user->lang('EXTENSION_DISABLED', $ext)); + } + else if (!class_exists($class)) + { + send_status_line(404, 'Not Found'); + trigger_error($user->lang('EXTENSION_CONTROLLER_MISSING', $ext)); + } + + $controller = new $class; + + if (!($controller instanceof phpbb_extension_controller_interface)) + { + send_status_line(500, 'Internal Server Error'); + trigger_error($user->lang('EXTENSION_CLASS_WRONG_TYPE', $class)); + } + + $controller->handle(); + exit_handler(); +} + display_forums('', $config['load_moderators']); $order_legend = ($config['legend_sort_groupname']) ? 'group_name' : 'group_legend'; diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 7741ff8d1f..94edddc6f5 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -185,7 +185,11 @@ $lang = array_merge($lang, array( 'ERR_WRONG_PATH_TO_PHPBB' => 'The phpBB path specified appears to be invalid.', 'EXPAND_VIEW' => 'Expand view', 'EXTENSION' => 'Extension', + 'EXTENSION_CONTROLLER_MISSING' => 'The extension %s is missing a controller class and cannot be accessed through the front-end.', + 'EXTENSION_CLASS_WRONG_TYPE' => 'The extension controller class %s is not an instance of the phpbb_extension_controller_interface.', + 'EXTENSION_DISABLED' => 'The extension %s is not enabled.', 'EXTENSION_DISABLED_AFTER_POSTING' => 'The extension %s has been deactivated and can no longer be displayed.', + 'EXTENSION_DOES_NOT_EXIST' => 'The extension %s does not exist.', 'FAQ' => 'FAQ', 'FAQ_EXPLAIN' => 'Frequently Asked Questions', diff --git a/tests/functional/extension_controller_test.php b/tests/functional/extension_controller_test.php new file mode 100644 index 0000000000..4ee0e68718 --- /dev/null +++ b/tests/functional/extension_controller_test.php @@ -0,0 +1,153 @@ +phpbb_extension_manager = $this->get_extension_manager(); + + $this->purge_cache(); + } + + /** + * Check an extension at ./ext/foobar/ which should have the class + * phpbb_ext_foobar_controller + */ + public function test_foobar() + { + $this->phpbb_extension_manager->enable('foobar'); + $crawler = $this->request('GET', 'index.php?ext=foobar'); + $this->assertContains("This is for testing purposes.", $crawler->filter('#page-body')->text()); + $this->phpbb_extension_manager->purge('foobar'); + } + + /** + * Check an extension at ./ext/foo/bar/ which should have the class + * phpbb_ext_foo_bar_controller + */ + public function test_foo_bar() + { + $this->phpbb_extension_manager->enable('foo/bar'); + $crawler = $this->request('GET', 'index.php?ext=foo/bar'); + $this->assertContains("This is for testing purposes.", $crawler->filter('#page-body')->text()); + $this->phpbb_extension_manager->purge('foo/bar'); + } + + /** + * Check the error produced by extension at ./ext/error/class which has class + * phpbb_ext_foobar_controller + */ + public function test_error_class_name() + { + $this->phpbb_extension_manager->enable('error/class'); + $crawler = $this->request('GET', 'index.php?ext=error/class'); + $this->assertContains("The extension error/class is missing a controller class and cannot be accessed through the front-end.", $crawler->filter('#message')->text()); + $this->phpbb_extension_manager->purge('error/class'); + } + + /** + * Check the error produced by extension at ./ext/error/classtype which has class + * phpbb_ext_error_classtype_controller but does not implement phpbb_extension_controller_interface + */ + public function test_error_class_type() + { + $this->phpbb_extension_manager->enable('error/classtype'); + $crawler = $this->request('GET', 'index.php?ext=error/classtype'); + $this->assertContains("The extension controller class phpbb_ext_error_classtype_controller is not an instance of the phpbb_extension_controller_interface.", $crawler->filter('#message')->text()); + $this->phpbb_extension_manager->purge('error/classtype'); + } + + /** + * Check the error produced by extension at ./ext/error/disabled that is (obviously) + * a disabled extension + */ + public function test_error_ext_disabled() + { + $crawler = $this->request('GET', 'index.php?ext=error/disabled'); + $this->assertContains("The extension error/disabled is not enabled", $crawler->filter('#message')->text()); + } + + /** + * Check the error produced by extension at ./ext/error/404 that is (obviously) + * not existant + */ + public function test_error_ext_missing() + { + $crawler = $this->request('GET', 'index.php?ext=error/404'); + $this->assertContains("The extension error/404 does not exist.", $crawler->filter('#message')->text()); + } +} diff --git a/tests/functional/fixtures/ext/error/class/controller.php b/tests/functional/fixtures/ext/error/class/controller.php new file mode 100644 index 0000000000..eb2ae362a6 --- /dev/null +++ b/tests/functional/fixtures/ext/error/class/controller.php @@ -0,0 +1,17 @@ +set_ext_dir_prefix($phpbb_root_path . 'ext/error/class/'); + + $template->set_filenames(array( + 'body' => 'index_body.html' + )); + + page_header('Test extension'); + page_footer(); + } +} diff --git a/tests/functional/fixtures/ext/error/class/ext.php b/tests/functional/fixtures/ext/error/class/ext.php new file mode 100644 index 0000000000..f97ad2b838 --- /dev/null +++ b/tests/functional/fixtures/ext/error/class/ext.php @@ -0,0 +1,6 @@ +set_ext_dir_prefix($phpbb_root_path . 'ext/error/classtype/'); + + $template->set_filenames(array( + 'body' => 'index_body.html' + )); + + page_header('Test extension'); + page_footer(); + } +} diff --git a/tests/functional/fixtures/ext/error/classtype/ext.php b/tests/functional/fixtures/ext/error/classtype/ext.php new file mode 100644 index 0000000000..35b1cd15a2 --- /dev/null +++ b/tests/functional/fixtures/ext/error/classtype/ext.php @@ -0,0 +1,6 @@ +set_ext_dir_prefix($phpbb_root_path . 'ext/error/disabled/'); + + $template->set_filenames(array( + 'body' => 'index_body.html' + )); + + page_header('Test extension'); + page_footer(); + } +} diff --git a/tests/functional/fixtures/ext/error/disabled/ext.php b/tests/functional/fixtures/ext/error/disabled/ext.php new file mode 100644 index 0000000000..aec8051848 --- /dev/null +++ b/tests/functional/fixtures/ext/error/disabled/ext.php @@ -0,0 +1,6 @@ +set_ext_dir_prefix($phpbb_root_path . 'ext/foo/bar/'); + + $template->set_filenames(array( + 'body' => 'foobar_body.html' + )); + + page_header('Test extension'); + page_footer(); + } +} diff --git a/tests/functional/fixtures/ext/foo/bar/ext.php b/tests/functional/fixtures/ext/foo/bar/ext.php new file mode 100644 index 0000000000..3a2068631e --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/ext.php @@ -0,0 +1,6 @@ + + +