aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--phpBB/.htaccess11
-rw-r--r--phpBB/app.php29
-rw-r--r--phpBB/common.php9
-rw-r--r--phpBB/composer.json1
-rw-r--r--phpBB/composer.lock62
-rw-r--r--phpBB/config/routing.yml9
-rw-r--r--phpBB/config/services.yml63
-rw-r--r--phpBB/includes/controller/helper.php142
-rw-r--r--phpBB/includes/controller/provider.php94
-rw-r--r--phpBB/includes/controller/resolver.php123
-rw-r--r--phpBB/includes/controller/route_collection.php36
-rw-r--r--phpBB/includes/functions.php35
-rw-r--r--phpBB/includes/template/template.php19
-rw-r--r--phpBB/index.php40
-rw-r--r--phpBB/language/en/app.php59
-rw-r--r--phpBB/web.config12
-rw-r--r--tests/controller/config/routing.yml3
-rw-r--r--tests/controller/config/services.yml3
-rw-r--r--tests/controller/controller_test.php75
-rw-r--r--tests/controller/ext/foo/config/routing.yml3
-rw-r--r--tests/controller/ext/foo/config/services.yml3
-rw-r--r--tests/controller/ext/foo/controller.php23
-rw-r--r--tests/controller/includes/controller/foo.php23
23 files changed, 818 insertions, 59 deletions
diff --git a/phpBB/.htaccess b/phpBB/.htaccess
index 474f9774c2..61bd4249e3 100644
--- a/phpBB/.htaccess
+++ b/phpBB/.htaccess
@@ -1,12 +1,17 @@
+<IfModule mod_rewrite.c>
+RewriteEngine on
+
#
# Uncomment the statement below if you want to make use of
# HTTP authentication and it does not already work.
# This could be required if you are for example using PHP via Apache CGI.
#
-#<IfModule mod_rewrite.c>
-#RewriteEngine on
#RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
-#</IfModule>
+
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteRule ^(.*)$ app.php [QSA,L]
+</IfModule>
<Files "config.php">
Order Allow,Deny
diff --git a/phpBB/app.php b/phpBB/app.php
new file mode 100644
index 0000000000..9ff9069104
--- /dev/null
+++ b/phpBB/app.php
@@ -0,0 +1,29 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+*/
+
+/**
+* @ignore
+*/
+define('IN_PHPBB', true);
+$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
+$phpEx = substr(strrchr(__FILE__, '.'), 1);
+include($phpbb_root_path . 'common.' . $phpEx);
+
+// Start session management
+$user->session_begin();
+$auth->acl($user->data);
+$user->setup('app');
+
+$http_kernel = $phpbb_container->get('http_kernel');
+$response = $http_kernel->handle($symfony_request);
+$response->send();
+$http_kernel->terminate($symfony_request, $response);
diff --git a/phpBB/common.php b/phpBB/common.php
index c4237dfcf5..986f0a8839 100644
--- a/phpBB/common.php
+++ b/phpBB/common.php
@@ -8,9 +8,7 @@
* Minimum Requirement: PHP 5.3.3
*/
-use Symfony\Component\Config\FileLocator;
-use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
+use Symfony\Component\HttpFoundation\Request;
/**
*/
@@ -106,6 +104,11 @@ $phpbb_class_loader_ext->set_cache($phpbb_container->get('cache.driver'));
// set up caching
$cache = $phpbb_container->get('cache');
+// Instantiate the Symfony Request object
+// This must be done before phpbb_request
+// because otherwise globals are disabled
+$symfony_request = Request::createFromGlobals();
+
// Instantiate some basic classes
$phpbb_dispatcher = $phpbb_container->get('dispatcher');
$request = $phpbb_container->get('request');
diff --git a/phpBB/composer.json b/phpBB/composer.json
index 380bdc367c..5a03e68f73 100644
--- a/phpBB/composer.json
+++ b/phpBB/composer.json
@@ -5,6 +5,7 @@
"symfony/dependency-injection": "2.1.*",
"symfony/event-dispatcher": "2.1.*",
"symfony/http-kernel": "2.1.*",
+ "symfony/routing": "2.1.*",
"symfony/yaml": "2.1.*"
},
"require-dev": {
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index 69e4a2b4b8..62ece6d505 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -1,5 +1,5 @@
{
- "hash": "407cc89f4bb0e409146c863dee51b0ae",
+ "hash": "efb4768ba71d7cd2c84baa0610d84067",
"packages": [
{
"name": "symfony/config",
@@ -273,6 +273,64 @@
"homepage": "http://symfony.com"
},
{
+ "name": "symfony/routing",
+ "version": "v2.1.3",
+ "target-dir": "Symfony/Component/Routing",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Routing",
+ "reference": "v2.1.3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://github.com/symfony/Routing/zipball/v2.1.3",
+ "reference": "v2.1.3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/config": "2.1.*",
+ "symfony/yaml": "2.1.*",
+ "symfony/http-kernel": "2.1.*",
+ "doctrine/common": ">=2.2,<2.4-dev"
+ },
+ "suggest": {
+ "symfony/config": "2.1.*",
+ "symfony/yaml": "2.1.*",
+ "doctrine/common": ">=2.2,<2.4-dev"
+ },
+ "time": "2012-10-26 02:26:42",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Routing": ""
+ }
+ },
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Routing Component",
+ "homepage": "http://symfony.com"
+ },
+ {
"name": "symfony/yaml",
"version": "v2.1.3",
"target-dir": "Symfony/Component/Yaml",
@@ -331,7 +389,7 @@
},
"dist": {
"type": "zip",
- "url": "https://github.com/fabpot/Goutte/zipball/f2940f9c7c1f409159f5e9f512e575946c5cff48",
+ "url": "https://github.com/fabpot/Goutte/archive/f2940f9c7c1f409159f5e9f512e575946c5cff48.zip",
"reference": "f2940f9c7c1f409159f5e9f512e575946c5cff48",
"shasum": ""
},
diff --git a/phpBB/config/routing.yml b/phpBB/config/routing.yml
new file mode 100644
index 0000000000..f6f728fa47
--- /dev/null
+++ b/phpBB/config/routing.yml
@@ -0,0 +1,9 @@
+# Structure:
+#
+# foo_controller:
+# pattern: /foo
+# defaults: { _controller: foo_sevice:method }
+#
+# The above will be accessed via app.php/foo and it will instantiate the
+# "foo_service" service and call the "method" method.
+#
diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml
index 20aa0546d5..650869d1e6 100644
--- a/phpBB/config/services.yml
+++ b/phpBB/config/services.yml
@@ -44,6 +44,27 @@ services:
- @cache.driver
- %tables.config%
+ controller.helper:
+ class: phpbb_controller_helper
+ arguments:
+ - @service_container
+
+ controller.resolver:
+ class: phpbb_controller_resolver
+ arguments:
+ - @user
+ - @service_container
+ - @ext.finder
+
+ controller.route_collection:
+ class: phpbb_controller_route_collection
+ arguments:
+ - @ext.finder
+ - @controller.provider
+
+ controller.provider:
+ class: phpbb_controller_provider
+
cron.task_collection:
class: phpbb_di_service_collection
arguments:
@@ -92,10 +113,46 @@ services:
- %core.root_path%
- .%core.php_ext%
- @cache.driver
+<<<<<<< HEAD
+=======
+
+ ext.finder:
+ class: phpbb_extension_finder
+ arguments:
+ - @ext.manager
+ - %core.root_path%
+ - @cache.driver
+ - .%core.php_ext%
+ - _ext_finder
+
+ http_kernel:
+ class: Symfony\Component\HttpKernel\HttpKernel
+ arguments:
+ - @dispatcher
+ - @controller.resolver
+
+ kernel_event_subscriber:
+ class: phpbb_event_kernel_subscriber
+ arguments:
+ - @template
+ - @user
+ tags:
+ - { name: kernel.event_subscriber }
+>>>>>>> 719171f... [feature/controller] Implement a front controller
request:
class: phpbb_request
+ request.context:
+ class: Symfony\Component\Routing\RequestContext
+
+ router_listener:
+ class: Symfony\Component\HttpKernel\EventListener\RouterListener
+ arguments:
+ - @url_matcher
+ tags:
+ - { name: kernel.event_subscriber }
+
style:
class: phpbb_style
arguments:
@@ -132,5 +189,11 @@ services:
template_context:
class: phpbb_template_context
+ url_matcher:
+ class: Symfony\Component\Routing\Matcher\UrlMatcher
+ arguments:
+ - @controller.route_collection
+ - @request.context
+
user:
class: phpbb_user
diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php
new file mode 100644
index 0000000000..1998ea6733
--- /dev/null
+++ b/phpBB/includes/controller/helper.php
@@ -0,0 +1,142 @@
+<?php
+/**
+*
+* @package controller
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+/**
+* Controller helper class, contains methods that do things for controllers
+* @package phpBB3
+*/
+class phpbb_controller_helper
+{
+ /**
+ * Container
+ * @var ContainerBuilder
+ */
+ protected $container;
+
+ /**
+ * Template object
+ * @var phpbb_template
+ */
+ protected $template;
+
+ /**
+ * phpBB Root Path
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * PHP Extension
+ * @var string
+ */
+ protected $php_ext;
+
+ /**
+ * Base URL
+ * @var array
+ */
+ protected $url_base;
+
+ /**
+ * Constructor
+ *
+ * @param ContainerBuilder $container DI Container
+ */
+ public function __construct(ContainerBuilder $container)
+ {
+ $this->container = $container;
+
+ $this->template = $this->container->get('template');
+ $this->phpbb_root_path = $this->container->getParameter('core.root_path');
+ $this->php_ext = $this->container->getParameter('core.php_ext');
+ }
+
+ /**
+ * Automate setting up the page and creating the response object.
+ *
+ * @param string $handle The template handle to render
+ * @param string $page_title The title of the page to output
+ * @param int $status_code The status code to be sent to the page header
+ * @return Response object containing rendered page
+ */
+ public function render($template_file, $page_title = '', $status_code = 200)
+ {
+ if (!function_exists('page_header'))
+ {
+ include("{$this->phpbb_root_path}includes/functions.{$this->php_ext}");
+ }
+
+ page_header($page_title);
+
+ $this->template->set_filenames(array(
+ 'body' => $template_file,
+ ));
+
+ page_footer(true, false, false);
+
+ return new Response($this->template->return_display('body'), $status_code);
+ }
+
+ /**
+ * Easily generate a URL
+ *
+ * @param array $url_parts Each array element is a 'folder'
+ * i.e. array('my', 'ext') maps to ./app.php/my/ext
+ * @param mixed $query The Query string, passed directly into the second
+ * argument of append_sid()
+ * @return string A URL that has already been run through append_sid()
+ */
+ public function url(array $url_parts, $query = '')
+ {
+ return append_sid($this->phpbb_root_path . $this->url_base . implode('/', $url_parts), $query);
+ }
+
+ /**
+ * Set base to prepend to urls generated by url()
+ * This allows extensions to have a certain 'directory' under which
+ * all their pages are served, but not have to type it every time
+ *
+ * @param array $url_parts Each array element is a 'folder'
+ * i.e. array('my', 'ext') maps to ./app.php/my/ext
+ * @return null
+ */
+ public function set_url_base(array $url_parts)
+ {
+ $this->url_base = !empty($url_parts) ? implode('/', $url_parts) . '/' : '';
+ }
+
+ /**
+ * Output an error, effectively the same thing as trigger_error
+ *
+ * @param string $code The error code (e.g. 404, 500, 503, etc.)
+ * @param string $message The error message
+ * @return Response A Reponse instance
+ */
+ public function error($code = 500, $message = '')
+ {
+ $this->template->assign_vars(array(
+ 'MESSAGE_TEXT' => $message,
+ 'MESSAGE_TITLE' => $this->container->get('user')->lang('INFORMATION'),
+ ));
+
+ return $this->render('message_body.html', $this->container->get('user')->lang('INFORMATION'), $code);
+ }
+}
diff --git a/phpBB/includes/controller/provider.php b/phpBB/includes/controller/provider.php
new file mode 100644
index 0000000000..25deedb5d1
--- /dev/null
+++ b/phpBB/includes/controller/provider.php
@@ -0,0 +1,94 @@
+<?php
+/**
+*
+* @package controller
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Loader\YamlFileLoader;
+use Symfony\Component\Config\FileLocator;
+
+/**
+* Controller interface
+* @package phpBB3
+*/
+class phpbb_controller_provider
+{
+ /**
+ * YAML file(s) containing route information
+ * @var array
+ */
+ protected $routing_paths;
+
+ /**
+ * Construct method
+ *
+ * @param array() $routing_paths Array of strings containing paths
+ * to YAML files holding route information
+ */
+ public function __construct($routing_paths = array())
+ {
+ $this->set_paths($routing_paths);
+ }
+
+ /**
+ * Locate paths containing routing files
+ * This sets an internal property but does not return the paths.
+ *
+ * @return The current instance of this object for method chaining
+ */
+ public function get_paths(phpbb_extension_finder $finder)
+ {
+ // We hardcode the path to the core config directory
+ // because the finder cannot find it
+ $this->set_paths(array_merge(array('config'), array_map('dirname', array_keys($finder
+ ->directory('config')
+ ->prefix('routing')
+ ->suffix('yml')
+ ->find()
+ ))));
+
+ return $this;
+ }
+
+ /**
+ * Set the $routing_paths property with a given list of paths
+ *
+ * @return The current instance of this object for method chaining
+ */
+ public function set_paths(array $paths)
+ {
+ $this->routing_paths = $paths;
+
+ return $this;
+ }
+
+ /**
+ * Get a list of controllers and return it
+ *
+ * @param string $base_path Base path to prepend to file paths
+ * @return array Array of controllers and their route information
+ */
+ public function find($base_path = '')
+ {
+ $routes = new RouteCollection;
+ foreach ($this->routing_paths as $path)
+ {
+ $loader = new YamlFileLoader(new FileLocator($base_path . $path));
+ $routes->addCollection($loader->load('routing.yml'));
+ }
+
+ return $routes;
+ }
+}
diff --git a/phpBB/includes/controller/resolver.php b/phpBB/includes/controller/resolver.php
new file mode 100644
index 0000000000..bf9ce3330d
--- /dev/null
+++ b/phpBB/includes/controller/resolver.php
@@ -0,0 +1,123 @@
+<?php
+/**
+*
+* @package controller
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+* Controller manager class
+* @package phpBB3
+*/
+class phpbb_controller_resolver implements ControllerResolverInterface
+{
+ /**
+ * User object
+ * @var phpbb_user
+ */
+ protected $user;
+
+ /**
+ * ContainerInterface object
+ * @var ContainerInterface
+ */
+ protected $container;
+
+ /**
+ * Construct method
+ *
+ * @param phpbb_user $user User Object
+ * @param ContainerInterface $container ContainerInterface object
+ */
+ public function __construct(phpbb_user $user, ContainerInterface $container)
+ {
+ $this->user = $user;
+ $this->container = $container;
+ }
+
+ /**
+ * Load a controller callable
+ *
+ * @param Symfony\Component\HttpFoundation\Request $request Symfony Request object
+ * @return bool|Callable Callable or false
+ * @throws RuntimeException
+ */
+ public function getController(Request $request)
+ {
+ $controller = $request->attributes->get('_controller');
+
+ if (!$controller)
+ {
+ throw new RuntimeException($this->user->lang['CONTROLLER_NOT_SPECIFIED']);
+ }
+
+ // Require a method name along with the service name
+ if (stripos($controller, ':') === false)
+ {
+ throw new RuntimeException($this->user->lang['CONTROLLER_METHOD_NOT_SPECIFIED']);
+ }
+
+ list($service, $method) = explode(':', $controller);
+
+ if (!$this->container->has($service))
+ {
+ throw new RuntimeException($this->user->lang('CONTROLLER_SERVICE_UNDEFINED', $service));
+ }
+
+ $controller_object = $this->container->get($service);
+
+ return array($controller_object, $method);
+ }
+
+ /**
+ * Dependencies should be specified in the service definition and can be
+ * then accessed in __construct(). Arguments are sent through the URL path
+ * and should match the parameters of the method you are using as your
+ * controller.
+ *
+ * @param Symfony\Component\HttpFoundation\Request $request Symfony Request object
+ * @param string $controller Controller class name
+ * @return bool False
+ */
+ public function getArguments(Request $request, $controller)
+ {
+ // At this point, $controller contains the object and method name
+ list($object, $method) = $controller;
+ $mirror = new ReflectionMethod($object, $method);
+
+ $arguments = array();
+ $parameters = $mirror->getParameters();
+ $attributes = $request->attributes->all();
+ foreach ($parameters as $param)
+ {
+ if (array_key_exists($param->name, $attributes))
+ {
+ $arguments[] = $attributes[$param->name];
+ }
+ else if ($param->isDefaultValueAvailable())
+ {
+ $arguments[] = $param->getDefaultValue();
+ }
+ else
+ {
+ throw new RuntimeException($user->lang('CONTROLLER_ARGUMENT_VALUE_MISSING', $param->getPosition() + 1, get_class($object) . ':' . $method, $param->name));
+ }
+ }
+
+ return $arguments;
+ }
+}
diff --git a/phpBB/includes/controller/route_collection.php b/phpBB/includes/controller/route_collection.php
new file mode 100644
index 0000000000..e6c7d3b543
--- /dev/null
+++ b/phpBB/includes/controller/route_collection.php
@@ -0,0 +1,36 @@
+<?php
+/**
+*
+* @package controller
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+* Controller manager class
+* @package phpBB3
+*/
+class phpbb_controller_route_collection extends RouteCollection
+{
+ /**
+ * Construct method
+ *
+ * @param phpbb_extension_finder $finder Finder object
+ */
+ public function __construct(phpbb_extension_finder $finder, phpbb_controller_provider $provider)
+ {
+ parent::__construct();
+ $this->addCollection($provider->get_paths($finder)->find());
+ }
+}
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 3a5b100515..fb05b74cd3 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -2335,7 +2335,7 @@ function phpbb_on_page($template, $user, $base_url, $num_items, $per_page, $star
function append_sid($url, $params = false, $is_amp = true, $session_id = false)
{
global $_SID, $_EXTRA_URL, $phpbb_hook;
- global $phpbb_dispatcher;
+ global $phpbb_dispatcher, $phpbb_root_path, $config, $symfony_request;
if ($params === '' || (is_array($params) && empty($params)))
{
@@ -2343,6 +2343,20 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false)
$params = false;
}
+ // Make sure we have a Symfony Request object; tests do not have one
+ // unless they need it.
+ if ($symfony_request)
+ {
+ // Correct the path when we are accessing it through a controller
+ // This simply rewrites the value given by $phpbb_root_path to the
+ // script_path in config.
+ $path_info = $symfony_request->getPathInfo();
+ if (!empty($path_info) && $path_info != '/')
+ {
+ $url = $config['script_path'] . '/' . substr($url, strlen($phpbb_root_path));
+ }
+ }
+
$append_sid_overwrite = false;
/**
@@ -5039,7 +5053,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
// Determine board url - we may need it later
$board_url = generate_board_url() . '/';
- $web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $phpbb_root_path;
+ $web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $config['script_path'] . '/';
// Send a proper content-language to the output
$user_lang = $user->lang['USER_LANG'];
@@ -5216,8 +5230,12 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
/**
* Generate page footer
+*
+* @param bool $run_cron Whether or not to run the cron
+* @param bool $display_template Whether or not to display the template
+* @param bool $exit_handler Whether or not to run the exit_handler()
*/
-function page_footer($run_cron = true)
+function page_footer($run_cron = true, $display_template = true, $exit_handler = true)
{
global $db, $config, $template, $user, $auth, $cache, $starttime, $phpbb_root_path, $phpEx;
global $request, $phpbb_dispatcher;
@@ -5312,10 +5330,17 @@ function page_footer($run_cron = true)
}
}
- $template->display('body');
+ if ($display_template)
+ {
+ $template->display('body');
+ }
garbage_collection();
- exit_handler();
+
+ if ($exit_handler)
+ {
+ exit_handler();
+ }
}
/**
diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php
index 8a7dc6b2f3..a48e8459d5 100644
--- a/phpBB/includes/template/template.php
+++ b/phpBB/includes/template/template.php
@@ -224,15 +224,9 @@ class phpbb_template
*/
public function assign_display($handle, $template_var = '', $return_content = true)
{
- ob_start();
- $result = $this->display($handle);
- $contents = ob_get_clean();
- if ($result === false)
- {
- return false;
- }
+ $contents = $this->return_display($handle);
- if ($return_content)
+ if ($return_content === true || empty($template_var) || $contents === false)
{
return $contents;
}
@@ -242,6 +236,15 @@ class phpbb_template
return true;
}
+ public function return_display($handle)
+ {
+ ob_start();
+ $result = $this->display($handle);
+ $contents = ob_get_clean();
+
+ return $result === false ? $result : $contents;
+ }
+
/**
* Obtains a template renderer for a template identified by specified
* handle. The template renderer can display the template later.
diff --git a/phpBB/index.php b/phpBB/index.php
index 66e1b2114b..845d0f0c02 100644
--- a/phpBB/index.php
+++ b/phpBB/index.php
@@ -17,48 +17,12 @@ define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
+include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
// Start session management
$user->session_begin();
$auth->acl($user->data);
-$user->setup();
-
-// 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();
-}
-
-include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
-
-$user->add_lang('viewforum');
+$user->setup('viewforum');
display_forums('', $config['load_moderators']);
diff --git a/phpBB/language/en/app.php b/phpBB/language/en/app.php
new file mode 100644
index 0000000000..db7f3164d0
--- /dev/null
+++ b/phpBB/language/en/app.php
@@ -0,0 +1,59 @@
+<?php
+/**
+*
+* app [English]
+*
+* @package language
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* DO NOT CHANGE
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+if (empty($lang) || !is_array($lang))
+{
+ $lang = array();
+}
+
+// DEVELOPERS PLEASE NOTE
+//
+// All language files should use UTF-8 as their encoding and the files must not contain a BOM.
+//
+// Placeholders can now contain order information, e.g. instead of
+// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows
+// translators to re-order the output of data while ensuring it remains correct
+//
+// You do not need this where single placeholders are used, e.g. 'Message %d' is fine
+// equally where a string contains only two placeholders which are used to wrap text
+// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
+//
+// Some characters you may want to copy&paste:
+// ’ » “ ” …
+//
+
+$lang = array_merge($lang, array(
+ 'CONTROLLER_ARGUMENT_VALUE_MISSING' => 'Missing value for argument #%1$s: <strong>%3$s</strong> in class <strong>%2$s</strong>',
+ 'CONTROLLER_NOT_SPECIFIED' => 'No controller has been specified.',
+ 'CONTROLLER_NOT_FOUND' => 'The requested page could not be found.',
+ 'CONTROLLER_METHOD_NOT_SPECIFIED' => 'No method was specified for the controller.',
+ 'CONTROLLER_SERVICE_NOT_GIVEN' => 'The controller "<strong>%s</strong>" must have a service specified in ./config/routing.yml.',
+ 'CONTROLLER_SERVICE_UNDEFINED' => 'The service for controller "<strong>%s</strong>" is not defined in ./config/services.yml.',
+ 'CONTROLLER_RETURN_TYPE_INVALID' => 'The controller object <strong>%s</strong> must return a Symfony\Component\HttpFoundation\Response object.',
+
+ // Event Listener/Subscriber error messages
+ 'NO_EVENT_ATTRIBUTE' => 'Service "%1$s" must define the "event" attribute on "kernel.event_listener" tags.',
+ 'SUBSCRIBER_WRONG_TYPE' => 'Service "%1$s" must implement interface "%2$s".',
+
+ // Core error controller messages
+ 'PAGE_NOT_FOUND_ERROR' => 'The page you have requested does not exist.',
+ 'NOT_AUTHORISED_ERROR' => 'You do not have permission to access this page.',
+ 'NOT_AUTHENTICATED_ERROR' => 'You must log in to access this page.',
+ 'INTERNAL_SERVER_ERROR_ERROR' => 'An unknown error occured.',
+));
diff --git a/phpBB/web.config b/phpBB/web.config
index a73c328626..e31a48b991 100644
--- a/phpBB/web.config
+++ b/phpBB/web.config
@@ -12,6 +12,18 @@
</hiddenSegments>
</requestFiltering>
</security>
+ <rewrite>
+ <rules>
+ <rule name="Route through app.php" >
+ <match url="(.*)" ignoreCase="true" />
+ <conditions>
+ <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
+ <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
+ </conditions>
+ <action type="Rewrite" url="app.php" appendQueryString="false" />
+ </rule>
+ </rules>
+ </rewrite>
</system.webServer>
<location path="images/avatars">
<system.webServer>
diff --git a/tests/controller/config/routing.yml b/tests/controller/config/routing.yml
new file mode 100644
index 0000000000..175b11f130
--- /dev/null
+++ b/tests/controller/config/routing.yml
@@ -0,0 +1,3 @@
+core_controller:
+ pattern: /core_foo
+ defaults: { _controller: core_foo.controller:bar }
diff --git a/tests/controller/config/services.yml b/tests/controller/config/services.yml
new file mode 100644
index 0000000000..f1bd047489
--- /dev/null
+++ b/tests/controller/config/services.yml
@@ -0,0 +1,3 @@
+services:
+ core_foo.controller:
+ class: phpbb_controller_foo
diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php
new file mode 100644
index 0000000000..38f58c80a0
--- /dev/null
+++ b/tests/controller/controller_test.php
@@ -0,0 +1,75 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
+
+class phpbb_controller_test extends phpbb_test_case
+{
+ public function setUp()
+ {
+ $this->extension_manager = new phpbb_mock_extension_manager(
+ dirname(__FILE__) . '/',
+ array(
+ 'foo' => array(
+ 'ext_name' => 'foo',
+ 'ext_active' => '1',
+ 'ext_path' => 'ext/foo/',
+ ),
+ ));
+ }
+
+ public function test_provider()
+ {
+ $provider = new phpbb_controller_provider;
+ $routes = $provider
+ ->get_paths($this->extension_manager->get_finder())
+ ->find('./tests/controller/');
+
+ // This will need to be updated if any new routes are defined
+ $this->assertEquals(2, count($routes));
+ }
+
+ public function test_controller_resolver()
+ {
+ $container = new ContainerBuilder();
+ // For some reason, I cannot get it to load more than one services
+ // file at a time, even when givein multiple paths
+ // So instead, I am looping through all of the paths
+ foreach (array(__DIR__.'/config', __DIR__.'/ext/foo/config') as $path)
+ {
+ $loader = new YamlFileLoader($container, new FileLocator($path));
+ $loader->load('services.yml');
+ }
+
+ // Autoloading classes within the tests folder does not work
+ // so I'll include them manually
+ if (!class_exists('phpbb_ext_foo_controller'))
+ {
+ include(__DIR__.'/ext/foo/controller.php');
+ }
+ if (!class_exists('phpbb_controller_foo'))
+ {
+ include(__DIR__.'/includes/controller/foo.php');
+ }
+
+ $resolver = new phpbb_controller_resolver(new phpbb_user, $container);
+ $symfony_request = new Request(array(), array(), array('_controller' => 'foo.controller:handle'));
+
+ $this->assertEquals($resolver->getController($symfony_request), array(new phpbb_ext_foo_controller, 'handle'));
+
+ $symfony_request = new Request(array(), array(), array('_controller' => 'core_foo.controller:bar'));
+
+ $this->assertEquals($resolver->getController($symfony_request), array(new phpbb_controller_foo, 'bar'));
+ }
+}
diff --git a/tests/controller/ext/foo/config/routing.yml b/tests/controller/ext/foo/config/routing.yml
new file mode 100644
index 0000000000..4799fec37d
--- /dev/null
+++ b/tests/controller/ext/foo/config/routing.yml
@@ -0,0 +1,3 @@
+controller1:
+ pattern: /foo
+ defaults: { _controller: foo.controller:handle }
diff --git a/tests/controller/ext/foo/config/services.yml b/tests/controller/ext/foo/config/services.yml
new file mode 100644
index 0000000000..ce0e18c610
--- /dev/null
+++ b/tests/controller/ext/foo/config/services.yml
@@ -0,0 +1,3 @@
+services:
+ foo.controller:
+ class: phpbb_ext_foo_controller
diff --git a/tests/controller/ext/foo/controller.php b/tests/controller/ext/foo/controller.php
new file mode 100644
index 0000000000..72b8560c20
--- /dev/null
+++ b/tests/controller/ext/foo/controller.php
@@ -0,0 +1,23 @@
+<?php
+
+use Symfony\Component\HttpFoundation\Response;
+
+class phpbb_ext_foo_controller
+{
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ }
+
+ /**
+ * Handle method
+ *
+ * @return null
+ */
+ public function handle()
+ {
+ return new Response('Test', 200);
+ }
+}
diff --git a/tests/controller/includes/controller/foo.php b/tests/controller/includes/controller/foo.php
new file mode 100644
index 0000000000..cd1c4849cb
--- /dev/null
+++ b/tests/controller/includes/controller/foo.php
@@ -0,0 +1,23 @@
+<?php
+
+use Symfony\Component\HttpFoundation\Response;
+
+class phpbb_controller_foo
+{
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ }
+
+ /**
+ * Bar method
+ *
+ * @return null
+ */
+ public function bar()
+ {
+ return new Response('bar()', 200);
+ }
+}