From 06158693c7b846518abfe9d72491fc7376e457f3 Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 19 Oct 2012 19:54:19 -0400 Subject: [feature/controller] Implement a front controller PHPBB3-10864 --- phpBB/includes/controller/helper.php | 142 +++++++++++++++++++++++++ phpBB/includes/controller/provider.php | 94 ++++++++++++++++ phpBB/includes/controller/resolver.php | 123 +++++++++++++++++++++ phpBB/includes/controller/route_collection.php | 36 +++++++ phpBB/includes/functions.php | 35 +++++- phpBB/includes/template/template.php | 19 ++-- 6 files changed, 436 insertions(+), 13 deletions(-) create mode 100644 phpBB/includes/controller/helper.php create mode 100644 phpBB/includes/controller/provider.php create mode 100644 phpBB/includes/controller/resolver.php create mode 100644 phpBB/includes/controller/route_collection.php (limited to 'phpBB/includes') 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 @@ +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 @@ +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 @@ +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 @@ +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. -- cgit v1.2.1 From 067a77073015adf56fb3730417ac2a6d62ce454c Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 20 Oct 2012 17:06:04 -0400 Subject: [feature/controller] Transfer kernel-related stuff from container PR PHPBB3-10864 --- phpBB/includes/event/kernel_compiler_pass.php | 72 ++++++++++++++++++++ phpBB/includes/event/kernel_subscriber.php | 94 +++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 phpBB/includes/event/kernel_compiler_pass.php create mode 100644 phpBB/includes/event/kernel_subscriber.php (limited to 'phpBB/includes') diff --git a/phpBB/includes/event/kernel_compiler_pass.php b/phpBB/includes/event/kernel_compiler_pass.php new file mode 100644 index 0000000000..18b6661cd4 --- /dev/null +++ b/phpBB/includes/event/kernel_compiler_pass.php @@ -0,0 +1,72 @@ +getDefinition('dispatcher'); + $user = $container->get('user'); + + foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events) + { + foreach ($events as $event) + { + $priority = isset($event['priority']) ? $event['priority'] : 0; + + if (!isset($event['event'])) + { + throw new InvalidArgumentException($user->lang('NO_EVENT_ATTRIBUTE', $id)); + } + + if (!isset($event['method'])) + { + $event['method'] = 'on'.preg_replace(array( + '/(?<=\b)[a-z]/ie', + '/[^a-z0-9]/i' + ), array('strtoupper("\\0")', ''), $event['event']); + } + + $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); + } + } + + foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) + { + // We must assume that the class value has been correctly filled, even if the service is created by a factory + $class = $container->getDefinition($id)->getClass(); + + $refClass = new ReflectionClass($class); + $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; + if (!$refClass->implementsInterface($interface)) + { + throw new InvalidArgumentException($user->lang('SUBSCRIBER_WRONG_TYPE', $id, $interface)); + } + + $definition->addMethodCall('addSubscriberService', array($id, $class)); + } + } +} diff --git a/phpBB/includes/event/kernel_subscriber.php b/phpBB/includes/event/kernel_subscriber.php new file mode 100644 index 0000000000..9737d9bc23 --- /dev/null +++ b/phpBB/includes/event/kernel_subscriber.php @@ -0,0 +1,94 @@ +template = $template; + $this->user = $user; + } + + /** + * This listener is run when the KernelEvents::TERMINATE event is triggered + * This comes after a Response has been sent to the server; this is + * primarily cleanup stuff. + * + * @param PostResponseEvent $event + * @return null + */ + public function on_kernel_terminate(PostResponseEvent $event) + { + exit_handler(); + } + + /** + * This listener is run when the KernelEvents::EXCEPTION event is triggered + * + * @param GetResponseForExceptionEvent $event + * @return null + */ + public function on_kernel_exception(GetResponseForExceptionEvent $event) + { + page_header($this->user->lang('INFORMATION')); + + $this->template->assign_vars(array( + 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'), + 'MESSAGE_TEXT' => $event->getException()->getMessage(), + )); + + $this->template->set_filenames(array( + 'body' => 'message_body.html', + )); + + page_footer(true, false, false); + + $event->setResponse(new Response($this->template->return_display('body'), 404)); + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::TERMINATE => 'on_kernel_terminate', + KernelEvents::EXCEPTION => 'on_kernel_exception', + ); + } +} -- cgit v1.2.1 From 5c86a1660d436cf16448ae6c978237833e3e86b7 Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 20 Oct 2012 17:16:14 -0400 Subject: [feature/controller] Don't allow a kernel listener to be added with no method PHPBB3-10864 --- phpBB/includes/event/kernel_compiler_pass.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/event/kernel_compiler_pass.php b/phpBB/includes/event/kernel_compiler_pass.php index 18b6661cd4..9a650bc404 100644 --- a/phpBB/includes/event/kernel_compiler_pass.php +++ b/phpBB/includes/event/kernel_compiler_pass.php @@ -44,10 +44,7 @@ class phpbb_event_kernel_compiler_pass implements CompilerPassInterface if (!isset($event['method'])) { - $event['method'] = 'on'.preg_replace(array( - '/(?<=\b)[a-z]/ie', - '/[^a-z0-9]/i' - ), array('strtoupper("\\0")', ''), $event['event']); + throw new InvalidArgumentException($user->lang('NO_METHOD_ATTRIBUTE', $id)); } $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); -- cgit v1.2.1 From 97957d679250c642969a09b002f4125889a5f4fa Mon Sep 17 00:00:00 2001 From: David King Date: Sun, 21 Oct 2012 16:37:03 -0400 Subject: [feature/controller-new] Rename kernel compiler pass class PHPBB3-10864 --- phpBB/includes/di/pass/kernel.php | 69 +++++++++++++++++++++++++++ phpBB/includes/event/kernel_compiler_pass.php | 69 --------------------------- 2 files changed, 69 insertions(+), 69 deletions(-) create mode 100644 phpBB/includes/di/pass/kernel.php delete mode 100644 phpBB/includes/event/kernel_compiler_pass.php (limited to 'phpBB/includes') diff --git a/phpBB/includes/di/pass/kernel.php b/phpBB/includes/di/pass/kernel.php new file mode 100644 index 0000000000..7b190a6236 --- /dev/null +++ b/phpBB/includes/di/pass/kernel.php @@ -0,0 +1,69 @@ +getDefinition('dispatcher'); + $user = $container->get('user'); + + foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events) + { + foreach ($events as $event) + { + $priority = isset($event['priority']) ? $event['priority'] : 0; + + if (!isset($event['event'])) + { + throw new InvalidArgumentException($user->lang('NO_EVENT_ATTRIBUTE', $id)); + } + + if (!isset($event['method'])) + { + throw new InvalidArgumentException($user->lang('NO_METHOD_ATTRIBUTE', $id)); + } + + $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); + } + } + + foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) + { + // We must assume that the class value has been correctly filled, even if the service is created by a factory + $class = $container->getDefinition($id)->getClass(); + + $refClass = new ReflectionClass($class); + $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; + if (!$refClass->implementsInterface($interface)) + { + throw new InvalidArgumentException($user->lang('SUBSCRIBER_WRONG_TYPE', $id, $interface)); + } + + $definition->addMethodCall('addSubscriberService', array($id, $class)); + } + } +} diff --git a/phpBB/includes/event/kernel_compiler_pass.php b/phpBB/includes/event/kernel_compiler_pass.php deleted file mode 100644 index 9a650bc404..0000000000 --- a/phpBB/includes/event/kernel_compiler_pass.php +++ /dev/null @@ -1,69 +0,0 @@ -getDefinition('dispatcher'); - $user = $container->get('user'); - - foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events) - { - foreach ($events as $event) - { - $priority = isset($event['priority']) ? $event['priority'] : 0; - - if (!isset($event['event'])) - { - throw new InvalidArgumentException($user->lang('NO_EVENT_ATTRIBUTE', $id)); - } - - if (!isset($event['method'])) - { - throw new InvalidArgumentException($user->lang('NO_METHOD_ATTRIBUTE', $id)); - } - - $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); - } - } - - foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) - { - // We must assume that the class value has been correctly filled, even if the service is created by a factory - $class = $container->getDefinition($id)->getClass(); - - $refClass = new ReflectionClass($class); - $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; - if (!$refClass->implementsInterface($interface)) - { - throw new InvalidArgumentException($user->lang('SUBSCRIBER_WRONG_TYPE', $id, $interface)); - } - - $definition->addMethodCall('addSubscriberService', array($id, $class)); - } - } -} -- cgit v1.2.1 From 4e1f17a87dc6fefa30becc594a7f41e7f6293cad Mon Sep 17 00:00:00 2001 From: David King Date: Sun, 11 Nov 2012 14:17:31 -0500 Subject: [feature/controller] includes/functions.php is included by default PHPBB3-10864 --- phpBB/includes/controller/helper.php | 5 ----- 1 file changed, 5 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 1998ea6733..f3127fd1fc 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -79,11 +79,6 @@ class phpbb_controller_helper */ 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( -- cgit v1.2.1 From 7687f069611b35f81c6d0fc87e46b9bb0821d616 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 13 Nov 2012 09:26:31 -0500 Subject: [feature/controller] Inject dependencies instead of container PHPBB3-10864 --- phpBB/includes/controller/helper.php | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index f3127fd1fc..0fc3ba0c67 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -15,9 +15,7 @@ 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 @@ -25,12 +23,6 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; */ class phpbb_controller_helper { - /** - * Container - * @var ContainerBuilder - */ - protected $container; - /** * Template object * @var phpbb_template @@ -38,13 +30,19 @@ class phpbb_controller_helper protected $template; /** - * phpBB Root Path + * User object + * @var phpbb_user + */ + protected $user; + + /** + * phpBB root path * @var string */ - protected $phpbb_root_path; + protected $root_path; /** - * PHP Extension + * PHP extension * @var string */ protected $php_ext; @@ -58,15 +56,17 @@ class phpbb_controller_helper /** * Constructor * - * @param ContainerBuilder $container DI Container + * @param phpbb_template $template Template object + * @param phpbb_user $user User object + * @param string $root_path phpBB root path + * @param string $php_ext PHP extension */ - public function __construct(ContainerBuilder $container) + public function __construct(phpbb_template $template, phpbb_user $user, $root_path, $php_ext) { - $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'); + $this->template = $template; + $this->user = $user; + $this->root_path = $root_path; + $this->php_ext = $php_ext; } /** @@ -101,7 +101,7 @@ class phpbb_controller_helper */ public function url(array $url_parts, $query = '') { - return append_sid($this->phpbb_root_path . $this->url_base . implode('/', $url_parts), $query); + return append_sid($this->root_path . $this->url_base . implode('/', $url_parts), $query); } /** @@ -129,9 +129,9 @@ class phpbb_controller_helper { $this->template->assign_vars(array( 'MESSAGE_TEXT' => $message, - 'MESSAGE_TITLE' => $this->container->get('user')->lang('INFORMATION'), + 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'), )); - return $this->render('message_body.html', $this->container->get('user')->lang('INFORMATION'), $code); + return $this->render('message_body.html', $this->user->lang('INFORMATION'), $code); } } -- cgit v1.2.1 From 4b6d538b062a56f55ba221ac8437b4bfc712a475 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 13 Nov 2012 09:28:56 -0500 Subject: [feature/controller] Rename kernel pass class properly PHPBB3-10864 --- phpBB/includes/di/pass/kernel.php | 69 ---------------------------------- phpBB/includes/di/pass/kernel_pass.php | 69 ++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 69 deletions(-) delete mode 100644 phpBB/includes/di/pass/kernel.php create mode 100644 phpBB/includes/di/pass/kernel_pass.php (limited to 'phpBB/includes') diff --git a/phpBB/includes/di/pass/kernel.php b/phpBB/includes/di/pass/kernel.php deleted file mode 100644 index 7b190a6236..0000000000 --- a/phpBB/includes/di/pass/kernel.php +++ /dev/null @@ -1,69 +0,0 @@ -getDefinition('dispatcher'); - $user = $container->get('user'); - - foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events) - { - foreach ($events as $event) - { - $priority = isset($event['priority']) ? $event['priority'] : 0; - - if (!isset($event['event'])) - { - throw new InvalidArgumentException($user->lang('NO_EVENT_ATTRIBUTE', $id)); - } - - if (!isset($event['method'])) - { - throw new InvalidArgumentException($user->lang('NO_METHOD_ATTRIBUTE', $id)); - } - - $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); - } - } - - foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) - { - // We must assume that the class value has been correctly filled, even if the service is created by a factory - $class = $container->getDefinition($id)->getClass(); - - $refClass = new ReflectionClass($class); - $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; - if (!$refClass->implementsInterface($interface)) - { - throw new InvalidArgumentException($user->lang('SUBSCRIBER_WRONG_TYPE', $id, $interface)); - } - - $definition->addMethodCall('addSubscriberService', array($id, $class)); - } - } -} diff --git a/phpBB/includes/di/pass/kernel_pass.php b/phpBB/includes/di/pass/kernel_pass.php new file mode 100644 index 0000000000..d186ff2767 --- /dev/null +++ b/phpBB/includes/di/pass/kernel_pass.php @@ -0,0 +1,69 @@ +getDefinition('dispatcher'); + $user = $container->get('user'); + + foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events) + { + foreach ($events as $event) + { + $priority = isset($event['priority']) ? $event['priority'] : 0; + + if (!isset($event['event'])) + { + throw new InvalidArgumentException($user->lang('NO_EVENT_ATTRIBUTE', $id)); + } + + if (!isset($event['method'])) + { + throw new InvalidArgumentException($user->lang('NO_METHOD_ATTRIBUTE', $id)); + } + + $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); + } + } + + foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) + { + // We must assume that the class value has been correctly filled, even if the service is created by a factory + $class = $container->getDefinition($id)->getClass(); + + $refClass = new ReflectionClass($class); + $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; + if (!$refClass->implementsInterface($interface)) + { + throw new InvalidArgumentException($user->lang('SUBSCRIBER_WRONG_TYPE', $id, $interface)); + } + + $definition->addMethodCall('addSubscriberService', array($id, $class)); + } + } +} -- cgit v1.2.1 From ac29c7e9d982648ed64e0ef73bbebd67567c2d89 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 13 Nov 2012 09:43:53 -0500 Subject: [feature/controller] Rework assign_display(), use exceptions instead of return PHPBB3-10864 --- phpBB/includes/template/template.php | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index a48e8459d5..a6ae44969b 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -219,30 +219,45 @@ class phpbb_template * * @param string $handle Handle to operate on * @param string $template_var Template variable to assign compiled handle to - * @param bool $return_content If true return compiled handle, otherwise assign to $template_var - * @return bool|string false on failure, otherwise if $return_content is true return string of the compiled handle, otherwise return true + * @param bool $return_contents If true return compiled handle, otherwise assign to $template_var + * @return bool|string If $return_content is true return string of the compiled handle, otherwise return true + * @throws RuntimeException */ - public function assign_display($handle, $template_var = '', $return_content = true) + public function assign_display($handle, $template_var = '', $return_contents = true) { $contents = $this->return_display($handle); - if ($return_content === true || empty($template_var) || $contents === false) + if (!$template_var) { - return $contents; + throw new RuntimeException($this->user->lang('TEMPLATE_CANNOT_BE_ASSIGNED') } $this->assign_var($template_var, $contents); - return true; + // If !$return_content evaluates to true, true will be returned + // Otherwise, the value of $contents will be returned + return !$return_contents ?: $contents; } + /** + * Return the compiled template code as a string + * + * @param string $handle Handle to operate on + * @return string Compiled template code; can be output directly to page + * @throws RuntimeException + */ public function return_display($handle) { ob_start(); $result = $this->display($handle); $contents = ob_get_clean(); - return $result === false ? $result : $contents; + if ($result === false) + { + throw new RuntimeException($user->lang('TEMPLATE_HANDLE_NOT_FOUND')); + } + + return $contents; } /** -- cgit v1.2.1 From b5255d4ea4f9e5e1d8c2783555891a0d5a63aca2 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 13 Nov 2012 09:51:23 -0500 Subject: [feature/controller] Fix syntax error in template code PHPBB3-10864 --- phpBB/includes/template/template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index a6ae44969b..75bbbe2ef3 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -229,7 +229,7 @@ class phpbb_template if (!$template_var) { - throw new RuntimeException($this->user->lang('TEMPLATE_CANNOT_BE_ASSIGNED') + throw new RuntimeException($this->user->lang('TEMPLATE_CANNOT_BE_ASSIGNED')); } $this->assign_var($template_var, $contents); -- cgit v1.2.1 From ef46af8298e18c64b662375adb7eaa40342900a8 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 13 Nov 2012 09:57:51 -0500 Subject: [feature/controller] Don't attempt to assign if no variable is give PHPBB3-10864 --- phpBB/includes/template/template.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index 75bbbe2ef3..11d226d705 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -227,12 +227,15 @@ class phpbb_template { $contents = $this->return_display($handle); - if (!$template_var) + if (!$template_var && !$return_contents) { throw new RuntimeException($this->user->lang('TEMPLATE_CANNOT_BE_ASSIGNED')); } - $this->assign_var($template_var, $contents); + if ($template_var) + { + $this->assign_var($template_var, $contents); + } // If !$return_content evaluates to true, true will be returned // Otherwise, the value of $contents will be returned -- cgit v1.2.1 From 6900456e903a01c3df8d717de711480d347d287c Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 13 Nov 2012 10:41:11 -0500 Subject: [feature/controller] Revert changes to template class As per IRC, assign_display() effectively does what return_display() was added to do, so no change was needed. PHPBB3-10864 --- phpBB/includes/template/template.php | 1139 +++++++++++++++++----------------- 1 file changed, 559 insertions(+), 580 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index 11d226d705..00fe26b9b1 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -1,580 +1,559 @@ - $user->img('icon_contact', 'CONTACT', 'full'); -* -* More in-depth... -* yadayada -*/ - -/** -* Base Template class. -* @package phpBB3 -*/ -class phpbb_template -{ - /** - * Template context. - * Stores template data used during template rendering. - * @var phpbb_template_context - */ - private $context; - - /** - * Path of the cache directory for the template - * @var string - */ - public $cachepath = ''; - - /** - * phpBB root path - * @var string - */ - private $phpbb_root_path; - - /** - * PHP file extension - * @var string - */ - private $php_ext; - - /** - * phpBB config instance - * @var phpbb_config - */ - private $config; - - /** - * Current user - * @var phpbb_user - */ - private $user; - - /** - * Template locator - * @var phpbb_template_locator - */ - private $locator; - - /** - * Location of templates directory within style directories - * @var string - */ - public $template_path = 'template/'; - - /** - * Constructor. - * - * @param string $phpbb_root_path phpBB root path - * @param user $user current user - * @param phpbb_template_locator $locator template locator - * @param phpbb_template_context $context template context - */ - public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator, phpbb_template_context $context) - { - $this->phpbb_root_path = $phpbb_root_path; - $this->php_ext = $php_ext; - $this->config = $config; - $this->user = $user; - $this->locator = $locator; - $this->template_path = $this->locator->template_path; - $this->context = $context; - } - - /** - * Sets the template filenames for handles. - * - * @param array $filname_array Should be a hash of handle => filename pairs. - */ - public function set_filenames(array $filename_array) - { - $this->locator->set_filenames($filename_array); - - return true; - } - - /** - * Clears all variables and blocks assigned to this template. - */ - public function destroy() - { - $this->context->clear(); - } - - /** - * Reset/empty complete block - * - * @param string $blockname Name of block to destroy - */ - public function destroy_block_vars($blockname) - { - $this->context->destroy_block_vars($blockname); - } - - /** - * Display a template for provided handle. - * - * The template will be loaded and compiled, if necessary, first. - * - * This function calls hooks. - * - * @param string $handle Handle to display - * @return bool True on success, false on failure - */ - public function display($handle) - { - $result = $this->call_hook($handle, __FUNCTION__); - if ($result !== false) - { - return $result[0]; - } - - return $this->load_and_render($handle); - } - - /** - * Loads a template for $handle, compiling it if necessary, and - * renders the template. - * - * @param string $handle Template handle to render - * @return bool True on success, false on failure - */ - private function load_and_render($handle) - { - $renderer = $this->_tpl_load($handle); - - if ($renderer) - { - $renderer->render($this->context, $this->get_lang()); - return true; - } - else - { - return false; - } - } - - /** - * Calls hook if any is defined. - * - * @param string $handle Template handle being displayed. - * @param string $method Method name of the caller. - */ - private function call_hook($handle, $method) - { - global $phpbb_hook; - - if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) - { - if ($phpbb_hook->hook_return(array(__CLASS__, $method))) - { - $result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); - return array($result); - } - } - - return false; - } - - /** - * Obtains language array. - * This is either lang property of $user property, or if - * it is not set an empty array. - * @return array language entries - */ - public function get_lang() - { - if (isset($this->user->lang)) - { - $lang = $this->user->lang; - } - else - { - $lang = array(); - } - return $lang; - } - - /** - * Display the handle and assign the output to a template variable - * or return the compiled result. - * - * @param string $handle Handle to operate on - * @param string $template_var Template variable to assign compiled handle to - * @param bool $return_contents If true return compiled handle, otherwise assign to $template_var - * @return bool|string If $return_content is true return string of the compiled handle, otherwise return true - * @throws RuntimeException - */ - public function assign_display($handle, $template_var = '', $return_contents = true) - { - $contents = $this->return_display($handle); - - if (!$template_var && !$return_contents) - { - throw new RuntimeException($this->user->lang('TEMPLATE_CANNOT_BE_ASSIGNED')); - } - - if ($template_var) - { - $this->assign_var($template_var, $contents); - } - - // If !$return_content evaluates to true, true will be returned - // Otherwise, the value of $contents will be returned - return !$return_contents ?: $contents; - } - - /** - * Return the compiled template code as a string - * - * @param string $handle Handle to operate on - * @return string Compiled template code; can be output directly to page - * @throws RuntimeException - */ - public function return_display($handle) - { - ob_start(); - $result = $this->display($handle); - $contents = ob_get_clean(); - - if ($result === false) - { - throw new RuntimeException($user->lang('TEMPLATE_HANDLE_NOT_FOUND')); - } - - return $contents; - } - - /** - * Obtains a template renderer for a template identified by specified - * handle. The template renderer can display the template later. - * - * Template source will first be compiled into php code. - * If template cache is writable the compiled php code will be stored - * on filesystem and template will not be subsequently recompiled. - * If template cache is not writable template source will be recompiled - * every time it is needed. DEBUG define and load_tplcompile - * configuration setting may be used to force templates to be always - * recompiled. - * - * Returns an object implementing phpbb_template_renderer, or null - * if template loading or compilation failed. Call render() on the - * renderer to display the template. This will result in template - * contents sent to the output stream (unless, of course, output - * buffering is in effect). - * - * @param string $handle Handle of the template to load - * @return phpbb_template_renderer Template renderer object, or null on failure - * @uses phpbb_template_compile is used to compile template source - */ - private function _tpl_load($handle) - { - $output_file = $this->_compiled_file_for_handle($handle); - - $recompile = defined('DEBUG') || - !file_exists($output_file) || - @filesize($output_file) === 0; - - if ($recompile || $this->config['load_tplcompile']) - { - // Set only if a recompile or an mtime check are required. - $source_file = $this->locator->get_source_file_for_handle($handle); - - if (!$recompile && @filemtime($output_file) < @filemtime($source_file)) - { - $recompile = true; - } - } - - // Recompile page if the original template is newer, otherwise load the compiled version - if (!$recompile) - { - return new phpbb_template_renderer_include($output_file, $this); - } - - $compile = new phpbb_template_compile($this->config['tpl_allow_php'], $this->locator, $this->phpbb_root_path); - - if ($compile->compile_file_to_file($source_file, $output_file) !== false) - { - $renderer = new phpbb_template_renderer_include($output_file, $this); - } - else if (($code = $compile->compile_file($source_file)) !== false) - { - $renderer = new phpbb_template_renderer_eval($code, $this); - } - else - { - $renderer = null; - } - - return $renderer; - } - - /** - * Determines compiled file path for handle $handle. - * - * @param string $handle Template handle (i.e. "friendly" template name) - * @return string Compiled file path - */ - private function _compiled_file_for_handle($handle) - { - $source_file = $this->locator->get_filename_for_handle($handle); - $compiled_file = $this->cachepath . str_replace('/', '.', $source_file) . '.' . $this->php_ext; - return $compiled_file; - } - - /** - * Assign key variable pairs from an array - * - * @param array $vararray A hash of variable name => value pairs - */ - public function assign_vars(array $vararray) - { - foreach ($vararray as $key => $val) - { - $this->assign_var($key, $val); - } - } - - /** - * Assign a single scalar value to a single key. - * - * Value can be a string, an integer or a boolean. - * - * @param string $varname Variable name - * @param string $varval Value to assign to variable - */ - public function assign_var($varname, $varval) - { - $this->context->assign_var($varname, $varval); - } - - /** - * Append text to the string value stored in a key. - * - * Text is appended using the string concatenation operator (.). - * - * @param string $varname Variable name - * @param string $varval Value to append to variable - */ - public function append_var($varname, $varval) - { - $this->context->append_var($varname, $varval); - } - - // Docstring is copied from phpbb_template_context method with the same name. - /** - * Assign key variable pairs from an array to a specified block - * @param string $blockname Name of block to assign $vararray to - * @param array $vararray A hash of variable name => value pairs - */ - public function assign_block_vars($blockname, array $vararray) - { - return $this->context->assign_block_vars($blockname, $vararray); - } - - // Docstring is copied from phpbb_template_context method with the same name. - /** - * Change already assigned key variable pair (one-dimensional - single loop entry) - * - * An example of how to use this function: - * {@example alter_block_array.php} - * - * @param string $blockname the blockname, for example 'loop' - * @param array $vararray the var array to insert/add or merge - * @param mixed $key Key to search for - * - * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] - * - * int: Position [the position to change or insert at directly given] - * - * If key is false the position is set to 0 - * If key is true the position is set to the last entry - * - * @param string $mode Mode to execute (valid modes are 'insert' and 'change') - * - * If insert, the vararray is inserted at the given position (position counting from zero). - * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). - * - * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) - * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) - * - * @return bool false on error, true on success - */ - public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') - { - return $this->context->alter_block_array($blockname, $vararray, $key, $mode); - } - - /** - * Include a separate template. - * - * This function is marked public due to the way the template - * implementation uses it. It is actually an implementation function - * and should not be considered part of template class's public API. - * - * @param string $filename Template filename to include - * @param bool $include True to include the file, false to just load it - * @uses template_compile is used to compile uncached templates - */ - public function _tpl_include($filename, $include = true) - { - $this->locator->set_filenames(array($filename => $filename)); - - if (!$this->load_and_render($filename)) - { - // trigger_error cannot be used here, as the output already started - echo 'template->_tpl_include(): Failed including ' . htmlspecialchars($handle) . "\n"; - } - } - - /** - * Include a PHP file. - * - * If a relative path is passed in $filename, it is considered to be - * relative to board root ($phpbb_root_path). Absolute paths are - * also allowed. - * - * This function is marked public due to the way the template - * implementation uses it. It is actually an implementation function - * and should not be considered part of template class's public API. - * - * @param string $filename Path to PHP file to include - */ - public function _php_include($filename) - { - if (phpbb_is_absolute($filename)) - { - $file = $filename; - } - else - { - $file = $this->phpbb_root_path . $filename; - } - - if (!file_exists($file)) - { - // trigger_error cannot be used here, as the output already started - echo 'template->_php_include(): File ' . htmlspecialchars($file) . " does not exist\n"; - return; - } - include($file); - } - - /** - * Obtains filesystem path for a template file. - * - * The simplest use is specifying a single template file as a string - * in the first argument. This template file should be a basename - * of a template file in the selected style, or its parent styles - * if template inheritance is being utilized. - * - * Note: "selected style" is whatever style the style resource locator - * is configured for. - * - * The return value then will be a path, relative to the current - * directory or absolute, to the template file in the selected style - * or its closest parent. - * - * If the selected style does not have the template file being searched, - * (and if inheritance is involved, none of the parents have it either), - * false will be returned. - * - * Specifying true for $return_default will cause the function to - * return the first path which was checked for existence in the event - * that the template file was not found, instead of false. - * This is the path in the selected style itself, not any of its - * parents. - * - * $files can be given an array of templates instead of a single - * template. When given an array, the function will try to resolve - * each template in the array to a path, and will return the first - * path that exists, or false if none exist. - * - * If $return_full_path is false, then instead of returning a usable - * path (when the template is found) only the template's basename - * will be returned. This can be used to check which of the templates - * specified in $files exists, provided different file names are - * used for different templates. - * - * @param string or array $files List of templates to locate. If there is only - * one template, $files can be a string to make code easier to read. - * @param bool $return_default Determines what to return if template does not - * exist. If true, function will return location where template is - * supposed to be. If false, function will return false. - * @param bool $return_full_path If true, function will return full path - * to template. If false, function will return template file name. - * This parameter can be used to check which one of set of template - * files is available. - * @return string or boolean Source template path if template exists or $return_default is - * true. False if template does not exist and $return_default is false - */ - public function locate($files, $return_default = false, $return_full_path = true) - { - // add template path prefix - $templates = array(); - if (is_string($files)) - { - $templates[] = $this->template_path . $files; - } - else - { - foreach ($files as $file) - { - $templates[] = $this->template_path . $file; - } - } - - // use resource locator to find files - return $this->locator->get_first_file_location($templates, $return_default, $return_full_path); - } - - /** - * Include JS file - * - * @param string $file file name - * @param bool $locate True if file needs to be located - * @param bool $relative True if path is relative to phpBB root directory. Ignored if $locate == true - */ - public function _js_include($file, $locate = false, $relative = false) - { - // Locate file - if ($locate) - { - $located = $this->locator->get_first_file_location(array($file), false, true); - if ($located) - { - $file = $located; - } - } - else if ($relative) - { - $file = $this->phpbb_root_path . $file; - } - - $file .= (strpos($file, '?') === false) ? '?' : '&'; - $file .= 'assets_version=' . $this->config['assets_version']; - - // Add HTML code - $code = ''; - $this->context->append_var('SCRIPTS', $code); - } -} + $user->img('icon_contact', 'CONTACT', 'full'); +* +* More in-depth... +* yadayada +*/ + +/** +* Base Template class. +* @package phpBB3 +*/ +class phpbb_template +{ + /** + * Template context. + * Stores template data used during template rendering. + * @var phpbb_template_context + */ + private $context; + + /** + * Path of the cache directory for the template + * @var string + */ + public $cachepath = ''; + + /** + * phpBB root path + * @var string + */ + private $phpbb_root_path; + + /** + * PHP file extension + * @var string + */ + private $php_ext; + + /** + * phpBB config instance + * @var phpbb_config + */ + private $config; + + /** + * Current user + * @var phpbb_user + */ + private $user; + + /** + * Template locator + * @var phpbb_template_locator + */ + private $locator; + + /** + * Location of templates directory within style directories + * @var string + */ + public $template_path = 'template/'; + + /** + * Constructor. + * + * @param string $phpbb_root_path phpBB root path + * @param user $user current user + * @param phpbb_template_locator $locator template locator + * @param phpbb_template_context $context template context + */ + public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator, phpbb_template_context $context) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->config = $config; + $this->user = $user; + $this->locator = $locator; + $this->template_path = $this->locator->template_path; + $this->context = $context; + } + + /** + * Sets the template filenames for handles. + * + * @param array $filname_array Should be a hash of handle => filename pairs. + */ + public function set_filenames(array $filename_array) + { + $this->locator->set_filenames($filename_array); + + return true; + } + + /** + * Clears all variables and blocks assigned to this template. + */ + public function destroy() + { + $this->context->clear(); + } + + /** + * Reset/empty complete block + * + * @param string $blockname Name of block to destroy + */ + public function destroy_block_vars($blockname) + { + $this->context->destroy_block_vars($blockname); + } + + /** + * Display a template for provided handle. + * + * The template will be loaded and compiled, if necessary, first. + * + * This function calls hooks. + * + * @param string $handle Handle to display + * @return bool True on success, false on failure + */ + public function display($handle) + { + $result = $this->call_hook($handle, __FUNCTION__); + if ($result !== false) + { + return $result[0]; + } + + return $this->load_and_render($handle); + } + + /** + * Loads a template for $handle, compiling it if necessary, and + * renders the template. + * + * @param string $handle Template handle to render + * @return bool True on success, false on failure + */ + private function load_and_render($handle) + { + $renderer = $this->_tpl_load($handle); + + if ($renderer) + { + $renderer->render($this->context, $this->get_lang()); + return true; + } + else + { + return false; + } + } + + /** + * Calls hook if any is defined. + * + * @param string $handle Template handle being displayed. + * @param string $method Method name of the caller. + */ + private function call_hook($handle, $method) + { + global $phpbb_hook; + + if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) + { + if ($phpbb_hook->hook_return(array(__CLASS__, $method))) + { + $result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); + return array($result); + } + } + + return false; + } + + /** + * Obtains language array. + * This is either lang property of $user property, or if + * it is not set an empty array. + * @return array language entries + */ + public function get_lang() + { + if (isset($this->user->lang)) + { + $lang = $this->user->lang; + } + else + { + $lang = array(); + } + return $lang; + } + + /** + * Display the handle and assign the output to a template variable + * or return the compiled result. + * + * @param string $handle Handle to operate on + * @param string $template_var Template variable to assign compiled handle to + * @param bool $return_content If true return compiled handle, otherwise assign to $template_var + * @return bool|string false on failure, otherwise if $return_content is true return string of the compiled handle, otherwise return true + */ + 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; + } + + if ($return_content) + { + return $contents; + } + + $this->assign_var($template_var, $contents); + + return true; + } + + /** + * Obtains a template renderer for a template identified by specified + * handle. The template renderer can display the template later. + * + * Template source will first be compiled into php code. + * If template cache is writable the compiled php code will be stored + * on filesystem and template will not be subsequently recompiled. + * If template cache is not writable template source will be recompiled + * every time it is needed. DEBUG define and load_tplcompile + * configuration setting may be used to force templates to be always + * recompiled. + * + * Returns an object implementing phpbb_template_renderer, or null + * if template loading or compilation failed. Call render() on the + * renderer to display the template. This will result in template + * contents sent to the output stream (unless, of course, output + * buffering is in effect). + * + * @param string $handle Handle of the template to load + * @return phpbb_template_renderer Template renderer object, or null on failure + * @uses phpbb_template_compile is used to compile template source + */ + private function _tpl_load($handle) + { + $output_file = $this->_compiled_file_for_handle($handle); + + $recompile = defined('DEBUG') || + !file_exists($output_file) || + @filesize($output_file) === 0; + + if ($recompile || $this->config['load_tplcompile']) + { + // Set only if a recompile or an mtime check are required. + $source_file = $this->locator->get_source_file_for_handle($handle); + + if (!$recompile && @filemtime($output_file) < @filemtime($source_file)) + { + $recompile = true; + } + } + + // Recompile page if the original template is newer, otherwise load the compiled version + if (!$recompile) + { + return new phpbb_template_renderer_include($output_file, $this); + } + + $compile = new phpbb_template_compile($this->config['tpl_allow_php'], $this->locator, $this->phpbb_root_path); + + if ($compile->compile_file_to_file($source_file, $output_file) !== false) + { + $renderer = new phpbb_template_renderer_include($output_file, $this); + } + else if (($code = $compile->compile_file($source_file)) !== false) + { + $renderer = new phpbb_template_renderer_eval($code, $this); + } + else + { + $renderer = null; + } + + return $renderer; + } + + /** + * Determines compiled file path for handle $handle. + * + * @param string $handle Template handle (i.e. "friendly" template name) + * @return string Compiled file path + */ + private function _compiled_file_for_handle($handle) + { + $source_file = $this->locator->get_filename_for_handle($handle); + $compiled_file = $this->cachepath . str_replace('/', '.', $source_file) . '.' . $this->php_ext; + return $compiled_file; + } + + /** + * Assign key variable pairs from an array + * + * @param array $vararray A hash of variable name => value pairs + */ + public function assign_vars(array $vararray) + { + foreach ($vararray as $key => $val) + { + $this->assign_var($key, $val); + } + } + + /** + * Assign a single scalar value to a single key. + * + * Value can be a string, an integer or a boolean. + * + * @param string $varname Variable name + * @param string $varval Value to assign to variable + */ + public function assign_var($varname, $varval) + { + $this->context->assign_var($varname, $varval); + } + + /** + * Append text to the string value stored in a key. + * + * Text is appended using the string concatenation operator (.). + * + * @param string $varname Variable name + * @param string $varval Value to append to variable + */ + public function append_var($varname, $varval) + { + $this->context->append_var($varname, $varval); + } + + // Docstring is copied from phpbb_template_context method with the same name. + /** + * Assign key variable pairs from an array to a specified block + * @param string $blockname Name of block to assign $vararray to + * @param array $vararray A hash of variable name => value pairs + */ + public function assign_block_vars($blockname, array $vararray) + { + return $this->context->assign_block_vars($blockname, $vararray); + } + + // Docstring is copied from phpbb_template_context method with the same name. + /** + * Change already assigned key variable pair (one-dimensional - single loop entry) + * + * An example of how to use this function: + * {@example alter_block_array.php} + * + * @param string $blockname the blockname, for example 'loop' + * @param array $vararray the var array to insert/add or merge + * @param mixed $key Key to search for + * + * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] + * + * int: Position [the position to change or insert at directly given] + * + * If key is false the position is set to 0 + * If key is true the position is set to the last entry + * + * @param string $mode Mode to execute (valid modes are 'insert' and 'change') + * + * If insert, the vararray is inserted at the given position (position counting from zero). + * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). + * + * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) + * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) + * + * @return bool false on error, true on success + */ + public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') + { + return $this->context->alter_block_array($blockname, $vararray, $key, $mode); + } + + /** + * Include a separate template. + * + * This function is marked public due to the way the template + * implementation uses it. It is actually an implementation function + * and should not be considered part of template class's public API. + * + * @param string $filename Template filename to include + * @param bool $include True to include the file, false to just load it + * @uses template_compile is used to compile uncached templates + */ + public function _tpl_include($filename, $include = true) + { + $this->locator->set_filenames(array($filename => $filename)); + + if (!$this->load_and_render($filename)) + { + // trigger_error cannot be used here, as the output already started + echo 'template->_tpl_include(): Failed including ' . htmlspecialchars($handle) . "\n"; + } + } + + /** + * Include a PHP file. + * + * If a relative path is passed in $filename, it is considered to be + * relative to board root ($phpbb_root_path). Absolute paths are + * also allowed. + * + * This function is marked public due to the way the template + * implementation uses it. It is actually an implementation function + * and should not be considered part of template class's public API. + * + * @param string $filename Path to PHP file to include + */ + public function _php_include($filename) + { + if (phpbb_is_absolute($filename)) + { + $file = $filename; + } + else + { + $file = $this->phpbb_root_path . $filename; + } + + if (!file_exists($file)) + { + // trigger_error cannot be used here, as the output already started + echo 'template->_php_include(): File ' . htmlspecialchars($file) . " does not exist\n"; + return; + } + include($file); + } + + /** + * Obtains filesystem path for a template file. + * + * The simplest use is specifying a single template file as a string + * in the first argument. This template file should be a basename + * of a template file in the selected style, or its parent styles + * if template inheritance is being utilized. + * + * Note: "selected style" is whatever style the style resource locator + * is configured for. + * + * The return value then will be a path, relative to the current + * directory or absolute, to the template file in the selected style + * or its closest parent. + * + * If the selected style does not have the template file being searched, + * (and if inheritance is involved, none of the parents have it either), + * false will be returned. + * + * Specifying true for $return_default will cause the function to + * return the first path which was checked for existence in the event + * that the template file was not found, instead of false. + * This is the path in the selected style itself, not any of its + * parents. + * + * $files can be given an array of templates instead of a single + * template. When given an array, the function will try to resolve + * each template in the array to a path, and will return the first + * path that exists, or false if none exist. + * + * If $return_full_path is false, then instead of returning a usable + * path (when the template is found) only the template's basename + * will be returned. This can be used to check which of the templates + * specified in $files exists, provided different file names are + * used for different templates. + * + * @param string or array $files List of templates to locate. If there is only + * one template, $files can be a string to make code easier to read. + * @param bool $return_default Determines what to return if template does not + * exist. If true, function will return location where template is + * supposed to be. If false, function will return false. + * @param bool $return_full_path If true, function will return full path + * to template. If false, function will return template file name. + * This parameter can be used to check which one of set of template + * files is available. + * @return string or boolean Source template path if template exists or $return_default is + * true. False if template does not exist and $return_default is false + */ + public function locate($files, $return_default = false, $return_full_path = true) + { + // add template path prefix + $templates = array(); + if (is_string($files)) + { + $templates[] = $this->template_path . $files; + } + else + { + foreach ($files as $file) + { + $templates[] = $this->template_path . $file; + } + } + + // use resource locator to find files + return $this->locator->get_first_file_location($templates, $return_default, $return_full_path); + } + + /** + * Include JS file + * + * @param string $file file name + * @param bool $locate True if file needs to be located + * @param bool $relative True if path is relative to phpBB root directory. Ignored if $locate == true + */ + public function _js_include($file, $locate = false, $relative = false) + { + // Locate file + if ($locate) + { + $located = $this->locator->get_first_file_location(array($file), false, true); + if ($located) + { + $file = $located; + } + } + else if ($relative) + { + $file = $this->phpbb_root_path . $file; + } + + $file .= (strpos($file, '?') === false) ? '?' : '&'; + $file .= 'assets_version=' . $this->config['assets_version']; + + // Add HTML code + $code = ''; + $this->context->append_var('SCRIPTS', $code); + } +} -- cgit v1.2.1 From 2e594504596eaf6ab758240a1cd012dfea79fe77 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 13 Nov 2012 10:42:20 -0500 Subject: [feature/controller] Use assign_display() instead of return_display() The latter was deemed unnecessary at the moment. PHPBB3-10864 --- phpBB/includes/controller/helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 0fc3ba0c67..8bb4427382 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -87,7 +87,7 @@ class phpbb_controller_helper page_footer(true, false, false); - return new Response($this->template->return_display('body'), $status_code); + return new Response($this->template->assign_display('body'), $status_code); } /** -- cgit v1.2.1 From c6a5699325171ca12c540772ed4e6c0c55318ec5 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 13 Nov 2012 10:46:46 -0500 Subject: [feature/controller-new] Fix line endings PHPBB3-10864 --- phpBB/includes/template/template.php | 1118 +++++++++++++++++----------------- 1 file changed, 559 insertions(+), 559 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index 00fe26b9b1..8a7dc6b2f3 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -1,559 +1,559 @@ - $user->img('icon_contact', 'CONTACT', 'full'); -* -* More in-depth... -* yadayada -*/ - -/** -* Base Template class. -* @package phpBB3 -*/ -class phpbb_template -{ - /** - * Template context. - * Stores template data used during template rendering. - * @var phpbb_template_context - */ - private $context; - - /** - * Path of the cache directory for the template - * @var string - */ - public $cachepath = ''; - - /** - * phpBB root path - * @var string - */ - private $phpbb_root_path; - - /** - * PHP file extension - * @var string - */ - private $php_ext; - - /** - * phpBB config instance - * @var phpbb_config - */ - private $config; - - /** - * Current user - * @var phpbb_user - */ - private $user; - - /** - * Template locator - * @var phpbb_template_locator - */ - private $locator; - - /** - * Location of templates directory within style directories - * @var string - */ - public $template_path = 'template/'; - - /** - * Constructor. - * - * @param string $phpbb_root_path phpBB root path - * @param user $user current user - * @param phpbb_template_locator $locator template locator - * @param phpbb_template_context $context template context - */ - public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator, phpbb_template_context $context) - { - $this->phpbb_root_path = $phpbb_root_path; - $this->php_ext = $php_ext; - $this->config = $config; - $this->user = $user; - $this->locator = $locator; - $this->template_path = $this->locator->template_path; - $this->context = $context; - } - - /** - * Sets the template filenames for handles. - * - * @param array $filname_array Should be a hash of handle => filename pairs. - */ - public function set_filenames(array $filename_array) - { - $this->locator->set_filenames($filename_array); - - return true; - } - - /** - * Clears all variables and blocks assigned to this template. - */ - public function destroy() - { - $this->context->clear(); - } - - /** - * Reset/empty complete block - * - * @param string $blockname Name of block to destroy - */ - public function destroy_block_vars($blockname) - { - $this->context->destroy_block_vars($blockname); - } - - /** - * Display a template for provided handle. - * - * The template will be loaded and compiled, if necessary, first. - * - * This function calls hooks. - * - * @param string $handle Handle to display - * @return bool True on success, false on failure - */ - public function display($handle) - { - $result = $this->call_hook($handle, __FUNCTION__); - if ($result !== false) - { - return $result[0]; - } - - return $this->load_and_render($handle); - } - - /** - * Loads a template for $handle, compiling it if necessary, and - * renders the template. - * - * @param string $handle Template handle to render - * @return bool True on success, false on failure - */ - private function load_and_render($handle) - { - $renderer = $this->_tpl_load($handle); - - if ($renderer) - { - $renderer->render($this->context, $this->get_lang()); - return true; - } - else - { - return false; - } - } - - /** - * Calls hook if any is defined. - * - * @param string $handle Template handle being displayed. - * @param string $method Method name of the caller. - */ - private function call_hook($handle, $method) - { - global $phpbb_hook; - - if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) - { - if ($phpbb_hook->hook_return(array(__CLASS__, $method))) - { - $result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); - return array($result); - } - } - - return false; - } - - /** - * Obtains language array. - * This is either lang property of $user property, or if - * it is not set an empty array. - * @return array language entries - */ - public function get_lang() - { - if (isset($this->user->lang)) - { - $lang = $this->user->lang; - } - else - { - $lang = array(); - } - return $lang; - } - - /** - * Display the handle and assign the output to a template variable - * or return the compiled result. - * - * @param string $handle Handle to operate on - * @param string $template_var Template variable to assign compiled handle to - * @param bool $return_content If true return compiled handle, otherwise assign to $template_var - * @return bool|string false on failure, otherwise if $return_content is true return string of the compiled handle, otherwise return true - */ - 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; - } - - if ($return_content) - { - return $contents; - } - - $this->assign_var($template_var, $contents); - - return true; - } - - /** - * Obtains a template renderer for a template identified by specified - * handle. The template renderer can display the template later. - * - * Template source will first be compiled into php code. - * If template cache is writable the compiled php code will be stored - * on filesystem and template will not be subsequently recompiled. - * If template cache is not writable template source will be recompiled - * every time it is needed. DEBUG define and load_tplcompile - * configuration setting may be used to force templates to be always - * recompiled. - * - * Returns an object implementing phpbb_template_renderer, or null - * if template loading or compilation failed. Call render() on the - * renderer to display the template. This will result in template - * contents sent to the output stream (unless, of course, output - * buffering is in effect). - * - * @param string $handle Handle of the template to load - * @return phpbb_template_renderer Template renderer object, or null on failure - * @uses phpbb_template_compile is used to compile template source - */ - private function _tpl_load($handle) - { - $output_file = $this->_compiled_file_for_handle($handle); - - $recompile = defined('DEBUG') || - !file_exists($output_file) || - @filesize($output_file) === 0; - - if ($recompile || $this->config['load_tplcompile']) - { - // Set only if a recompile or an mtime check are required. - $source_file = $this->locator->get_source_file_for_handle($handle); - - if (!$recompile && @filemtime($output_file) < @filemtime($source_file)) - { - $recompile = true; - } - } - - // Recompile page if the original template is newer, otherwise load the compiled version - if (!$recompile) - { - return new phpbb_template_renderer_include($output_file, $this); - } - - $compile = new phpbb_template_compile($this->config['tpl_allow_php'], $this->locator, $this->phpbb_root_path); - - if ($compile->compile_file_to_file($source_file, $output_file) !== false) - { - $renderer = new phpbb_template_renderer_include($output_file, $this); - } - else if (($code = $compile->compile_file($source_file)) !== false) - { - $renderer = new phpbb_template_renderer_eval($code, $this); - } - else - { - $renderer = null; - } - - return $renderer; - } - - /** - * Determines compiled file path for handle $handle. - * - * @param string $handle Template handle (i.e. "friendly" template name) - * @return string Compiled file path - */ - private function _compiled_file_for_handle($handle) - { - $source_file = $this->locator->get_filename_for_handle($handle); - $compiled_file = $this->cachepath . str_replace('/', '.', $source_file) . '.' . $this->php_ext; - return $compiled_file; - } - - /** - * Assign key variable pairs from an array - * - * @param array $vararray A hash of variable name => value pairs - */ - public function assign_vars(array $vararray) - { - foreach ($vararray as $key => $val) - { - $this->assign_var($key, $val); - } - } - - /** - * Assign a single scalar value to a single key. - * - * Value can be a string, an integer or a boolean. - * - * @param string $varname Variable name - * @param string $varval Value to assign to variable - */ - public function assign_var($varname, $varval) - { - $this->context->assign_var($varname, $varval); - } - - /** - * Append text to the string value stored in a key. - * - * Text is appended using the string concatenation operator (.). - * - * @param string $varname Variable name - * @param string $varval Value to append to variable - */ - public function append_var($varname, $varval) - { - $this->context->append_var($varname, $varval); - } - - // Docstring is copied from phpbb_template_context method with the same name. - /** - * Assign key variable pairs from an array to a specified block - * @param string $blockname Name of block to assign $vararray to - * @param array $vararray A hash of variable name => value pairs - */ - public function assign_block_vars($blockname, array $vararray) - { - return $this->context->assign_block_vars($blockname, $vararray); - } - - // Docstring is copied from phpbb_template_context method with the same name. - /** - * Change already assigned key variable pair (one-dimensional - single loop entry) - * - * An example of how to use this function: - * {@example alter_block_array.php} - * - * @param string $blockname the blockname, for example 'loop' - * @param array $vararray the var array to insert/add or merge - * @param mixed $key Key to search for - * - * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] - * - * int: Position [the position to change or insert at directly given] - * - * If key is false the position is set to 0 - * If key is true the position is set to the last entry - * - * @param string $mode Mode to execute (valid modes are 'insert' and 'change') - * - * If insert, the vararray is inserted at the given position (position counting from zero). - * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). - * - * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) - * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) - * - * @return bool false on error, true on success - */ - public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') - { - return $this->context->alter_block_array($blockname, $vararray, $key, $mode); - } - - /** - * Include a separate template. - * - * This function is marked public due to the way the template - * implementation uses it. It is actually an implementation function - * and should not be considered part of template class's public API. - * - * @param string $filename Template filename to include - * @param bool $include True to include the file, false to just load it - * @uses template_compile is used to compile uncached templates - */ - public function _tpl_include($filename, $include = true) - { - $this->locator->set_filenames(array($filename => $filename)); - - if (!$this->load_and_render($filename)) - { - // trigger_error cannot be used here, as the output already started - echo 'template->_tpl_include(): Failed including ' . htmlspecialchars($handle) . "\n"; - } - } - - /** - * Include a PHP file. - * - * If a relative path is passed in $filename, it is considered to be - * relative to board root ($phpbb_root_path). Absolute paths are - * also allowed. - * - * This function is marked public due to the way the template - * implementation uses it. It is actually an implementation function - * and should not be considered part of template class's public API. - * - * @param string $filename Path to PHP file to include - */ - public function _php_include($filename) - { - if (phpbb_is_absolute($filename)) - { - $file = $filename; - } - else - { - $file = $this->phpbb_root_path . $filename; - } - - if (!file_exists($file)) - { - // trigger_error cannot be used here, as the output already started - echo 'template->_php_include(): File ' . htmlspecialchars($file) . " does not exist\n"; - return; - } - include($file); - } - - /** - * Obtains filesystem path for a template file. - * - * The simplest use is specifying a single template file as a string - * in the first argument. This template file should be a basename - * of a template file in the selected style, or its parent styles - * if template inheritance is being utilized. - * - * Note: "selected style" is whatever style the style resource locator - * is configured for. - * - * The return value then will be a path, relative to the current - * directory or absolute, to the template file in the selected style - * or its closest parent. - * - * If the selected style does not have the template file being searched, - * (and if inheritance is involved, none of the parents have it either), - * false will be returned. - * - * Specifying true for $return_default will cause the function to - * return the first path which was checked for existence in the event - * that the template file was not found, instead of false. - * This is the path in the selected style itself, not any of its - * parents. - * - * $files can be given an array of templates instead of a single - * template. When given an array, the function will try to resolve - * each template in the array to a path, and will return the first - * path that exists, or false if none exist. - * - * If $return_full_path is false, then instead of returning a usable - * path (when the template is found) only the template's basename - * will be returned. This can be used to check which of the templates - * specified in $files exists, provided different file names are - * used for different templates. - * - * @param string or array $files List of templates to locate. If there is only - * one template, $files can be a string to make code easier to read. - * @param bool $return_default Determines what to return if template does not - * exist. If true, function will return location where template is - * supposed to be. If false, function will return false. - * @param bool $return_full_path If true, function will return full path - * to template. If false, function will return template file name. - * This parameter can be used to check which one of set of template - * files is available. - * @return string or boolean Source template path if template exists or $return_default is - * true. False if template does not exist and $return_default is false - */ - public function locate($files, $return_default = false, $return_full_path = true) - { - // add template path prefix - $templates = array(); - if (is_string($files)) - { - $templates[] = $this->template_path . $files; - } - else - { - foreach ($files as $file) - { - $templates[] = $this->template_path . $file; - } - } - - // use resource locator to find files - return $this->locator->get_first_file_location($templates, $return_default, $return_full_path); - } - - /** - * Include JS file - * - * @param string $file file name - * @param bool $locate True if file needs to be located - * @param bool $relative True if path is relative to phpBB root directory. Ignored if $locate == true - */ - public function _js_include($file, $locate = false, $relative = false) - { - // Locate file - if ($locate) - { - $located = $this->locator->get_first_file_location(array($file), false, true); - if ($located) - { - $file = $located; - } - } - else if ($relative) - { - $file = $this->phpbb_root_path . $file; - } - - $file .= (strpos($file, '?') === false) ? '?' : '&'; - $file .= 'assets_version=' . $this->config['assets_version']; - - // Add HTML code - $code = ''; - $this->context->append_var('SCRIPTS', $code); - } -} + $user->img('icon_contact', 'CONTACT', 'full'); +* +* More in-depth... +* yadayada +*/ + +/** +* Base Template class. +* @package phpBB3 +*/ +class phpbb_template +{ + /** + * Template context. + * Stores template data used during template rendering. + * @var phpbb_template_context + */ + private $context; + + /** + * Path of the cache directory for the template + * @var string + */ + public $cachepath = ''; + + /** + * phpBB root path + * @var string + */ + private $phpbb_root_path; + + /** + * PHP file extension + * @var string + */ + private $php_ext; + + /** + * phpBB config instance + * @var phpbb_config + */ + private $config; + + /** + * Current user + * @var phpbb_user + */ + private $user; + + /** + * Template locator + * @var phpbb_template_locator + */ + private $locator; + + /** + * Location of templates directory within style directories + * @var string + */ + public $template_path = 'template/'; + + /** + * Constructor. + * + * @param string $phpbb_root_path phpBB root path + * @param user $user current user + * @param phpbb_template_locator $locator template locator + * @param phpbb_template_context $context template context + */ + public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator, phpbb_template_context $context) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->config = $config; + $this->user = $user; + $this->locator = $locator; + $this->template_path = $this->locator->template_path; + $this->context = $context; + } + + /** + * Sets the template filenames for handles. + * + * @param array $filname_array Should be a hash of handle => filename pairs. + */ + public function set_filenames(array $filename_array) + { + $this->locator->set_filenames($filename_array); + + return true; + } + + /** + * Clears all variables and blocks assigned to this template. + */ + public function destroy() + { + $this->context->clear(); + } + + /** + * Reset/empty complete block + * + * @param string $blockname Name of block to destroy + */ + public function destroy_block_vars($blockname) + { + $this->context->destroy_block_vars($blockname); + } + + /** + * Display a template for provided handle. + * + * The template will be loaded and compiled, if necessary, first. + * + * This function calls hooks. + * + * @param string $handle Handle to display + * @return bool True on success, false on failure + */ + public function display($handle) + { + $result = $this->call_hook($handle, __FUNCTION__); + if ($result !== false) + { + return $result[0]; + } + + return $this->load_and_render($handle); + } + + /** + * Loads a template for $handle, compiling it if necessary, and + * renders the template. + * + * @param string $handle Template handle to render + * @return bool True on success, false on failure + */ + private function load_and_render($handle) + { + $renderer = $this->_tpl_load($handle); + + if ($renderer) + { + $renderer->render($this->context, $this->get_lang()); + return true; + } + else + { + return false; + } + } + + /** + * Calls hook if any is defined. + * + * @param string $handle Template handle being displayed. + * @param string $method Method name of the caller. + */ + private function call_hook($handle, $method) + { + global $phpbb_hook; + + if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) + { + if ($phpbb_hook->hook_return(array(__CLASS__, $method))) + { + $result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); + return array($result); + } + } + + return false; + } + + /** + * Obtains language array. + * This is either lang property of $user property, or if + * it is not set an empty array. + * @return array language entries + */ + public function get_lang() + { + if (isset($this->user->lang)) + { + $lang = $this->user->lang; + } + else + { + $lang = array(); + } + return $lang; + } + + /** + * Display the handle and assign the output to a template variable + * or return the compiled result. + * + * @param string $handle Handle to operate on + * @param string $template_var Template variable to assign compiled handle to + * @param bool $return_content If true return compiled handle, otherwise assign to $template_var + * @return bool|string false on failure, otherwise if $return_content is true return string of the compiled handle, otherwise return true + */ + 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; + } + + if ($return_content) + { + return $contents; + } + + $this->assign_var($template_var, $contents); + + return true; + } + + /** + * Obtains a template renderer for a template identified by specified + * handle. The template renderer can display the template later. + * + * Template source will first be compiled into php code. + * If template cache is writable the compiled php code will be stored + * on filesystem and template will not be subsequently recompiled. + * If template cache is not writable template source will be recompiled + * every time it is needed. DEBUG define and load_tplcompile + * configuration setting may be used to force templates to be always + * recompiled. + * + * Returns an object implementing phpbb_template_renderer, or null + * if template loading or compilation failed. Call render() on the + * renderer to display the template. This will result in template + * contents sent to the output stream (unless, of course, output + * buffering is in effect). + * + * @param string $handle Handle of the template to load + * @return phpbb_template_renderer Template renderer object, or null on failure + * @uses phpbb_template_compile is used to compile template source + */ + private function _tpl_load($handle) + { + $output_file = $this->_compiled_file_for_handle($handle); + + $recompile = defined('DEBUG') || + !file_exists($output_file) || + @filesize($output_file) === 0; + + if ($recompile || $this->config['load_tplcompile']) + { + // Set only if a recompile or an mtime check are required. + $source_file = $this->locator->get_source_file_for_handle($handle); + + if (!$recompile && @filemtime($output_file) < @filemtime($source_file)) + { + $recompile = true; + } + } + + // Recompile page if the original template is newer, otherwise load the compiled version + if (!$recompile) + { + return new phpbb_template_renderer_include($output_file, $this); + } + + $compile = new phpbb_template_compile($this->config['tpl_allow_php'], $this->locator, $this->phpbb_root_path); + + if ($compile->compile_file_to_file($source_file, $output_file) !== false) + { + $renderer = new phpbb_template_renderer_include($output_file, $this); + } + else if (($code = $compile->compile_file($source_file)) !== false) + { + $renderer = new phpbb_template_renderer_eval($code, $this); + } + else + { + $renderer = null; + } + + return $renderer; + } + + /** + * Determines compiled file path for handle $handle. + * + * @param string $handle Template handle (i.e. "friendly" template name) + * @return string Compiled file path + */ + private function _compiled_file_for_handle($handle) + { + $source_file = $this->locator->get_filename_for_handle($handle); + $compiled_file = $this->cachepath . str_replace('/', '.', $source_file) . '.' . $this->php_ext; + return $compiled_file; + } + + /** + * Assign key variable pairs from an array + * + * @param array $vararray A hash of variable name => value pairs + */ + public function assign_vars(array $vararray) + { + foreach ($vararray as $key => $val) + { + $this->assign_var($key, $val); + } + } + + /** + * Assign a single scalar value to a single key. + * + * Value can be a string, an integer or a boolean. + * + * @param string $varname Variable name + * @param string $varval Value to assign to variable + */ + public function assign_var($varname, $varval) + { + $this->context->assign_var($varname, $varval); + } + + /** + * Append text to the string value stored in a key. + * + * Text is appended using the string concatenation operator (.). + * + * @param string $varname Variable name + * @param string $varval Value to append to variable + */ + public function append_var($varname, $varval) + { + $this->context->append_var($varname, $varval); + } + + // Docstring is copied from phpbb_template_context method with the same name. + /** + * Assign key variable pairs from an array to a specified block + * @param string $blockname Name of block to assign $vararray to + * @param array $vararray A hash of variable name => value pairs + */ + public function assign_block_vars($blockname, array $vararray) + { + return $this->context->assign_block_vars($blockname, $vararray); + } + + // Docstring is copied from phpbb_template_context method with the same name. + /** + * Change already assigned key variable pair (one-dimensional - single loop entry) + * + * An example of how to use this function: + * {@example alter_block_array.php} + * + * @param string $blockname the blockname, for example 'loop' + * @param array $vararray the var array to insert/add or merge + * @param mixed $key Key to search for + * + * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] + * + * int: Position [the position to change or insert at directly given] + * + * If key is false the position is set to 0 + * If key is true the position is set to the last entry + * + * @param string $mode Mode to execute (valid modes are 'insert' and 'change') + * + * If insert, the vararray is inserted at the given position (position counting from zero). + * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). + * + * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) + * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) + * + * @return bool false on error, true on success + */ + public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') + { + return $this->context->alter_block_array($blockname, $vararray, $key, $mode); + } + + /** + * Include a separate template. + * + * This function is marked public due to the way the template + * implementation uses it. It is actually an implementation function + * and should not be considered part of template class's public API. + * + * @param string $filename Template filename to include + * @param bool $include True to include the file, false to just load it + * @uses template_compile is used to compile uncached templates + */ + public function _tpl_include($filename, $include = true) + { + $this->locator->set_filenames(array($filename => $filename)); + + if (!$this->load_and_render($filename)) + { + // trigger_error cannot be used here, as the output already started + echo 'template->_tpl_include(): Failed including ' . htmlspecialchars($handle) . "\n"; + } + } + + /** + * Include a PHP file. + * + * If a relative path is passed in $filename, it is considered to be + * relative to board root ($phpbb_root_path). Absolute paths are + * also allowed. + * + * This function is marked public due to the way the template + * implementation uses it. It is actually an implementation function + * and should not be considered part of template class's public API. + * + * @param string $filename Path to PHP file to include + */ + public function _php_include($filename) + { + if (phpbb_is_absolute($filename)) + { + $file = $filename; + } + else + { + $file = $this->phpbb_root_path . $filename; + } + + if (!file_exists($file)) + { + // trigger_error cannot be used here, as the output already started + echo 'template->_php_include(): File ' . htmlspecialchars($file) . " does not exist\n"; + return; + } + include($file); + } + + /** + * Obtains filesystem path for a template file. + * + * The simplest use is specifying a single template file as a string + * in the first argument. This template file should be a basename + * of a template file in the selected style, or its parent styles + * if template inheritance is being utilized. + * + * Note: "selected style" is whatever style the style resource locator + * is configured for. + * + * The return value then will be a path, relative to the current + * directory or absolute, to the template file in the selected style + * or its closest parent. + * + * If the selected style does not have the template file being searched, + * (and if inheritance is involved, none of the parents have it either), + * false will be returned. + * + * Specifying true for $return_default will cause the function to + * return the first path which was checked for existence in the event + * that the template file was not found, instead of false. + * This is the path in the selected style itself, not any of its + * parents. + * + * $files can be given an array of templates instead of a single + * template. When given an array, the function will try to resolve + * each template in the array to a path, and will return the first + * path that exists, or false if none exist. + * + * If $return_full_path is false, then instead of returning a usable + * path (when the template is found) only the template's basename + * will be returned. This can be used to check which of the templates + * specified in $files exists, provided different file names are + * used for different templates. + * + * @param string or array $files List of templates to locate. If there is only + * one template, $files can be a string to make code easier to read. + * @param bool $return_default Determines what to return if template does not + * exist. If true, function will return location where template is + * supposed to be. If false, function will return false. + * @param bool $return_full_path If true, function will return full path + * to template. If false, function will return template file name. + * This parameter can be used to check which one of set of template + * files is available. + * @return string or boolean Source template path if template exists or $return_default is + * true. False if template does not exist and $return_default is false + */ + public function locate($files, $return_default = false, $return_full_path = true) + { + // add template path prefix + $templates = array(); + if (is_string($files)) + { + $templates[] = $this->template_path . $files; + } + else + { + foreach ($files as $file) + { + $templates[] = $this->template_path . $file; + } + } + + // use resource locator to find files + return $this->locator->get_first_file_location($templates, $return_default, $return_full_path); + } + + /** + * Include JS file + * + * @param string $file file name + * @param bool $locate True if file needs to be located + * @param bool $relative True if path is relative to phpBB root directory. Ignored if $locate == true + */ + public function _js_include($file, $locate = false, $relative = false) + { + // Locate file + if ($locate) + { + $located = $this->locator->get_first_file_location(array($file), false, true); + if ($located) + { + $file = $located; + } + } + else if ($relative) + { + $file = $this->phpbb_root_path . $file; + } + + $file .= (strpos($file, '?') === false) ? '?' : '&'; + $file .= 'assets_version=' . $this->config['assets_version']; + + // Add HTML code + $code = ''; + $this->context->append_var('SCRIPTS', $code); + } +} -- cgit v1.2.1 From d3aa8823b21990634f8b74676ac301739ddfc58b Mon Sep 17 00:00:00 2001 From: David King Date: Wed, 14 Nov 2012 15:42:13 -0500 Subject: [feature/controller] Use a dumped url matcher class to improve performance PHPBB3-10864 --- phpBB/includes/controller/route_collection.php | 36 ------------------ phpBB/includes/event/kernel_subscriber.php | 52 +++++++++++++++++++++++++- phpBB/includes/functions.php | 52 ++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 38 deletions(-) delete mode 100644 phpBB/includes/controller/route_collection.php (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/route_collection.php b/phpBB/includes/controller/route_collection.php deleted file mode 100644 index e6c7d3b543..0000000000 --- a/phpBB/includes/controller/route_collection.php +++ /dev/null @@ -1,36 +0,0 @@ -addCollection($provider->get_paths($finder)->find()); - } -} diff --git a/phpBB/includes/event/kernel_subscriber.php b/phpBB/includes/event/kernel_subscriber.php index 9737d9bc23..79ee4f4dc5 100644 --- a/phpBB/includes/event/kernel_subscriber.php +++ b/phpBB/includes/event/kernel_subscriber.php @@ -18,8 +18,11 @@ if (!defined('IN_PHPBB')) use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\PostResponseEvent; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\EventListener\RouterListener; +use Symfony\Component\Routing\RequestContext; class phpbb_event_kernel_subscriber implements EventSubscriberInterface { @@ -35,16 +38,40 @@ class phpbb_event_kernel_subscriber implements EventSubscriberInterface */ protected $user; + /** + * Extension finder object + * @var phpbb_extension_finder + */ + protected $finder; + + /** + * PHP extension + * @var string + */ + protected $php_ext; + + /** + * Root path + * @var string + */ + protected $root_path; + /** * Construct method * * @param phpbb_template $template Template object * @param phpbb_user $user User object + * @param phpbb_extension_finder $finder Extension finder object + * @param string $root_path Root path + * @param string $php_ext PHP extension */ - public function __construct(phpbb_template $template, phpbb_user $user) + public function __construct(phpbb_template $template, phpbb_user $user, phpbb_extension_finder $finder, $root_path, $php_ext) { $this->template = $template; $this->user = $user; + $this->finder = $finder; + $this->root_path = $root_path; + $this->php_ext = $php_ext; } /** @@ -81,12 +108,33 @@ class phpbb_event_kernel_subscriber implements EventSubscriberInterface page_footer(true, false, false); - $event->setResponse(new Response($this->template->return_display('body'), 404)); + $event->setResponse(new Response($this->template->assign_display('body'), 404)); + } + + /** + * This listener is run when the KernelEvents::REQUEST event is triggered + * + * This is responsible for setting up the routing information + * + * @param GetResponseEvent $event + * @return null + */ + public function on_kernel_request(GetResponseEvent $event) + { + $request = $event->getRequest(); + $context = new RequestContext(); + $context->fromRequest($request); + + $matcher = phpbb_create_url_matcher($this->finder, $context, $this->root_path, $this->php_ext); + + $router_listener = new RouterListener($matcher, $context); + $router_listener->onKernelRequest($event); } public static function getSubscribedEvents() { return array( + KernelEvents::REQUEST => 'on_kernel_request', KernelEvents::TERMINATE => 'on_kernel_terminate', KernelEvents::EXCEPTION => 'on_kernel_exception', ); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index fb05b74cd3..7cf5611dca 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -7,6 +7,9 @@ * */ +use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; +use Symfony\Component\Routing\RequestContext; + /** * @ignore */ @@ -5444,3 +5447,52 @@ function phpbb_to_numeric($input) { return ($input > PHP_INT_MAX) ? (float) $input : (int) $input; } + +/** +* Create and/or return the cached phpbb_url_matcher class +* +* If the class already exists, it instantiates it +* +* @param phpbb_extension_finder $finder Extension finder +* @param RequestContext $context Symfony RequestContext object +* @param string $root_path Root path +* @param string $php_ext PHP extension +* @return phpbb_url_matcher +*/ +function phpbb_create_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) +{ + $matcher = phpbb_load_url_matcher($finder, $context, $root_path, $php_ext); + if ($matcher === false) + { + $provider = new phpbb_controller_provider(); + $dumper = new PhpMatcherDumper($provider->get_paths($finder)->find()); + $cached_url_matcher_dump = $dumper->dump(array( + 'class' => 'phpbb_url_matcher', + )); + + file_put_contents($root_path . 'cache/url_matcher' . $php_ext, $cached_url_matcher_dump); + return phpbb_load_url_matcher($finder, $context, $root_path, $php_ext); + } + + return $matcher; +} + +/** +* Load the cached phpbb_url_matcher class +* +* @param phpbb_extension_finder $finder Extension finder +* @param RequestContext $context Symfony RequestContext object +* @param string $root_path Root path +* @param string $php_ext PHP extension +* @return phpbb_url_matcher|bool False if the file doesn't exist +*/ +function phpbb_load_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) +{ + if (file_exists($root_path . 'cache/url_matcher' . $php_ext)) + { + include($root_path . 'cache/url_matcher' . $php_ext); + return new phpbb_url_matcher($context); + } + + return false; +} -- cgit v1.2.1 From 196c2d4bc346ab6a31fd0b752c788e37cf39459d Mon Sep 17 00:00:00 2001 From: David King Date: Wed, 14 Nov 2012 15:56:07 -0500 Subject: [feature/controller] Move new functions to their own file PHPBB3-10864 --- phpBB/includes/functions.php | 49 ----------------------- phpBB/includes/functions_url_matcher.php | 68 ++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 49 deletions(-) create mode 100644 phpBB/includes/functions_url_matcher.php (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 7cf5611dca..88ce142195 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -5447,52 +5447,3 @@ function phpbb_to_numeric($input) { return ($input > PHP_INT_MAX) ? (float) $input : (int) $input; } - -/** -* Create and/or return the cached phpbb_url_matcher class -* -* If the class already exists, it instantiates it -* -* @param phpbb_extension_finder $finder Extension finder -* @param RequestContext $context Symfony RequestContext object -* @param string $root_path Root path -* @param string $php_ext PHP extension -* @return phpbb_url_matcher -*/ -function phpbb_create_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) -{ - $matcher = phpbb_load_url_matcher($finder, $context, $root_path, $php_ext); - if ($matcher === false) - { - $provider = new phpbb_controller_provider(); - $dumper = new PhpMatcherDumper($provider->get_paths($finder)->find()); - $cached_url_matcher_dump = $dumper->dump(array( - 'class' => 'phpbb_url_matcher', - )); - - file_put_contents($root_path . 'cache/url_matcher' . $php_ext, $cached_url_matcher_dump); - return phpbb_load_url_matcher($finder, $context, $root_path, $php_ext); - } - - return $matcher; -} - -/** -* Load the cached phpbb_url_matcher class -* -* @param phpbb_extension_finder $finder Extension finder -* @param RequestContext $context Symfony RequestContext object -* @param string $root_path Root path -* @param string $php_ext PHP extension -* @return phpbb_url_matcher|bool False if the file doesn't exist -*/ -function phpbb_load_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) -{ - if (file_exists($root_path . 'cache/url_matcher' . $php_ext)) - { - include($root_path . 'cache/url_matcher' . $php_ext); - return new phpbb_url_matcher($context); - } - - return false; -} diff --git a/phpBB/includes/functions_url_matcher.php b/phpBB/includes/functions_url_matcher.php new file mode 100644 index 0000000000..0a6e90703c --- /dev/null +++ b/phpBB/includes/functions_url_matcher.php @@ -0,0 +1,68 @@ +get_paths($finder)->find()); + $cached_url_matcher_dump = $dumper->dump(array( + 'class' => 'phpbb_url_matcher', + )); + + file_put_contents($root_path . 'cache/url_matcher' . $php_ext, $cached_url_matcher_dump); + return phpbb_load_url_matcher($finder, $context, $root_path, $php_ext); + } + + return $matcher; +} + +/** +* Load the cached phpbb_url_matcher class +* +* @param phpbb_extension_finder $finder Extension finder +* @param RequestContext $context Symfony RequestContext object +* @param string $root_path Root path +* @param string $php_ext PHP extension +* @return phpbb_url_matcher|bool False if the file doesn't exist +*/ +function phpbb_load_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) +{ + if (file_exists($root_path . 'cache/url_matcher' . $php_ext)) + { + include($root_path . 'cache/url_matcher' . $php_ext); + return new phpbb_url_matcher($context); + } + + return false; +} -- cgit v1.2.1 From 4cb9ec522c7007b99eb5ef44cb1bfdb369478aff Mon Sep 17 00:00:00 2001 From: David King Date: Wed, 14 Nov 2012 16:06:12 -0500 Subject: [feature/controller] Separate Kernel listeners into their own classes PHPBB3-10864 --- .../includes/event/kernel_exception_subscriber.php | 79 ++++++++++++ phpBB/includes/event/kernel_request_subscriber.php | 90 +++++++++++++ phpBB/includes/event/kernel_subscriber.php | 142 --------------------- .../includes/event/kernel_terminate_subscriber.php | 43 +++++++ 4 files changed, 212 insertions(+), 142 deletions(-) create mode 100644 phpBB/includes/event/kernel_exception_subscriber.php create mode 100644 phpBB/includes/event/kernel_request_subscriber.php delete mode 100644 phpBB/includes/event/kernel_subscriber.php create mode 100644 phpBB/includes/event/kernel_terminate_subscriber.php (limited to 'phpBB/includes') diff --git a/phpBB/includes/event/kernel_exception_subscriber.php b/phpBB/includes/event/kernel_exception_subscriber.php new file mode 100644 index 0000000000..cd6ea40c70 --- /dev/null +++ b/phpBB/includes/event/kernel_exception_subscriber.php @@ -0,0 +1,79 @@ +template = $template; + $this->user = $user; + } + + /** + * This listener is run when the KernelEvents::EXCEPTION event is triggered + * + * @param GetResponseForExceptionEvent $event + * @return null + */ + public function on_kernel_exception(GetResponseForExceptionEvent $event) + { + page_header($this->user->lang('INFORMATION')); + + $this->template->assign_vars(array( + 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'), + 'MESSAGE_TEXT' => $event->getException()->getMessage(), + )); + + $this->template->set_filenames(array( + 'body' => 'message_body.html', + )); + + page_footer(true, false, false); + + $event->setResponse(new Response($this->template->assign_display('body'), 404)); + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::EXCEPTION => 'on_kernel_exception', + ); + } +} diff --git a/phpBB/includes/event/kernel_request_subscriber.php b/phpBB/includes/event/kernel_request_subscriber.php new file mode 100644 index 0000000000..98079acabb --- /dev/null +++ b/phpBB/includes/event/kernel_request_subscriber.php @@ -0,0 +1,90 @@ +template = $template; + $this->user = $user; + $this->finder = $finder; + $this->root_path = $root_path; + $this->php_ext = $php_ext; + } + + /** + * This listener is run when the KernelEvents::REQUEST event is triggered + * + * This is responsible for setting up the routing information + * + * @param GetResponseEvent $event + * @return null + */ + public function on_kernel_request(GetResponseEvent $event) + { + $request = $event->getRequest(); + $context = new RequestContext(); + $context->fromRequest($request); + + if (!function_exists('phpbb_create_url_matcher')) + { + include($this->root_path . 'includes/functions_url_matcher' . $this->php_ext); + } + $matcher = phpbb_create_url_matcher($this->finder, $context, $this->root_path, $this->php_ext); + + $router_listener = new RouterListener($matcher, $context); + $router_listener->onKernelRequest($event); + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::REQUEST => 'on_kernel_request', + ); + } +} diff --git a/phpBB/includes/event/kernel_subscriber.php b/phpBB/includes/event/kernel_subscriber.php deleted file mode 100644 index 79ee4f4dc5..0000000000 --- a/phpBB/includes/event/kernel_subscriber.php +++ /dev/null @@ -1,142 +0,0 @@ -template = $template; - $this->user = $user; - $this->finder = $finder; - $this->root_path = $root_path; - $this->php_ext = $php_ext; - } - - /** - * This listener is run when the KernelEvents::TERMINATE event is triggered - * This comes after a Response has been sent to the server; this is - * primarily cleanup stuff. - * - * @param PostResponseEvent $event - * @return null - */ - public function on_kernel_terminate(PostResponseEvent $event) - { - exit_handler(); - } - - /** - * This listener is run when the KernelEvents::EXCEPTION event is triggered - * - * @param GetResponseForExceptionEvent $event - * @return null - */ - public function on_kernel_exception(GetResponseForExceptionEvent $event) - { - page_header($this->user->lang('INFORMATION')); - - $this->template->assign_vars(array( - 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'), - 'MESSAGE_TEXT' => $event->getException()->getMessage(), - )); - - $this->template->set_filenames(array( - 'body' => 'message_body.html', - )); - - page_footer(true, false, false); - - $event->setResponse(new Response($this->template->assign_display('body'), 404)); - } - - /** - * This listener is run when the KernelEvents::REQUEST event is triggered - * - * This is responsible for setting up the routing information - * - * @param GetResponseEvent $event - * @return null - */ - public function on_kernel_request(GetResponseEvent $event) - { - $request = $event->getRequest(); - $context = new RequestContext(); - $context->fromRequest($request); - - $matcher = phpbb_create_url_matcher($this->finder, $context, $this->root_path, $this->php_ext); - - $router_listener = new RouterListener($matcher, $context); - $router_listener->onKernelRequest($event); - } - - public static function getSubscribedEvents() - { - return array( - KernelEvents::REQUEST => 'on_kernel_request', - KernelEvents::TERMINATE => 'on_kernel_terminate', - KernelEvents::EXCEPTION => 'on_kernel_exception', - ); - } -} diff --git a/phpBB/includes/event/kernel_terminate_subscriber.php b/phpBB/includes/event/kernel_terminate_subscriber.php new file mode 100644 index 0000000000..1eaf890e42 --- /dev/null +++ b/phpBB/includes/event/kernel_terminate_subscriber.php @@ -0,0 +1,43 @@ + 'on_kernel_terminate', + ); + } +} -- cgit v1.2.1 From fa43edd8778dffd21146350f1749fad5c0755fb7 Mon Sep 17 00:00:00 2001 From: David King Date: Wed, 14 Nov 2012 16:42:52 -0500 Subject: [feature/controller] Further separate url matcher functionality PHPBB3-10864 --- phpBB/includes/event/kernel_request_subscriber.php | 6 +- phpBB/includes/functions_url_matcher.php | 85 ++++++++++++++++------ 2 files changed, 63 insertions(+), 28 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/event/kernel_request_subscriber.php b/phpBB/includes/event/kernel_request_subscriber.php index 98079acabb..85c8c5b173 100644 --- a/phpBB/includes/event/kernel_request_subscriber.php +++ b/phpBB/includes/event/kernel_request_subscriber.php @@ -50,8 +50,6 @@ class phpbb_event_kernel_request_subscriber implements EventSubscriberInterface */ public function __construct(phpbb_extension_finder $finder, $root_path, $php_ext) { - $this->template = $template; - $this->user = $user; $this->finder = $finder; $this->root_path = $root_path; $this->php_ext = $php_ext; @@ -71,11 +69,11 @@ class phpbb_event_kernel_request_subscriber implements EventSubscriberInterface $context = new RequestContext(); $context->fromRequest($request); - if (!function_exists('phpbb_create_url_matcher')) + if (!function_exists('phpbb_load_url_matcher')) { include($this->root_path . 'includes/functions_url_matcher' . $this->php_ext); } - $matcher = phpbb_create_url_matcher($this->finder, $context, $this->root_path, $this->php_ext); + $matcher = phpbb_get_url_matcher($this->finder, $context, $this->root_path, $this->php_ext); $router_listener = new RouterListener($matcher, $context); $router_listener->onKernelRequest($event); diff --git a/phpBB/includes/functions_url_matcher.php b/phpBB/includes/functions_url_matcher.php index 0a6e90703c..f628337dee 100644 --- a/phpBB/includes/functions_url_matcher.php +++ b/phpBB/includes/functions_url_matcher.php @@ -8,6 +8,7 @@ */ use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; +use Symfony\Component\Routing\Matcher\UrlMatcher; use Symfony\Component\Routing\RequestContext; /** @@ -19,50 +20,86 @@ if (!defined('IN_PHPBB')) } /** -* Create and/or return the cached phpbb_url_matcher class -* -* If the class already exists, it instantiates it +* Create a new UrlMatcher class and dump it into the cache file * * @param phpbb_extension_finder $finder Extension finder * @param RequestContext $context Symfony RequestContext object * @param string $root_path Root path * @param string $php_ext PHP extension -* @return phpbb_url_matcher +* @return null */ -function phpbb_create_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) +function phpbb_get_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) { - $matcher = phpbb_load_url_matcher($finder, $context, $root_path, $php_ext); - if ($matcher === false) + if (defined('DEBUG')) { - $provider = new phpbb_controller_provider(); - $dumper = new PhpMatcherDumper($provider->get_paths($finder)->find()); - $cached_url_matcher_dump = $dumper->dump(array( - 'class' => 'phpbb_url_matcher', - )); + return phpbb_create_url_matcher($finder, $context); + } - file_put_contents($root_path . 'cache/url_matcher' . $php_ext, $cached_url_matcher_dump); - return phpbb_load_url_matcher($finder, $context, $root_path, $php_ext); + if (phpbb_url_matcher_dumped($root_path, $php_ext) === false) + { + phpbb_create_dumped_url_matcher($finder, $context, $root_path, $php_ext); } - return $matcher; + return phpbb_load_url_matcher($context, $root_path, $php_ext); } /** -* Load the cached phpbb_url_matcher class +* Create a new UrlMatcher class and dump it into the cache file * * @param phpbb_extension_finder $finder Extension finder * @param RequestContext $context Symfony RequestContext object * @param string $root_path Root path * @param string $php_ext PHP extension -* @return phpbb_url_matcher|bool False if the file doesn't exist +* @return null */ -function phpbb_load_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) +function phpbb_create_dumped_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) { - if (file_exists($root_path . 'cache/url_matcher' . $php_ext)) - { - include($root_path . 'cache/url_matcher' . $php_ext); - return new phpbb_url_matcher($context); - } + $provider = new phpbb_controller_provider(); + $dumper = new PhpMatcherDumper($provider->get_paths($finder)->find()); + $cached_url_matcher_dump = $dumper->dump(array( + 'class' => 'phpbb_url_matcher', + )); + + file_put_contents($root_path . 'cache/url_matcher' . $php_ext, $cached_url_matcher_dump); +} - return false; +/** +* Create a non-cached UrlMatcher +* +* @param phpbb_extension_finder $finder Extension finder +* @param RequestContext $context Symfony RequestContext object +* @return UrlMatcher +*/ +function phpbb_create_url_matcher(phpbb_extension_finder $finder, RequestContext $context) +{ + $provider = new phpbb_controller_provider(); + return new UrlMatcher($provider->get_paths($finder)->find(), $context); +} + +/** +* Load the cached phpbb_url_matcher class +* +* @param RequestContext $context Symfony RequestContext object +* @param string $root_path Root path +* @param string $php_ext PHP extension +* @return phpbb_url_matcher +*/ +function phpbb_load_url_matcher(RequestContext $context, $root_path, $php_ext) +{ + require($root_path . 'cache/url_matcher' . $php_ext); + return new phpbb_url_matcher($context); +} + +/** +* Determine whether we have our dumped URL matcher +* +* The class is automatically dumped to the cache directory +* +* @param string $root_path Root path +* @param string $php_ext PHP extension +* @return bool True if it exists, false if not +*/ +function phpbb_url_matcher_dumped($root_path, $php_ext) +{ + return file_exists($root_path . 'cache/url_matcher' . $php_ext); } -- cgit v1.2.1 From c54c3ee422a9bfb0878aecf80cbb298e230e4fd4 Mon Sep 17 00:00:00 2001 From: David King Date: Wed, 14 Nov 2012 17:04:45 -0500 Subject: [feature/controller] A few minor nitpickings PHPBB3-10864 --- phpBB/includes/functions_url_matcher.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_url_matcher.php b/phpBB/includes/functions_url_matcher.php index f628337dee..782acc4c20 100644 --- a/phpBB/includes/functions_url_matcher.php +++ b/phpBB/includes/functions_url_matcher.php @@ -35,7 +35,7 @@ function phpbb_get_url_matcher(phpbb_extension_finder $finder, RequestContext $c return phpbb_create_url_matcher($finder, $context); } - if (phpbb_url_matcher_dumped($root_path, $php_ext) === false) + if (!phpbb_url_matcher_dumped($root_path, $php_ext)) { phpbb_create_dumped_url_matcher($finder, $context, $root_path, $php_ext); } @@ -55,7 +55,8 @@ function phpbb_get_url_matcher(phpbb_extension_finder $finder, RequestContext $c function phpbb_create_dumped_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) { $provider = new phpbb_controller_provider(); - $dumper = new PhpMatcherDumper($provider->get_paths($finder)->find()); + $routes = $provider->get_paths($finder)->find(); + $dumper = new PhpMatcherDumper($routes); $cached_url_matcher_dump = $dumper->dump(array( 'class' => 'phpbb_url_matcher', )); -- cgit v1.2.1 From aead33432ae67857009f9570a5ec720d86f7575b Mon Sep 17 00:00:00 2001 From: David King Date: Wed, 14 Nov 2012 17:14:21 -0500 Subject: [feature/controller] Remove dumped container when cache is purged PHPBB3-10864 --- phpBB/includes/cache/driver/file.php | 1 + phpBB/includes/cache/driver/memory.php | 1 + 2 files changed, 2 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/cache/driver/file.php b/phpBB/includes/cache/driver/file.php index 32bdb1918a..5014ba18af 100644 --- a/phpBB/includes/cache/driver/file.php +++ b/phpBB/includes/cache/driver/file.php @@ -215,6 +215,7 @@ class phpbb_cache_driver_file extends phpbb_cache_driver_base while (($entry = readdir($dir)) !== false) { if (strpos($entry, 'container_') !== 0 && + strpos($entry, 'url_matcher') !== 0 && strpos($entry, 'sql_') !== 0 && strpos($entry, 'data_') !== 0 && strpos($entry, 'ctpl_') !== 0 && diff --git a/phpBB/includes/cache/driver/memory.php b/phpBB/includes/cache/driver/memory.php index 1ea9a3e9e7..f6c42c0ea6 100644 --- a/phpBB/includes/cache/driver/memory.php +++ b/phpBB/includes/cache/driver/memory.php @@ -163,6 +163,7 @@ abstract class phpbb_cache_driver_memory extends phpbb_cache_driver_base while (($entry = readdir($dir)) !== false) { if (strpos($entry, 'container_') !== 0 && + strpos($entry, 'url_matcher') !== 0 && strpos($entry, 'sql_') !== 0 && strpos($entry, 'data_') !== 0 && strpos($entry, 'ctpl_') !== 0 && -- cgit v1.2.1 From b4eff4f06acce78536a392b733f2438f4d1d1c52 Mon Sep 17 00:00:00 2001 From: David King Date: Thu, 15 Nov 2012 13:54:41 -0500 Subject: [feature/controller] Remove URL Base from helper class I had forgotten that the container sends the same instance of objects to all services that request it, so in this case all controllers would share the same base url path, which is not desired. PHPBB3-10864 --- phpBB/includes/controller/helper.php | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 8bb4427382..6b697c7e46 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -47,12 +47,6 @@ class phpbb_controller_helper */ protected $php_ext; - /** - * Base URL - * @var array - */ - protected $url_base; - /** * Constructor * @@ -101,21 +95,7 @@ class phpbb_controller_helper */ public function url(array $url_parts, $query = '') { - return append_sid($this->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) . '/' : ''; + return append_sid($this->root_path . implode('/', $url_parts), $query); } /** -- cgit v1.2.1 From db1d49d559a337f7266a9e9f0cfaf3eb025b0ed1 Mon Sep 17 00:00:00 2001 From: David King Date: Thu, 15 Nov 2012 13:59:30 -0500 Subject: [feature/controller] Rename get_paths to import_paths_from_finder Also removed unused variable from url_matcher function PHPBB3-10864 --- phpBB/includes/controller/provider.php | 20 ++++---------------- phpBB/includes/functions_url_matcher.php | 10 +++++----- 2 files changed, 9 insertions(+), 21 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/provider.php b/phpBB/includes/controller/provider.php index 25deedb5d1..b2a5b9f6b2 100644 --- a/phpBB/includes/controller/provider.php +++ b/phpBB/includes/controller/provider.php @@ -39,7 +39,7 @@ class phpbb_controller_provider */ public function __construct($routing_paths = array()) { - $this->set_paths($routing_paths); + $this->routing_paths = $routing_paths; } /** @@ -48,28 +48,16 @@ class phpbb_controller_provider * * @return The current instance of this object for method chaining */ - public function get_paths(phpbb_extension_finder $finder) + public function import_paths_from_finder(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 + $this->routing_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; } diff --git a/phpBB/includes/functions_url_matcher.php b/phpBB/includes/functions_url_matcher.php index 782acc4c20..7280cb74eb 100644 --- a/phpBB/includes/functions_url_matcher.php +++ b/phpBB/includes/functions_url_matcher.php @@ -37,7 +37,7 @@ function phpbb_get_url_matcher(phpbb_extension_finder $finder, RequestContext $c if (!phpbb_url_matcher_dumped($root_path, $php_ext)) { - phpbb_create_dumped_url_matcher($finder, $context, $root_path, $php_ext); + phpbb_create_dumped_url_matcher($finder, $root_path, $php_ext); } return phpbb_load_url_matcher($context, $root_path, $php_ext); @@ -47,15 +47,14 @@ function phpbb_get_url_matcher(phpbb_extension_finder $finder, RequestContext $c * Create a new UrlMatcher class and dump it into the cache file * * @param phpbb_extension_finder $finder Extension finder -* @param RequestContext $context Symfony RequestContext object * @param string $root_path Root path * @param string $php_ext PHP extension * @return null */ -function phpbb_create_dumped_url_matcher(phpbb_extension_finder $finder, RequestContext $context, $root_path, $php_ext) +function phpbb_create_dumped_url_matcher(phpbb_extension_finder $finder, $root_path, $php_ext) { $provider = new phpbb_controller_provider(); - $routes = $provider->get_paths($finder)->find(); + $routes = $provider->import_paths_from_finder($finder)->find(); $dumper = new PhpMatcherDumper($routes); $cached_url_matcher_dump = $dumper->dump(array( 'class' => 'phpbb_url_matcher', @@ -74,7 +73,8 @@ function phpbb_create_dumped_url_matcher(phpbb_extension_finder $finder, Request function phpbb_create_url_matcher(phpbb_extension_finder $finder, RequestContext $context) { $provider = new phpbb_controller_provider(); - return new UrlMatcher($provider->get_paths($finder)->find(), $context); + $routes = $provider->import_paths_from_finder($finder)->find(); + return new UrlMatcher($routes, $context); } /** -- cgit v1.2.1 From 8e480a87253fd2e42af3fc4daaed2f49b9ae65c5 Mon Sep 17 00:00:00 2001 From: David King Date: Thu, 15 Nov 2012 14:48:45 -0500 Subject: [feature/controller] Move include to app.php PHPBB3-10864 --- phpBB/includes/event/kernel_request_subscriber.php | 5 ----- 1 file changed, 5 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/event/kernel_request_subscriber.php b/phpBB/includes/event/kernel_request_subscriber.php index 85c8c5b173..afb8464f80 100644 --- a/phpBB/includes/event/kernel_request_subscriber.php +++ b/phpBB/includes/event/kernel_request_subscriber.php @@ -69,12 +69,7 @@ class phpbb_event_kernel_request_subscriber implements EventSubscriberInterface $context = new RequestContext(); $context->fromRequest($request); - if (!function_exists('phpbb_load_url_matcher')) - { - include($this->root_path . 'includes/functions_url_matcher' . $this->php_ext); - } $matcher = phpbb_get_url_matcher($this->finder, $context, $this->root_path, $this->php_ext); - $router_listener = new RouterListener($matcher, $context); $router_listener->onKernelRequest($event); } -- cgit v1.2.1 From 14f44c17ad76878ed540cd5dd56a3a62b30dbd15 Mon Sep 17 00:00:00 2001 From: David King Date: Thu, 15 Nov 2012 16:14:11 -0500 Subject: [feature/controller] phpbb_controller_exception instead of RuntimeException PHPBB3-10864 --- phpBB/includes/controller/exception.php | 24 ++++++++++++++++++++++++ phpBB/includes/controller/resolver.php | 11 ++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 phpBB/includes/controller/exception.php (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/exception.php b/phpBB/includes/controller/exception.php new file mode 100644 index 0000000000..da2fefc600 --- /dev/null +++ b/phpBB/includes/controller/exception.php @@ -0,0 +1,24 @@ +user->lang['CONTROLLER_NOT_SPECIFIED']); + throw new phpbb_controller_exception($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']); + throw new phpbb_controller_exception($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)); + throw new phpbb_controller_exception($this->user->lang('CONTROLLER_SERVICE_UNDEFINED', $service)); } $controller_object = $this->container->get($service); @@ -92,6 +92,7 @@ class phpbb_controller_resolver implements ControllerResolverInterface * @param Symfony\Component\HttpFoundation\Request $request Symfony Request object * @param string $controller Controller class name * @return bool False + * @throws phpbb_controller_exception */ public function getArguments(Request $request, $controller) { @@ -114,7 +115,7 @@ class phpbb_controller_resolver implements ControllerResolverInterface } else { - throw new RuntimeException($user->lang('CONTROLLER_ARGUMENT_VALUE_MISSING', $param->getPosition() + 1, get_class($object) . ':' . $method, $param->name)); + throw new phpbb_controller_exception($user->lang('CONTROLLER_ARGUMENT_VALUE_MISSING', $param->getPosition() + 1, get_class($object) . ':' . $method, $param->name)); } } -- cgit v1.2.1 From 45b3ab8e81a3cffae4d0ada8785620ea4209c207 Mon Sep 17 00:00:00 2001 From: David King Date: Thu, 15 Nov 2012 16:18:02 -0500 Subject: [feature/controller] Move Response definition into a variable PHPBB3-10864 --- phpBB/includes/event/kernel_exception_subscriber.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/event/kernel_exception_subscriber.php b/phpBB/includes/event/kernel_exception_subscriber.php index cd6ea40c70..e2668d4560 100644 --- a/phpBB/includes/event/kernel_exception_subscriber.php +++ b/phpBB/includes/event/kernel_exception_subscriber.php @@ -67,7 +67,8 @@ class phpbb_event_kernel_exception_subscriber implements EventSubscriberInterfac page_footer(true, false, false); - $event->setResponse(new Response($this->template->assign_display('body'), 404)); + $response = new Response($this->template->assign_display('body'), 404); + $event->setResponse($response); } public static function getSubscribedEvents() -- cgit v1.2.1 From 74bc46049303952e5f16f61e9f63fa2eeaffbadc Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 16 Nov 2012 09:43:08 -0500 Subject: [feature/controller] Rename improperly named controller exception class PHPBB3-10864 --- phpBB/includes/controller/exception.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/exception.php b/phpBB/includes/controller/exception.php index da2fefc600..faa8b6b584 100644 --- a/phpBB/includes/controller/exception.php +++ b/phpBB/includes/controller/exception.php @@ -19,6 +19,6 @@ if (!defined('IN_PHPBB')) * Controller exception class * @package phpBB3 */ -class phpbb_controller_provider extends RuntimeException +class phpbb_controller_exception extends RuntimeException { } -- cgit v1.2.1 From 120267e58030eb4b7184e0d54166dfc8d905c3f7 Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 16 Nov 2012 10:27:55 -0500 Subject: [feature/controller] Correctly access user object PHPBB3-10864 --- phpBB/includes/controller/resolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/resolver.php b/phpBB/includes/controller/resolver.php index 0e724ec608..5674a65118 100644 --- a/phpBB/includes/controller/resolver.php +++ b/phpBB/includes/controller/resolver.php @@ -115,7 +115,7 @@ class phpbb_controller_resolver implements ControllerResolverInterface } else { - throw new phpbb_controller_exception($user->lang('CONTROLLER_ARGUMENT_VALUE_MISSING', $param->getPosition() + 1, get_class($object) . ':' . $method, $param->name)); + throw new phpbb_controller_exception($this->user->lang('CONTROLLER_ARGUMENT_VALUE_MISSING', $param->getPosition() + 1, get_class($object) . ':' . $method, $param->name)); } } -- cgit v1.2.1 From c2f352ab3550dd5eed1aa425b720bd0cdf8d6859 Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 16 Nov 2012 10:35:55 -0500 Subject: [feature/controller] Fix param block for controller callable PHPBB3-10864 --- phpBB/includes/controller/resolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/resolver.php b/phpBB/includes/controller/resolver.php index 5674a65118..901aa7eaa0 100644 --- a/phpBB/includes/controller/resolver.php +++ b/phpBB/includes/controller/resolver.php @@ -90,7 +90,7 @@ class phpbb_controller_resolver implements ControllerResolverInterface * controller. * * @param Symfony\Component\HttpFoundation\Request $request Symfony Request object - * @param string $controller Controller class name + * @param mixed $controller A callable (controller class, method) * @return bool False * @throws phpbb_controller_exception */ -- cgit v1.2.1 From d41b1146e8947919ed9bdd41e6a30ad15e91d262 Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 16 Nov 2012 10:37:07 -0500 Subject: [feature/controller] Rename $root_path class property to $phpbb_root_path PHPBB3-10864 --- phpBB/includes/controller/helper.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 6b697c7e46..6dc3ec4626 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -39,7 +39,7 @@ class phpbb_controller_helper * phpBB root path * @var string */ - protected $root_path; + protected $phpbb_root_path; /** * PHP extension @@ -52,14 +52,14 @@ class phpbb_controller_helper * * @param phpbb_template $template Template object * @param phpbb_user $user User object - * @param string $root_path phpBB root path + * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP extension */ - public function __construct(phpbb_template $template, phpbb_user $user, $root_path, $php_ext) + public function __construct(phpbb_template $template, phpbb_user $user, $phpbb_root_path, $php_ext) { $this->template = $template; $this->user = $user; - $this->root_path = $root_path; + $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; } @@ -95,7 +95,7 @@ class phpbb_controller_helper */ public function url(array $url_parts, $query = '') { - return append_sid($this->root_path . implode('/', $url_parts), $query); + return append_sid($this->phpbb_root_path . implode('/', $url_parts), $query); } /** -- cgit v1.2.1 From 1952a4f276930edd16ca51fd690ed3e7965071da Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 16 Nov 2012 10:38:40 -0500 Subject: [feature/controller] Flip method parameters, require $message PHPBB3-10864 --- phpBB/includes/controller/helper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 6dc3ec4626..6cacc8fefa 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -101,11 +101,11 @@ class phpbb_controller_helper /** * 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 + * @param string $code The error code (e.g. 404, 500, 503, etc.) * @return Response A Reponse instance */ - public function error($code = 500, $message = '') + public function error($message, $code = 500) { $this->template->assign_vars(array( 'MESSAGE_TEXT' => $message, -- cgit v1.2.1 From 8913b2c7c4ffc38d4caf34ca7014b8a07f11d19d Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 17 Nov 2012 17:48:20 -0500 Subject: [feature/controller] Use query string, not path info, for controller access This is hopefully just temporary until we can fix the relative path issue. PHPBB3-10864 --- phpBB/includes/functions.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 88ce142195..17fc16ef86 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2346,20 +2346,6 @@ 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; /** @@ -5056,7 +5042,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 : $config['script_path'] . '/'; + $web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $phpbb_root_path; // Send a proper content-language to the output $user_lang = $user->lang['USER_LANG']; -- cgit v1.2.1 From 4d6f6351dd0563b26105d15b98052d907f9c52ed Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 17 Nov 2012 18:05:32 -0500 Subject: [feature/controller] Allow injecting Symfony Request into controllers PHPBB3-10864 --- phpBB/includes/controller/resolver.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/controller/resolver.php b/phpBB/includes/controller/resolver.php index 901aa7eaa0..ee469aa9c8 100644 --- a/phpBB/includes/controller/resolver.php +++ b/phpBB/includes/controller/resolver.php @@ -109,6 +109,10 @@ class phpbb_controller_resolver implements ControllerResolverInterface { $arguments[] = $attributes[$param->name]; } + else if ($param->getClass() && $param->getClass()->isInstance($request)) + { + $arguments[] = $request; + } else if ($param->isDefaultValueAvailable()) { $arguments[] = $param->getDefaultValue(); -- cgit v1.2.1 From 53caf83233c962adbb68dcfb0f8172ebf788b8f7 Mon Sep 17 00:00:00 2001 From: David King Date: Sun, 18 Nov 2012 13:35:04 -0500 Subject: [feature/controller] Remove now-unused code PHPBB3-10864 --- phpBB/includes/functions.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 17fc16ef86..02a9e33f2a 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -7,9 +7,6 @@ * */ -use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; -use Symfony\Component\Routing\RequestContext; - /** * @ignore */ @@ -2338,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, $phpbb_root_path, $config, $symfony_request; + global $phpbb_dispatcher; if ($params === '' || (is_array($params) && empty($params))) { -- cgit v1.2.1 From 60c0a1dd2ac2c733a670093ad440e3ba6be3be4d Mon Sep 17 00:00:00 2001 From: David King Date: Sun, 18 Nov 2012 15:51:05 -0500 Subject: [feature/controller] Don't use $user->lang() before container compilation PHPBB3-10864 --- phpBB/includes/di/pass/kernel_pass.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/di/pass/kernel_pass.php b/phpBB/includes/di/pass/kernel_pass.php index d186ff2767..a701ebcfa6 100644 --- a/phpBB/includes/di/pass/kernel_pass.php +++ b/phpBB/includes/di/pass/kernel_pass.php @@ -29,7 +29,6 @@ class phpbb_di_pass_kernel_pass implements CompilerPassInterface public function process(ContainerBuilder $container) { $definition = $container->getDefinition('dispatcher'); - $user = $container->get('user'); foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events) { @@ -39,12 +38,12 @@ class phpbb_di_pass_kernel_pass implements CompilerPassInterface if (!isset($event['event'])) { - throw new InvalidArgumentException($user->lang('NO_EVENT_ATTRIBUTE', $id)); + throw new InvalidArgumentException(sprintf('Service "%1$s" must define the "event" attribute on "kernel.event_listener" tags.', $id)); } if (!isset($event['method'])) { - throw new InvalidArgumentException($user->lang('NO_METHOD_ATTRIBUTE', $id)); + throw new InvalidArgumentException(sprintf('Service "%1$s" must define the "method" attribute on "kernel.event_listener" tags.', $id)); } $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); @@ -60,7 +59,7 @@ class phpbb_di_pass_kernel_pass implements CompilerPassInterface $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; if (!$refClass->implementsInterface($interface)) { - throw new InvalidArgumentException($user->lang('SUBSCRIBER_WRONG_TYPE', $id, $interface)); + throw new InvalidArgumentException(sprintf('Service "%1$s" must implement interface "%2$s".', $id, $interface)); } $definition->addMethodCall('addSubscriberService', array($id, $class)); -- cgit v1.2.1 From 0f4f81b0966e29b5aaae5bf94e46260474ec0cb2 Mon Sep 17 00:00:00 2001 From: David King Date: Sun, 18 Nov 2012 15:52:35 -0500 Subject: [feature/controller] Create Symfony Request in new function PHPBB3-10864 --- phpBB/includes/functions.php | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 02a9e33f2a..820d96c9aa 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -7,6 +7,8 @@ * */ +use Symfony\Component\HttpFoundation\Request; + /** * @ignore */ @@ -5430,3 +5432,40 @@ function phpbb_to_numeric($input) { return ($input > PHP_INT_MAX) ? (float) $input : (int) $input; } + +/** +* Create a Symfony Request object from a given URI and phpbb_request object +* +* @param string $uri Request URI +* @param phpbb_request $request Request object +* @return Request A Symfony Request object +*/ +function phpbb_create_symfony_request($uri, phpbb_request $request) +{ + $request_method = $request->server('REQUEST_METHOD'); + $parameter_names = array(); + $parameter_names['request'] = array_merge( + $request->variable_names(phpbb_request_interface::GET), + // POST overwrites duplicated GET parameters + $request->variable_names(phpbb_request_interface::POST) + ); + $parameter_names['server'] = $request->variable_names(phpbb_request_interface::SERVER); + $parameter_names['files'] = $request->variable_names(phpbb_request_interface::FILES); + $parameter_names['cookie'] = $request->variable_names(phpbb_request_interface::COOKIE); + + $parameters = array( + 'request' => array(), + 'cookie' => array(), + 'files' => array(), + 'server' => array(), + ); + foreach ($parameter_names as $type => $names) + { + foreach ($names as $name) + { + $parameters[$type][$name] = $request->variable($name, ''); + } + } + + return Request::create($uri, $request_method, $parameters['request'], $parameters['cookie'], $parameters['files'], $parameters['server']); +} -- cgit v1.2.1 From e2bf66d0658ae7d7bb253083b73d5769c117746a Mon Sep 17 00:00:00 2001 From: David King Date: Sun, 18 Nov 2012 15:58:47 -0500 Subject: [feature/controller] Add documentation about input being HTML-escaped PHPBB3-10864 --- phpBB/includes/functions.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 820d96c9aa..cdc05ca649 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -5436,6 +5436,9 @@ function phpbb_to_numeric($input) /** * Create a Symfony Request object from a given URI and phpbb_request object * +* Note that everything passed into the Request object has already been HTML +* escaped by the phpbb_request object. +* * @param string $uri Request URI * @param phpbb_request $request Request object * @return Request A Symfony Request object -- cgit v1.2.1 From 30043502814cd42d824dc1d6bcb25bebc60adbed Mon Sep 17 00:00:00 2001 From: David King Date: Mon, 19 Nov 2012 11:47:42 -0500 Subject: [feature/controller] Correctly create Symfony object from globals PHPBB3-10864 --- phpBB/includes/functions.php | 70 ++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 32 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index cdc05ca649..ee147969f9 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -5434,41 +5434,47 @@ function phpbb_to_numeric($input) } /** -* Create a Symfony Request object from a given URI and phpbb_request object +* Create a Symfony Request object from phpbb_request object * -* Note that everything passed into the Request object has already been HTML -* escaped by the phpbb_request object. -* -* @param string $uri Request URI * @param phpbb_request $request Request object * @return Request A Symfony Request object */ -function phpbb_create_symfony_request($uri, phpbb_request $request) +function phpbb_create_symfony_request(phpbb_request $request) { - $request_method = $request->server('REQUEST_METHOD'); - $parameter_names = array(); - $parameter_names['request'] = array_merge( - $request->variable_names(phpbb_request_interface::GET), - // POST overwrites duplicated GET parameters - $request->variable_names(phpbb_request_interface::POST) - ); - $parameter_names['server'] = $request->variable_names(phpbb_request_interface::SERVER); - $parameter_names['files'] = $request->variable_names(phpbb_request_interface::FILES); - $parameter_names['cookie'] = $request->variable_names(phpbb_request_interface::COOKIE); - - $parameters = array( - 'request' => array(), - 'cookie' => array(), - 'files' => array(), - 'server' => array(), - ); - foreach ($parameter_names as $type => $names) - { - foreach ($names as $name) - { - $parameters[$type][$name] = $request->variable($name, ''); - } - } - - return Request::create($uri, $request_method, $parameters['request'], $parameters['cookie'], $parameters['files'], $parameters['server']); + // This function is meant to sanitize the global input arrays + $sanitizer = function(&$value, $key) { + $type_cast_helper = new phpbb_request_type_cast_helper(); + $type_cast_helper->set_var($value, $value, gettype($value), true); + }; + + // We need to re-enable the super globals so we can access them here + $request->enable_super_globals(); + $get_parameters = $_GET; + $post_parameters = $_POST; + $server_parameters = $_SERVER; + $files_parameters = $_FILES; + $cookie_parameters = $_COOKIE; + // And now disable them again for security + $request->disable_super_globals(); + + array_walk_recursive($get_parameters, $sanitizer); + array_walk_recursive($post_parameters, $sanitizer); + + // Until we fix the issue with relative paths, we have to fake path info + // to allow urls like app.php?controller=foo/bar + $controller = $request->variable('controller', ''); + $path_info = '/' . $controller; + $request_uri = $server_parameters['REQUEST_URI']; + + // Remove the query string from REQUEST_URI + if ($pos = strpos($request_uri, '?')) + { + $request_uri = substr($request_uri, 0, $pos); + } + + // Add the path info (i.e. controller route) to the REQUEST_URI + $server_parameters['REQUEST_URI'] = $request_uri . $path_info; + $server_parameters['SCRIPT_NAME'] = ''; + + return new Request($get_parameters, $post_parameters, array(), $cookie_parameters, $files_parameters, $server_parameters); } -- cgit v1.2.1 From f8614bfc84ba9b9cc814b8f78e343005620f18f8 Mon Sep 17 00:00:00 2001 From: David King Date: Mon, 19 Nov 2012 12:37:20 -0500 Subject: [feature/controller] Check for proper status codes from controllers PHPBB3-10864 --- phpBB/includes/event/kernel_exception_subscriber.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/event/kernel_exception_subscriber.php b/phpBB/includes/event/kernel_exception_subscriber.php index e2668d4560..e843df2e68 100644 --- a/phpBB/includes/event/kernel_exception_subscriber.php +++ b/phpBB/includes/event/kernel_exception_subscriber.php @@ -18,6 +18,7 @@ if (!defined('IN_PHPBB')) use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpFoundation\Response; class phpbb_event_kernel_exception_subscriber implements EventSubscriberInterface @@ -56,9 +57,11 @@ class phpbb_event_kernel_exception_subscriber implements EventSubscriberInterfac { page_header($this->user->lang('INFORMATION')); + $exception = $event->getException(); + $this->template->assign_vars(array( 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'), - 'MESSAGE_TEXT' => $event->getException()->getMessage(), + 'MESSAGE_TEXT' => $exception->getMessage(), )); $this->template->set_filenames(array( @@ -67,7 +70,9 @@ class phpbb_event_kernel_exception_subscriber implements EventSubscriberInterfac page_footer(true, false, false); - $response = new Response($this->template->assign_display('body'), 404); + + $status_code = $exception instanceof NotFoundHttpException ? $exception->getStatusCode() : 500; + $response = new Response($this->template->assign_display('body'), $status_code); $event->setResponse($response); } -- cgit v1.2.1 From 01ec6085939d74e6a37c3ef041434db1c4b8f3e4 Mon Sep 17 00:00:00 2001 From: David King Date: Mon, 19 Nov 2012 12:55:15 -0500 Subject: [feature/controller] Fix comments, check against more general HttpException PHPBB3-10864 --- phpBB/includes/event/kernel_exception_subscriber.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/event/kernel_exception_subscriber.php b/phpBB/includes/event/kernel_exception_subscriber.php index e843df2e68..f90989a74c 100644 --- a/phpBB/includes/event/kernel_exception_subscriber.php +++ b/phpBB/includes/event/kernel_exception_subscriber.php @@ -18,7 +18,7 @@ if (!defined('IN_PHPBB')) use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpFoundation\Response; class phpbb_event_kernel_exception_subscriber implements EventSubscriberInterface @@ -71,7 +71,7 @@ class phpbb_event_kernel_exception_subscriber implements EventSubscriberInterfac page_footer(true, false, false); - $status_code = $exception instanceof NotFoundHttpException ? $exception->getStatusCode() : 500; + $status_code = $exception instanceof HttpException ? $exception->getStatusCode() : 500; $response = new Response($this->template->assign_display('body'), $status_code); $event->setResponse($response); } -- cgit v1.2.1