[feature/controller] Implement a front controller

PHPBB3-10864
This commit is contained in:
David King 2012-10-19 19:54:19 -04:00
parent 65dde648ca
commit 06158693c7
23 changed files with 818 additions and 59 deletions

View file

@ -1,12 +1,17 @@
<IfModule mod_rewrite.c>
RewriteEngine on
# #
# Uncomment the statement below if you want to make use of # Uncomment the statement below if you want to make use of
# HTTP authentication and it does not already work. # HTTP authentication and it does not already work.
# This could be required if you are for example using PHP via Apache CGI. # 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] #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"> <Files "config.php">
Order Allow,Deny Order Allow,Deny

29
phpBB/app.php Normal file
View file

@ -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);

View file

@ -8,9 +8,7 @@
* Minimum Requirement: PHP 5.3.3 * Minimum Requirement: PHP 5.3.3
*/ */
use Symfony\Component\Config\FileLocator; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
/** /**
*/ */
@ -106,6 +104,11 @@ $phpbb_class_loader_ext->set_cache($phpbb_container->get('cache.driver'));
// set up caching // set up caching
$cache = $phpbb_container->get('cache'); $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 // Instantiate some basic classes
$phpbb_dispatcher = $phpbb_container->get('dispatcher'); $phpbb_dispatcher = $phpbb_container->get('dispatcher');
$request = $phpbb_container->get('request'); $request = $phpbb_container->get('request');

View file

@ -5,6 +5,7 @@
"symfony/dependency-injection": "2.1.*", "symfony/dependency-injection": "2.1.*",
"symfony/event-dispatcher": "2.1.*", "symfony/event-dispatcher": "2.1.*",
"symfony/http-kernel": "2.1.*", "symfony/http-kernel": "2.1.*",
"symfony/routing": "2.1.*",
"symfony/yaml": "2.1.*" "symfony/yaml": "2.1.*"
}, },
"require-dev": { "require-dev": {

62
phpBB/composer.lock generated
View file

@ -1,5 +1,5 @@
{ {
"hash": "407cc89f4bb0e409146c863dee51b0ae", "hash": "efb4768ba71d7cd2c84baa0610d84067",
"packages": [ "packages": [
{ {
"name": "symfony/config", "name": "symfony/config",
@ -272,6 +272,64 @@
"description": "Symfony HttpKernel Component", "description": "Symfony HttpKernel Component",
"homepage": "http://symfony.com" "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", "name": "symfony/yaml",
"version": "v2.1.3", "version": "v2.1.3",
@ -331,7 +389,7 @@
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://github.com/fabpot/Goutte/zipball/f2940f9c7c1f409159f5e9f512e575946c5cff48", "url": "https://github.com/fabpot/Goutte/archive/f2940f9c7c1f409159f5e9f512e575946c5cff48.zip",
"reference": "f2940f9c7c1f409159f5e9f512e575946c5cff48", "reference": "f2940f9c7c1f409159f5e9f512e575946c5cff48",
"shasum": "" "shasum": ""
}, },

9
phpBB/config/routing.yml Normal file
View file

@ -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.
#

View file

@ -44,6 +44,27 @@ services:
- @cache.driver - @cache.driver
- %tables.config% - %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: cron.task_collection:
class: phpbb_di_service_collection class: phpbb_di_service_collection
arguments: arguments:
@ -92,10 +113,46 @@ services:
- %core.root_path% - %core.root_path%
- .%core.php_ext% - .%core.php_ext%
- @cache.driver - @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: request:
class: phpbb_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: style:
class: phpbb_style class: phpbb_style
arguments: arguments:
@ -132,5 +189,11 @@ services:
template_context: template_context:
class: phpbb_template_context class: phpbb_template_context
url_matcher:
class: Symfony\Component\Routing\Matcher\UrlMatcher
arguments:
- @controller.route_collection
- @request.context
user: user:
class: phpbb_user class: phpbb_user

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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());
}
}

View file

@ -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) function append_sid($url, $params = false, $is_amp = true, $session_id = false)
{ {
global $_SID, $_EXTRA_URL, $phpbb_hook; 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))) 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; $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; $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 // Determine board url - we may need it later
$board_url = generate_board_url() . '/'; $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 // Send a proper content-language to the output
$user_lang = $user->lang['USER_LANG']; $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 * 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 $db, $config, $template, $user, $auth, $cache, $starttime, $phpbb_root_path, $phpEx;
global $request, $phpbb_dispatcher; 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(); garbage_collection();
exit_handler();
if ($exit_handler)
{
exit_handler();
}
} }
/** /**

View file

@ -224,15 +224,9 @@ class phpbb_template
*/ */
public function assign_display($handle, $template_var = '', $return_content = true) public function assign_display($handle, $template_var = '', $return_content = true)
{ {
ob_start(); $contents = $this->return_display($handle);
$result = $this->display($handle);
$contents = ob_get_clean();
if ($result === false)
{
return false;
}
if ($return_content) if ($return_content === true || empty($template_var) || $contents === false)
{ {
return $contents; return $contents;
} }
@ -242,6 +236,15 @@ class phpbb_template
return true; 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 * Obtains a template renderer for a template identified by specified
* handle. The template renderer can display the template later. * handle. The template renderer can display the template later.

View file

@ -17,48 +17,12 @@ define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './'; $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1); $phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx); include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
// Start session management // Start session management
$user->session_begin(); $user->session_begin();
$auth->acl($user->data); $auth->acl($user->data);
$user->setup(); $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();
}
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
$user->add_lang('viewforum');
display_forums('', $config['load_moderators']); display_forums('', $config['load_moderators']);

59
phpBB/language/en/app.php Normal file
View file

@ -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.',
));

View file

@ -12,6 +12,18 @@
</hiddenSegments> </hiddenSegments>
</requestFiltering> </requestFiltering>
</security> </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> </system.webServer>
<location path="images/avatars"> <location path="images/avatars">
<system.webServer> <system.webServer>

View file

@ -0,0 +1,3 @@
core_controller:
pattern: /core_foo
defaults: { _controller: core_foo.controller:bar }

View file

@ -0,0 +1,3 @@
services:
core_foo.controller:
class: phpbb_controller_foo

View file

@ -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'));
}
}

View file

@ -0,0 +1,3 @@
controller1:
pattern: /foo
defaults: { _controller: foo.controller:handle }

View file

@ -0,0 +1,3 @@
services:
foo.controller:
class: phpbb_ext_foo_controller

View file

@ -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);
}
}

View file

@ -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);
}
}