Commit 7df10de7 by Scott

Handle Method Not Allowed in router

parent e572049e
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
More about this license: http://www.question2answer.org/license.php More about this license: http://www.question2answer.org/license.php
*/ */
use Q2A\Exceptions\ExceptionHandler;
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../../'); header('Location: ../../');
exit; exit;
...@@ -181,33 +179,39 @@ function qa_get_request_content() ...@@ -181,33 +179,39 @@ function qa_get_request_content()
$routing = qa_page_routing(); $routing = qa_page_routing();
qa_controller_routing(); qa_controller_routing();
$route = qa_service('router')->match($requestlower); $qa_content = [];
if ($route !== null) { try {
// use new Controller system // use new Controller system
qa_set_template($route->getOption('template')); $route = qa_service('router')->match($requestlower);
$controllerClass = $route->getController(); if ($route !== null) {
$ctrl = new $controllerClass(); qa_set_template($route->getOption('template'));
try { $controllerClass = $route->getController();
$ctrl = new $controllerClass();
$qa_content = $ctrl->executeAction($route->getAction(), $route->getParameters()); $qa_content = $ctrl->executeAction($route->getAction(), $route->getParameters());
} catch (Exception $e) {
$qa_content = (new ExceptionHandler())->handle($e);
} }
} elseif (isset($routing[$requestlower])) { } catch (\Exception $e) {
qa_set_template($firstlower); $qa_content = (new \Q2A\Exceptions\ExceptionHandler)->handle($e);
$qa_content = require QA_INCLUDE_DIR . $routing[$requestlower]; }
} elseif (isset($routing[$firstlower . '/'])) { if (empty($qa_content)) {
qa_set_template($firstlower); if (isset($routing[$requestlower])) {
$qa_content = require QA_INCLUDE_DIR . $routing[$firstlower . '/']; qa_set_template($firstlower);
$qa_content = require QA_INCLUDE_DIR . $routing[$requestlower];
} elseif (is_numeric($requestparts[0])) { } elseif (isset($routing[$firstlower . '/'])) {
qa_set_template('question'); qa_set_template($firstlower);
$qa_content = require QA_INCLUDE_DIR . 'pages/question.php'; $qa_content = require QA_INCLUDE_DIR . $routing[$firstlower . '/'];
} else { } elseif (is_numeric($requestparts[0])) {
qa_set_template(strlen($firstlower) ? $firstlower : 'qa'); // will be changed later qa_set_template('question');
$qa_content = require QA_INCLUDE_DIR . 'pages/default.php'; // handles many other pages, including custom pages and page modules $qa_content = require QA_INCLUDE_DIR . 'pages/question.php';
} else {
qa_set_template(strlen($firstlower) ? $firstlower : 'qa'); // will be changed later
$qa_content = require QA_INCLUDE_DIR . 'pages/default.php'; // handles many other pages, including custom pages and page modules
}
} }
if ($firstlower == 'admin') { if ($firstlower == 'admin') {
......
...@@ -87,6 +87,7 @@ return array( ...@@ -87,6 +87,7 @@ return array(
'highest_users' => 'Top scoring users', 'highest_users' => 'Top scoring users',
'hot_qs_in_x' => 'Hot questions in ^', 'hot_qs_in_x' => 'Hot questions in ^',
'hot_qs_title' => 'Hot questions', 'hot_qs_title' => 'Hot questions',
'http_status_405' => 'Error: 405 Method Not Allowed',
'image_not_read' => 'The image could not be read. Please upload one of: ^', 'image_not_read' => 'The image could not be read. Please upload one of: ^',
'image_too_big_x_pc' => 'This image is too big. Please scale to ^% then try again.', 'image_too_big_x_pc' => 'This image is too big. Please scale to ^% then try again.',
'in_category_x' => 'in ^', 'in_category_x' => 'in ^',
......
...@@ -20,6 +20,7 @@ namespace Q2A\Exceptions; ...@@ -20,6 +20,7 @@ namespace Q2A\Exceptions;
use Exception; use Exception;
use Q2A\Http\Exceptions\PageNotFoundException; use Q2A\Http\Exceptions\PageNotFoundException;
use Q2A\Http\Exceptions\MethodNotAllowedException;
class ExceptionHandler class ExceptionHandler
{ {
...@@ -34,6 +35,8 @@ class ExceptionHandler ...@@ -34,6 +35,8 @@ class ExceptionHandler
$this->handleFatalErrorException($exception); $this->handleFatalErrorException($exception);
} elseif ($exception instanceof PageNotFoundException) { } elseif ($exception instanceof PageNotFoundException) {
return $this->handlePageNotFoundException($exception); return $this->handlePageNotFoundException($exception);
} elseif ($exception instanceof MethodNotAllowedException) {
return $this->handleMethodNotAllowedException($exception);
} elseif ($exception instanceof ErrorMessageException) { } elseif ($exception instanceof ErrorMessageException) {
return $this->handleErrorMessageException($exception); return $this->handleErrorMessageException($exception);
} else { } else {
...@@ -48,7 +51,7 @@ class ExceptionHandler ...@@ -48,7 +51,7 @@ class ExceptionHandler
private function handlePageNotFoundException(PageNotFoundException $exception) private function handlePageNotFoundException(PageNotFoundException $exception)
{ {
header('HTTP/1.0 404 Not Found'); header('HTTP/1.1 404 Not Found');
$qa_content = $this->handleErrorMessageException($exception); $qa_content = $this->handleErrorMessageException($exception);
$qa_content['suggest_next'] = qa_html_suggest_qs_tags(qa_using_tags()); $qa_content['suggest_next'] = qa_html_suggest_qs_tags(qa_using_tags());
...@@ -56,6 +59,15 @@ class ExceptionHandler ...@@ -56,6 +59,15 @@ class ExceptionHandler
return $qa_content; return $qa_content;
} }
private function handleMethodNotAllowedException(MethodNotAllowedException $exception)
{
header('HTTP/1.1 405 Method Not Allowed');
$qa_content = $this->handleErrorMessageException($exception);
return $qa_content;
}
private function handleErrorMessageException(ErrorMessageException $exception) private function handleErrorMessageException(ErrorMessageException $exception)
{ {
$qa_content = qa_content_prepare(); $qa_content = qa_content_prepare();
......
<?php
/*
Question2Answer by Gideon Greenspan and contributors
http://www.question2answer.org/
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
More about this license: http://www.question2answer.org/license.php
*/
namespace Q2A\Http\Exceptions;
use Q2A\Exceptions\ErrorMessageException;
class MethodNotAllowedException extends ErrorMessageException
{
/**
* @param string $message
*/
public function __construct($message = null)
{
if ($message === null) {
$message = qa_lang_html('main/http_status_405');
}
parent::__construct($message);
}
}
...@@ -23,8 +23,6 @@ use Q2A\Exceptions\ErrorMessageException; ...@@ -23,8 +23,6 @@ use Q2A\Exceptions\ErrorMessageException;
class PageNotFoundException extends ErrorMessageException class PageNotFoundException extends ErrorMessageException
{ {
/** /**
* PageNotFoundException constructor.
*
* @param string $message * @param string $message
*/ */
public function __construct($message = null) public function __construct($message = null)
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
namespace Q2A\Http; namespace Q2A\Http;
use Q2A\Http\Exceptions\MethodNotAllowedException;
class Router class Router
{ {
/** @var Route[] */ /** @var Route[] */
...@@ -61,12 +63,11 @@ class Router ...@@ -61,12 +63,11 @@ class Router
public function match($request) public function match($request)
{ {
foreach ($this->routes as $route) { foreach ($this->routes as $route) {
if ($route->getHttpMethod() !== $this->httpMethod) {
continue;
}
$pathRegex = $this->buildPathRegex($route->getRoutePath()); $pathRegex = $this->buildPathRegex($route->getRoutePath());
if (preg_match($pathRegex, $request, $matches)) { if (preg_match($pathRegex, $request, $matches)) {
if ($route->getHttpMethod() !== $this->httpMethod) {
throw new MethodNotAllowedException;
}
$route->setParameters(array_slice($matches, 1)); $route->setParameters(array_slice($matches, 1));
return $route; return $route;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment