mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-06-17 00:37:52 +00:00
Development
- Optimised Input-classes. - `get` and `getObject` methods on `Input` now supports filtering on multiple method-types when using the `$method` parameter. - Input classes now know how to parse that stupid nested $_FILES array. - It's now possible to change method-names on ResourceControllers. - Removed `getValue` and `setValue` from `InputFile` classes. - Ensured that request-method are only parsed from $_POST or $_SERVER. - Fixed minor parameter-issues with subdomain routing. - Added PHPDocs. - Added even more unit-tests. - Many small optimisations tweaks.
This commit is contained in:
@@ -22,7 +22,7 @@ interface ILoadableRoute extends IRoute
|
||||
* @param Request $request
|
||||
* @param ILoadableRoute $route
|
||||
*/
|
||||
public function loadMiddleware(Request $request, ILoadableRoute &$route);
|
||||
public function loadMiddleware(Request $request, ILoadableRoute $route);
|
||||
|
||||
public function getUrl();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ interface IRoute
|
||||
* Returns class to be rendered.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return object
|
||||
* @return \Closure|string
|
||||
*/
|
||||
public function renderRoute(Request $request);
|
||||
|
||||
|
||||
@@ -9,7 +9,14 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
{
|
||||
const PARAMETERS_REGEX_MATCH = '%s([\w\-\_]*?)\%s{0,1}%s';
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
@@ -19,7 +26,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
* @param ILoadableRoute $route
|
||||
* @throws HttpException
|
||||
*/
|
||||
public function loadMiddleware(Request $request, ILoadableRoute &$route)
|
||||
public function loadMiddleware(Request $request, ILoadableRoute $route)
|
||||
{
|
||||
if (count($this->getMiddlewares()) > 0) {
|
||||
|
||||
@@ -114,7 +121,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
$param = $keys[$i];
|
||||
$value = $params[$param];
|
||||
|
||||
$value = (isset($parameters[$param])) ? $parameters[$param] : $value;
|
||||
$value = $parameters[$param] ?? $value;
|
||||
|
||||
if (stripos($url, $param1) !== false || stripos($url, $param) !== false) {
|
||||
$url = str_ireplace([sprintf($param1, $param), sprintf($param2, $param)], $value, $url);
|
||||
|
||||
@@ -86,7 +86,7 @@ abstract class Route implements IRoute
|
||||
if ($character === '{') {
|
||||
/* Remove "/" and "\" from regex */
|
||||
if (substr($regex, strlen($regex) - 1) === '/') {
|
||||
$regex = substr($regex, 0, strlen($regex) - 2);
|
||||
$regex = substr($regex, 0, -2);
|
||||
}
|
||||
|
||||
$isParameter = true;
|
||||
@@ -99,7 +99,7 @@ abstract class Route implements IRoute
|
||||
}
|
||||
|
||||
if ($lastCharacter === '?') {
|
||||
$parameter = substr($parameter, 0, strlen($parameter) - 1);
|
||||
$parameter = substr($parameter, 0, -1);
|
||||
$regex .= '(?:\/?(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?)?';
|
||||
$required = false;
|
||||
} else {
|
||||
@@ -136,13 +136,13 @@ abstract class Route implements IRoute
|
||||
|
||||
$name = $parameterNames[$i];
|
||||
|
||||
$parameterValue = isset($parameterValues[$name['name']]) ? $parameterValues[$name['name']] : null;
|
||||
$parameterValue = $parameterValues[$name['name']] ?? null;
|
||||
|
||||
if ($name['required'] && $parameterValue === null) {
|
||||
if ($parameterValue === null && $name['required']) {
|
||||
throw new HttpException('Missing required parameter ' . $name['name'], 404);
|
||||
}
|
||||
|
||||
if ($name['required'] === false && $parameterValue === null) {
|
||||
if ($parameterValue === null && $name['required'] === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -384,10 +384,13 @@ abstract class Route implements IRoute
|
||||
}
|
||||
|
||||
if (count($this->parameters) > 0) {
|
||||
|
||||
/* Ensure the right order + values */
|
||||
$parameters = ($values['parameters'] + $this->parameters);
|
||||
$parameters = ($values['parameters'] ?? []) + $this->parameters;
|
||||
$parameters = array_merge($parameters, $this->parameters);
|
||||
|
||||
$this->setParameters($parameters);
|
||||
$values['parameters'] = $parameters;
|
||||
}
|
||||
|
||||
if (count($this->middlewares) > 0) {
|
||||
@@ -406,7 +409,7 @@ abstract class Route implements IRoute
|
||||
*/
|
||||
public function setSettings(array $values, $merge = false)
|
||||
{
|
||||
if (isset($values['namespace']) && $this->namespace === null) {
|
||||
if ($this->namespace === null && isset($values['namespace'])) {
|
||||
$this->setNamespace($values['namespace']);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,11 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
}
|
||||
|
||||
/* Remove method/type */
|
||||
if (stripos($name, '.') !== false) {
|
||||
if (strpos($name, '.') !== false) {
|
||||
$method = substr($name, strrpos($name, '.') + 1);
|
||||
$newName = substr($name, 0, strrpos($name, '.'));
|
||||
|
||||
if (strtolower($this->name) === strtolower($newName) && in_array($method, $this->names)) {
|
||||
if (in_array($method, $this->names) === true && strtolower($this->name) === strtolower($newName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -43,10 +43,15 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
return parent::hasName($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $method
|
||||
* @param string|array|null $parameters
|
||||
* @param string|null $name
|
||||
* @return string
|
||||
*/
|
||||
public function findUrl($method = null, $parameters = null, $name = null)
|
||||
{
|
||||
|
||||
if (stripos($name, '.') !== false) {
|
||||
if (strpos($name, '.') !== false) {
|
||||
$found = array_search(substr($name, strrpos($name, '.') + 1), $this->names);
|
||||
if ($found !== false) {
|
||||
$method = $found;
|
||||
@@ -54,7 +59,6 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
}
|
||||
|
||||
$url = '';
|
||||
|
||||
$parameters = (array)$parameters;
|
||||
|
||||
/* Remove requestType from method-name, if it exists */
|
||||
@@ -115,7 +119,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
|
||||
$url = rtrim($url, '/') . '/';
|
||||
|
||||
if (strtolower($url) == strtolower($this->url) || stripos($url, $this->url) === 0) {
|
||||
if (stripos($url, $this->url) === 0 && strtolower($url) === strtolower($this->url)) {
|
||||
|
||||
$strippedUrl = trim(str_ireplace($this->url, '/', $url), '/');
|
||||
|
||||
@@ -127,6 +131,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
$this->method = $method;
|
||||
|
||||
array_shift($path);
|
||||
|
||||
$this->parameters = $path;
|
||||
|
||||
// Set callback
|
||||
|
||||
@@ -27,8 +27,8 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
$domain = $this->domains[$i];
|
||||
$parameters = $this->parseParameters($domain, $request->getHost(), '.*');
|
||||
|
||||
if ($parameters !== null) {
|
||||
$this->parameters = $parameters;
|
||||
if ($parameters !== null && count($parameters) > 0) {
|
||||
$this->parameters = array_merge($this->parameters, $parameters);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,17 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
'update' => '',
|
||||
'destroy' => '',
|
||||
];
|
||||
|
||||
protected $methodNames = [
|
||||
'index' => 'index',
|
||||
'create' => 'create',
|
||||
'store' => 'store',
|
||||
'show' => 'show',
|
||||
'edit' => 'edit',
|
||||
'update' => 'update',
|
||||
'destroy' => 'destroy',
|
||||
];
|
||||
|
||||
protected $names = [];
|
||||
protected $controller;
|
||||
|
||||
@@ -42,7 +53,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
}
|
||||
|
||||
/* Remove method/type */
|
||||
if (stripos($name, '.') !== false) {
|
||||
if (strpos($name, '.') !== false) {
|
||||
$name = substr($name, 0, strrpos($name, '.'));
|
||||
}
|
||||
|
||||
@@ -51,7 +62,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
|
||||
public function findUrl($method = null, $parameters = null, $name = null)
|
||||
{
|
||||
$method = array_search($name, $this->names);
|
||||
$method = array_search($name, $this->names, false);
|
||||
if ($method !== false) {
|
||||
return rtrim($this->url . $this->urls[$method], '/') . '/';
|
||||
}
|
||||
@@ -104,43 +115,43 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
|
||||
$parameters = array_merge($this->parameters, (array)$parameters);
|
||||
|
||||
$action = isset($parameters['action']) ? $parameters['action'] : null;
|
||||
$action = $parameters['action'] ?? null;
|
||||
unset($parameters['action']);
|
||||
|
||||
$method = $request->getMethod();
|
||||
|
||||
// Delete
|
||||
if (isset($parameters['id']) && $method === static::REQUEST_TYPE_DELETE) {
|
||||
return $this->call('destroy', $parameters);
|
||||
if ($method === static::REQUEST_TYPE_DELETE && isset($parameters['id'])) {
|
||||
return $this->call($this->methodNames['destroy'], $parameters);
|
||||
}
|
||||
|
||||
// Update
|
||||
if (isset($parameters['id']) && in_array($method, [static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT])) {
|
||||
return $this->call('update', $parameters);
|
||||
return $this->call($this->methodNames['update'], $parameters);
|
||||
}
|
||||
|
||||
// Edit
|
||||
if (isset($parameters['id']) && strtolower($action) === 'edit' && $method === static::REQUEST_TYPE_GET) {
|
||||
return $this->call('edit', $parameters);
|
||||
if ($method === static::REQUEST_TYPE_GET && isset($parameters['id']) && strtolower($action) === 'edit') {
|
||||
return $this->call($this->methodNames['edit'], $parameters);
|
||||
}
|
||||
|
||||
// Create
|
||||
if (strtolower($action) === 'create' && $method === static::REQUEST_TYPE_GET) {
|
||||
return $this->call('create', $parameters);
|
||||
if ($method === static::REQUEST_TYPE_GET && strtolower($action) === 'create') {
|
||||
return $this->call($this->methodNames['create'], $parameters);
|
||||
}
|
||||
|
||||
// Save
|
||||
if ($method === static::REQUEST_TYPE_POST) {
|
||||
return $this->call('store', $parameters);
|
||||
return $this->call($this->methodNames['store'], $parameters);
|
||||
}
|
||||
|
||||
// Show
|
||||
if (isset($parameters['id']) && $method === static::REQUEST_TYPE_GET) {
|
||||
return $this->call('show', $parameters);
|
||||
if ($method === static::REQUEST_TYPE_GET && isset($parameters['id'])) {
|
||||
return $this->call($this->methodNames['show'], $parameters);
|
||||
}
|
||||
|
||||
// Index
|
||||
return $this->call('index', $parameters);
|
||||
return $this->call($this->methodNames['index'], $parameters);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -182,6 +193,29 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define custom method name for resource controller
|
||||
*
|
||||
* @param array $names
|
||||
* @return static $this
|
||||
*/
|
||||
public function setMethodNames(array $names)
|
||||
{
|
||||
$this->methodNames = $names;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get method names
|
||||
*
|
||||
* @return array $this
|
||||
*/
|
||||
public function getMethodNames()
|
||||
{
|
||||
return $this->methodNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge with information from another route.
|
||||
*
|
||||
@@ -195,6 +229,10 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
$this->names = $values['names'];
|
||||
}
|
||||
|
||||
if (isset($values['methods'])) {
|
||||
$this->methodNames = $values['methods'];
|
||||
}
|
||||
|
||||
parent::setSettings($values, $merge);
|
||||
|
||||
return $this;
|
||||
|
||||
@@ -100,7 +100,7 @@ class Router
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
protected function __construct()
|
||||
{
|
||||
$this->reset();
|
||||
}
|
||||
@@ -137,16 +137,26 @@ class Router
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process added routes.
|
||||
*
|
||||
* @param array $routes
|
||||
* @param IGroupRoute|null $group
|
||||
* @param IRoute|null $parent
|
||||
*/
|
||||
protected function processRoutes(array $routes, IGroupRoute $group = null, IRoute $parent = null)
|
||||
{
|
||||
// Loop through each route-request
|
||||
$max = count($routes) - 1;
|
||||
|
||||
$exceptionHandlers = [];
|
||||
|
||||
/* @var $route IRoute */
|
||||
for ($i = $max; $i >= 0; $i--) {
|
||||
|
||||
$route = $routes[$i];
|
||||
|
||||
/* @var $route IGroupRoute */
|
||||
if ($route instanceof IGroupRoute) {
|
||||
|
||||
$group = $route;
|
||||
@@ -159,9 +169,9 @@ class Router
|
||||
|
||||
if ($route->matchRoute($this->request)) {
|
||||
|
||||
/* Add exceptionhandlers */
|
||||
/* Add exception handlers */
|
||||
if (count($route->getExceptionHandlers()) > 0) {
|
||||
$this->exceptionHandlers = array_merge($route->getExceptionHandlers(), $this->exceptionHandlers);
|
||||
$exceptionHandlers += $route->getExceptionHandlers();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -172,7 +182,6 @@ class Router
|
||||
|
||||
/* Add the parent group */
|
||||
$route->setGroup($group);
|
||||
|
||||
}
|
||||
|
||||
if ($parent !== null) {
|
||||
@@ -201,6 +210,8 @@ class Router
|
||||
$this->processRoutes($stack, $route, $group);
|
||||
}
|
||||
}
|
||||
|
||||
$this->exceptionHandlers = array_unique(array_merge($exceptionHandlers, $this->exceptionHandlers));
|
||||
}
|
||||
|
||||
public function routeRequest($rewrite = false)
|
||||
@@ -253,7 +264,7 @@ class Router
|
||||
if ($route->matchRoute($this->request)) {
|
||||
|
||||
/* Check if request method matches */
|
||||
if (count($route->getRequestMethods()) > 0 && !in_array($this->request->getMethod(), $route->getRequestMethods())) {
|
||||
if (count($route->getRequestMethods()) > 0 && in_array($this->request->getMethod(), $route->getRequestMethods()) === false) {
|
||||
$routeNotAllowed = true;
|
||||
continue;
|
||||
}
|
||||
@@ -262,7 +273,7 @@ class Router
|
||||
$this->loadedRoute->loadMiddleware($this->request, $this->loadedRoute);
|
||||
|
||||
/* If the request has changed, we reinitialize the router */
|
||||
if ($this->request->getUri() !== $this->originalUrl && !in_array($this->request->getUri(), $this->routeRewrites)) {
|
||||
if ($this->request->getUri() !== $this->originalUrl && in_array($this->request->getUri(), $this->routeRewrites) === false) {
|
||||
$this->routeRewrites[] = $this->request->getUri();
|
||||
$this->routeRequest(true);
|
||||
|
||||
@@ -309,7 +320,7 @@ class Router
|
||||
$request = $handler->handleError($this->request, $this->loadedRoute, $e);
|
||||
|
||||
/* If the request has changed */
|
||||
if ($request !== null && $this->request->getUri() !== $this->originalUrl && !in_array($request->getUri(), $this->routeRewrites)) {
|
||||
if ($request !== null && $this->request->getUri() !== $this->originalUrl && in_array($request->getUri(), $this->routeRewrites) === false) {
|
||||
$this->request = $request;
|
||||
$this->routeRewrites[] = $request->getUri();
|
||||
$this->routeRequest(true);
|
||||
@@ -375,7 +386,7 @@ class Router
|
||||
if (strpos($name, '@') !== false && strpos($route->getCallback(), '@') !== false && !is_callable($route->getCallback())) {
|
||||
|
||||
/* Check if the entire callback is matching */
|
||||
if (strtolower($route->getCallback()) === strtolower($name) || strpos($route->getCallback(), $name) === 0) {
|
||||
if (strpos($route->getCallback(), $name) === 0 || strtolower($route->getCallback()) === strtolower($name)) {
|
||||
return $route;
|
||||
}
|
||||
|
||||
@@ -404,6 +415,7 @@ class Router
|
||||
* @param string|null $name
|
||||
* @param string|array|null $parameters
|
||||
* @param array|null $getParams
|
||||
* @throws \InvalidArgumentException
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl($name = null, $parameters = null, $getParams = null)
|
||||
@@ -439,7 +451,7 @@ class Router
|
||||
}
|
||||
|
||||
/* Using @ is most definitely a controller@method or alias@method */
|
||||
if (stripos($name, '@') !== false) {
|
||||
if (strpos($name, '@') !== false) {
|
||||
list($controller, $method) = explode('@', $name);
|
||||
|
||||
/* Loop through all the routes to see if we can find a match */
|
||||
|
||||
@@ -309,6 +309,7 @@ class SimpleRouter
|
||||
* @param string|null $name
|
||||
* @param string|array|null $parameters
|
||||
* @param array|null $getParams
|
||||
* @throws \Exception
|
||||
* @return string
|
||||
*/
|
||||
public static function getUrl($name = null, $parameters = null, $getParams = null)
|
||||
|
||||
Reference in New Issue
Block a user