From 2c5221051e0df631a7040e0a2f7f29293c602ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sat, 26 Nov 2016 10:40:42 +0100 Subject: [PATCH 1/8] Development --- src/Pecee/SimpleRouter/Route/IRoute.php | 3 +- .../SimpleRouter/Route/LoadableRoute.php | 35 ++++-- src/Pecee/SimpleRouter/Route/Route.php | 77 +++++++----- .../SimpleRouter/Route/RouteController.php | 51 ++------ src/Pecee/SimpleRouter/Route/RouteGroup.php | 36 +++--- .../SimpleRouter/Route/RouteResource.php | 116 +++++++----------- src/Pecee/SimpleRouter/Route/RouteUrl.php | 24 ++-- src/Pecee/SimpleRouter/Router.php | 9 +- 8 files changed, 165 insertions(+), 186 deletions(-) diff --git a/src/Pecee/SimpleRouter/Route/IRoute.php b/src/Pecee/SimpleRouter/Route/IRoute.php index 14bcbe8..a8df2da 100644 --- a/src/Pecee/SimpleRouter/Route/IRoute.php +++ b/src/Pecee/SimpleRouter/Route/IRoute.php @@ -18,7 +18,8 @@ interface IRoute * Returns class to be rendered. * * @param Request $request - * @return \Closure|string + * @throws \Pecee\SimpleRouter\Exceptions\NotFoundHttpException + * @return void */ public function renderRoute(Request $request); diff --git a/src/Pecee/SimpleRouter/Route/LoadableRoute.php b/src/Pecee/SimpleRouter/Route/LoadableRoute.php index 81b0297..9ae2c0b 100644 --- a/src/Pecee/SimpleRouter/Route/LoadableRoute.php +++ b/src/Pecee/SimpleRouter/Route/LoadableRoute.php @@ -46,6 +46,32 @@ abstract class LoadableRoute extends Route implements ILoadableRoute } } + public function matchRegex(Request $request, $url) { + + /* Match on custom defined regular expression */ + + if ($this->regex === null) { + return false; + } + + $parameters = []; + + if (preg_match($this->regex, $request->getHost() . $url, $parameters) !== false) { + + /* Remove global match */ + if (count($parameters) > 1) { + + $this->setParameters(array_slice($parameters, 1)); + //array_shift($parameters); + //$this->parameters = $parameters; + } + + return true; + } + + return false; + } + /** * Set url * @@ -61,15 +87,8 @@ abstract class LoadableRoute extends Route implements ILoadableRoute $regex = sprintf(static::PARAMETERS_REGEX_MATCH, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]); if (preg_match_all('/' . $regex . '/is', $this->url, $matches)) { - - $max = count($matches[1]); - - for ($i = 0; $i < $max; $i++) { - $this->parameters[$matches[1][$i]] = null; - } - + $this->parameters = array_fill_keys($matches[1], null); } - } return $this; diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index cb2a8d3..283e4d7 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -23,6 +23,13 @@ abstract class Route implements IRoute self::REQUEST_TYPE_DELETE, ]; + /** + * If enabled parameters containing null-value + * will not be passed along to the callback. + * + * @var bool + */ + protected $filterEmptyParams = false; protected $paramModifiers = '{}'; protected $paramOptionalSymbol = '?'; protected $group; @@ -38,6 +45,15 @@ abstract class Route implements IRoute protected $parameters = []; protected $middlewares = []; + protected function loadClass($name) + { + if (!class_exists($name)) { + throw new NotFoundHttpException(sprintf('Class %s does not exist', $name), 404); + } + + return new $name(); + } + public function renderRoute(Request $request) { if ($this->getCallback() !== null && is_callable($this->getCallback())) { @@ -54,20 +70,22 @@ abstract class Route implements IRoute $class = $this->loadClass($className); $method = $controller[1]; - if (!method_exists($class, $method)) { + if (method_exists($class, $method) === false) { throw new NotFoundHttpException(sprintf('Method %s does not exist in class %s', $method, $className), 404); } - $parameters = array_filter($this->getParameters(), function ($var) { - return ($var !== null); - }); + $parameters = []; + + /* Filter parameters with null-value */ + + if ($this->filterEmptyParams === true) { + $parameters = array_filter($this->getParameters(), function ($var) { + return ($var !== null); + }); + } call_user_func_array([$class, $method], $parameters); - - return $class; } - - return null; } protected function parseParameters($route, $url, $parameterRegex = '[\w]+') @@ -84,13 +102,16 @@ abstract class Route implements IRoute $character = strrev($route)[$i]; if ($character === '{') { + /* Remove "/" and "\" from regex */ if (substr($regex, strlen($regex) - 1) === '/') { $regex = substr($regex, 0, -2); } $isParameter = true; - } elseif ($isParameter && $character === '}') { + + } elseif ($isParameter === true && $character === '}') { + $required = true; /* Check for optional parameter and use custom parameter regex if it exists */ @@ -99,11 +120,15 @@ abstract class Route implements IRoute } if ($lastCharacter === '?') { + $parameter = substr($parameter, 0, -1); $regex .= '(?:\/?(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?)?'; $required = false; + } else { + $regex .= '\/?(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?'; + } $parameterNames[] = [ @@ -113,12 +138,19 @@ abstract class Route implements IRoute $parameter = ''; $isParameter = false; - } elseif ($isParameter) { + + } elseif ($isParameter === true) { + $parameter .= $character; + } elseif ($character === '/') { + $regex .= '\\' . $character; + } else { + $regex .= str_replace('.', '\\.', $character); + } $lastCharacter = $character; @@ -129,7 +161,6 @@ abstract class Route implements IRoute if (preg_match('/^' . $regex . '\/?$/is', $url, $parameterValues)) { $parameters = []; - $max = count($parameterNames) - 1; for ($i = $max; $i >= 0; $i--) { @@ -155,15 +186,6 @@ abstract class Route implements IRoute return null; } - protected function loadClass($name) - { - if (!class_exists($name)) { - throw new NotFoundHttpException(sprintf('Class %s does not exist', $name), 404); - } - - return new $name(); - } - /** * Returns callback name/identifier for the current route based on the callback. * Useful if you need to get a unique identifier for the loaded route, for instance @@ -384,13 +406,7 @@ abstract class Route implements IRoute } if (count($this->parameters) > 0) { - - /* Ensure the right order + values */ - $parameters = (isset($values['parameters']) ? $values['parameters'] : []) + $this->parameters; - $parameters = array_merge($parameters, $this->parameters); - - $this->setParameters($parameters); - $values['parameters'] = $parameters; + $values['parameters'] = $this->parameters; } if (count($this->middlewares) > 0) { @@ -422,7 +438,7 @@ abstract class Route implements IRoute } if (isset($values['parameters'])) { - $this->setParameters(array_merge($this->parameters, (array)$values['parameters'])); + $this->setParameters($values['parameters']); } // Push middleware if multiple @@ -487,7 +503,10 @@ abstract class Route implements IRoute */ public function setParameters(array $parameters) { - $this->parameters = $parameters; + /* Ensure the right order + values */ + + $this->parameters = array_fill_keys(array_keys($parameters), null) + $this->parameters; + $this->parameters = $parameters + $this->parameters; return $this; } diff --git a/src/Pecee/SimpleRouter/Route/RouteController.php b/src/Pecee/SimpleRouter/Route/RouteController.php index 486d92a..c4e5520 100644 --- a/src/Pecee/SimpleRouter/Route/RouteController.php +++ b/src/Pecee/SimpleRouter/Route/RouteController.php @@ -2,7 +2,6 @@ namespace Pecee\SimpleRouter\Route; use Pecee\Http\Request; -use Pecee\SimpleRouter\Exceptions\NotFoundHttpException; class RouteController extends LoadableRoute implements IControllerRoute { @@ -35,7 +34,7 @@ class RouteController extends LoadableRoute implements IControllerRoute $method = substr($name, strrpos($name, '.') + 1); $newName = substr($name, 0, strrpos($name, '.')); - if (in_array($method, $this->names) === true && strtolower($this->name) === strtolower($newName)) { + if (in_array($method, $this->names, false) === true && strtolower($this->name) === strtolower($newName)) { return true; } } @@ -52,7 +51,7 @@ class RouteController extends LoadableRoute implements IControllerRoute public function findUrl($method = null, $parameters = null, $name = null) { if (strpos($name, '.') !== false) { - $found = array_search(substr($name, strrpos($name, '.') + 1), $this->names); + $found = array_search(substr($name, strrpos($name, '.') + 1), $this->names, false); if ($found !== false) { $method = $found; } @@ -61,14 +60,10 @@ class RouteController extends LoadableRoute implements IControllerRoute $url = ''; $parameters = (array)$parameters; - /* Remove requestType from method-name, if it exists */ if ($method !== null) { - $max = count(static::$requestTypes); - - for ($i = 0; $i < $max; $i++) { - - $requestType = static::$requestTypes[$i]; + /* Remove requestType from method-name, if it exists */ + foreach(static::$requestTypes as $requestType) { if (stripos($method, $requestType) === 0) { $method = substr($method, strlen($requestType)); @@ -88,37 +83,16 @@ class RouteController extends LoadableRoute implements IControllerRoute return '/' . trim($url, '/') . '/'; } - public function renderRoute(Request $request) - { - if ($this->getCallback() !== null && is_callable($this->getCallback())) { - - // When the callback is a function - call_user_func_array($this->getCallback(), $this->getParameters()); - } else { - // When the callback is a method - $controller = explode('@', $this->getCallback()); - $className = $this->getNamespace() . '\\' . $controller[0]; - - $class = $this->loadClass($className); - $method = $request->getMethod() . ucfirst($controller[1]); - - if (!method_exists($class, $method)) { - throw new NotFoundHttpException(sprintf('Method %s does not exist in class %s', $method, $className), 404); - } - - call_user_func_array([$class, $method], $this->getParameters()); - - return $class; - } - - return null; - } - public function matchRoute(Request $request) { $url = parse_url(urldecode($request->getUri()), PHP_URL_PATH); $url = rtrim($url, '/') . '/'; + /* Match global regular-expression for route */ + if($this->matchRegex($request, $url) === true) { + return true; + } + if (stripos($url, $this->url) === 0 && strtolower($url) === strtolower($this->url)) { $strippedUrl = trim(str_ireplace($this->url, '/', $url), '/'); @@ -130,9 +104,10 @@ class RouteController extends LoadableRoute implements IControllerRoute $method = (!isset($path[0]) || trim($path[0]) === '') ? $this->defaultMethod : $path[0]; $this->method = $method; - array_shift($path); + //array_shift($path); + //$this->parameters = $path; - $this->parameters = $path; + $this->setParameters(array_slice($path, 1)); // Set callback $this->setCallback($this->controller . '@' . $this->method); @@ -141,7 +116,7 @@ class RouteController extends LoadableRoute implements IControllerRoute } } - return null; + return false; } /** diff --git a/src/Pecee/SimpleRouter/Route/RouteGroup.php b/src/Pecee/SimpleRouter/Route/RouteGroup.php index f55567d..c466749 100644 --- a/src/Pecee/SimpleRouter/Route/RouteGroup.php +++ b/src/Pecee/SimpleRouter/Route/RouteGroup.php @@ -18,26 +18,24 @@ class RouteGroup extends Route implements IGroupRoute */ public function matchDomain(Request $request) { - if (count($this->domains) > 0) { - - $max = count($this->domains) - 1; - - for ($i = $max; $i >= 0; $i--) { - - $domain = $this->domains[$i]; - $parameters = $this->parseParameters($domain, $request->getHost(), '.*'); - - if ($parameters !== null && count($parameters) > 0) { - $this->parameters = array_merge($this->parameters, $parameters); - - return true; - } - } - - return false; + if (count($this->domains) === 0) { + return true; } - return true; + foreach($this->domains as $domain) { + + $parameters = $this->parseParameters($domain, $request->getHost(), '.*'); + + if ($parameters !== null && count($parameters) > 0) { + + $this->setParameters($parameters); + //$this->parameters = array_merge($this->parameters, $parameters); + + return true; + } + } + + return false; } /** @@ -48,7 +46,7 @@ class RouteGroup extends Route implements IGroupRoute */ public function matchRoute(Request $request) { - // Skip if prefix doesn't match + /* Skip if prefix doesn't match */ if ($this->prefix !== null && stripos($request->getUri(), $this->prefix) === false) { return false; } diff --git a/src/Pecee/SimpleRouter/Route/RouteResource.php b/src/Pecee/SimpleRouter/Route/RouteResource.php index a4ea2b3..2efdbd6 100644 --- a/src/Pecee/SimpleRouter/Route/RouteResource.php +++ b/src/Pecee/SimpleRouter/Route/RouteResource.php @@ -2,7 +2,6 @@ namespace Pecee\SimpleRouter\Route; use Pecee\Http\Request; -use Pecee\SimpleRouter\Exceptions\NotFoundHttpException; class RouteResource extends LoadableRoute implements IControllerRoute { @@ -70,34 +69,9 @@ class RouteResource extends LoadableRoute implements IControllerRoute return $this->url; } - public function renderRoute(Request $request) - { - if ($this->getCallback() !== null && is_callable($this->getCallback())) { - // When the callback is a function - call_user_func_array($this->getCallback(), $this->getParameters()); - } else { - // When the callback is a method - $controller = explode('@', $this->getCallback()); - $className = $this->getNamespace() . '\\' . $controller[0]; - $class = $this->loadClass($className); - $method = strtolower($controller[1]); - - if (!method_exists($class, $method)) { - throw new NotFoundHttpException(sprintf('Method %s does not exist in class %s', $method, $className), 404); - } - - call_user_func_array([$class, $method], $this->getParameters()); - - return $class; - } - - return null; - } - - protected function call($method, $parameters) + protected function call($method) { $this->setCallback($this->controller . '@' . $method); - $this->parameters = $parameters; return true; } @@ -107,54 +81,58 @@ class RouteResource extends LoadableRoute implements IControllerRoute $url = parse_url(urldecode($request->getUri()), PHP_URL_PATH); $url = rtrim($url, '/') . '/'; + /* Match global regular-expression for route */ + if($this->matchRegex($request, $url) === true) { + return true; + } + $route = rtrim($this->url, '/') . '/{id?}/{action?}'; $parameters = $this->parseParameters($route, $url); - if ($parameters !== null) { - - $parameters = array_merge($this->parameters, (array)$parameters); - - $action = isset($parameters['action']) ? $parameters['action'] : null; - unset($parameters['action']); - - $method = $request->getMethod(); - - // Delete - 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($this->methodNames['update'], $parameters); - } - - // Edit - if ($method === static::REQUEST_TYPE_GET && isset($parameters['id']) && strtolower($action) === 'edit') { - return $this->call($this->methodNames['edit'], $parameters); - } - - // Create - 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($this->methodNames['store'], $parameters); - } - - // Show - if ($method === static::REQUEST_TYPE_GET && isset($parameters['id'])) { - return $this->call($this->methodNames['show'], $parameters); - } - - // Index - return $this->call($this->methodNames['index'], $parameters); + if ($parameters === null) { + return false; } - return null; + $this->setParameters((array)$parameters); + + $action = isset($this->parameters['action']) ? $this->parameters['action'] : null; + unset($this->parameters['action']); + + $method = $request->getMethod(); + + // Delete + if ($method === static::REQUEST_TYPE_DELETE && isset($this->parameters['id'])) { + return $this->call($this->methodNames['destroy']); + } + + // Update + if (isset($this->parameters['id']) && in_array($method, [ static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT ])) { + return $this->call($this->methodNames['update']); + } + + // Edit + if ($method === static::REQUEST_TYPE_GET && isset($this->parameters['id']) && strtolower($action) === 'edit') { + return $this->call($this->methodNames['edit']); + } + + // Create + if ($method === static::REQUEST_TYPE_GET && strtolower($action) === 'create') { + return $this->call($this->methodNames['create']); + } + + // Save + if ($method === static::REQUEST_TYPE_POST) { + return $this->call($this->methodNames['store']); + } + + // Show + if ($method === static::REQUEST_TYPE_GET && isset($this->parameters['id'])) { + return $this->call($this->methodNames['show']); + } + + // Index + return $this->call($this->methodNames['index']); } /** diff --git a/src/Pecee/SimpleRouter/Route/RouteUrl.php b/src/Pecee/SimpleRouter/Route/RouteUrl.php index baa2329..ff9be14 100644 --- a/src/Pecee/SimpleRouter/Route/RouteUrl.php +++ b/src/Pecee/SimpleRouter/Route/RouteUrl.php @@ -16,34 +16,24 @@ class RouteUrl extends LoadableRoute $url = parse_url(urldecode($request->getUri()), PHP_URL_PATH); $url = rtrim($url, '/') . '/'; - // Match on custom defined regular expression - if ($this->regex !== null) { - $parameters = []; - if (preg_match($this->regex, $request->getHost() . $url, $parameters)) { - /* Remove global match */ - if (count($parameters) > 1) { - array_shift($parameters); - $this->parameters = $parameters; - } - - return true; - } - - return null; + /* Match global regular-expression for route */ + if($this->matchRegex($request, $url) === true) { + return true; } - // Make regular expression based on route + /* Make regular expression based on route */ $route = rtrim($this->url, '/') . '/'; $parameters = $this->parseParameters($route, $url); if ($parameters !== null) { - $this->parameters = array_merge($this->parameters, $parameters); + $this->setParameters($parameters); + //$this->parameters = array_merge($this->parameters, $parameters); return true; } - return null; + return false; } } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php index e031431..7b8a9f2 100644 --- a/src/Pecee/SimpleRouter/Router.php +++ b/src/Pecee/SimpleRouter/Router.php @@ -167,7 +167,7 @@ class Router $route->renderRoute($this->request); $this->processingRoute = false; - if ($route->matchRoute($this->request)) { + if ($route->matchRoute($this->request) === true) { /* Add exception handlers */ if (count($route->getExceptionHandlers()) > 0) { @@ -220,7 +220,6 @@ class Router $routeNotAllowed = false; try { - /* Initialize boot-managers */ if (count($this->bootManagers) > 0) { @@ -246,7 +245,7 @@ class Router if ($this->csrfVerifier !== null) { - // Verify csrf token for request + /* Verify csrf token for request */ $this->csrfVerifier->handle($this->request); } @@ -261,10 +260,10 @@ class Router $route = $this->processedRoutes[$i]; /* If the route matches */ - if ($route->matchRoute($this->request)) { + if ($route->matchRoute($this->request) === true) { /* Check if request method matches */ - if (count($route->getRequestMethods()) > 0 && in_array($this->request->getMethod(), $route->getRequestMethods()) === false) { + if (count($route->getRequestMethods()) > 0 && in_array($this->request->getMethod(), $route->getRequestMethods(), false) === false) { $routeNotAllowed = true; continue; } From f5b03e106ca5e7ce5d15a9f5d4223965561b5940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 27 Nov 2016 00:55:47 +0100 Subject: [PATCH 2/8] Bugfixes --- .../SimpleRouter/Route/LoadableRoute.php | 5 +- src/Pecee/SimpleRouter/Route/Route.php | 143 +++++++++++------- src/Pecee/SimpleRouter/Route/RouteUrl.php | 10 +- 3 files changed, 89 insertions(+), 69 deletions(-) diff --git a/src/Pecee/SimpleRouter/Route/LoadableRoute.php b/src/Pecee/SimpleRouter/Route/LoadableRoute.php index 9ae2c0b..8ab37fc 100644 --- a/src/Pecee/SimpleRouter/Route/LoadableRoute.php +++ b/src/Pecee/SimpleRouter/Route/LoadableRoute.php @@ -51,7 +51,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute /* Match on custom defined regular expression */ if ($this->regex === null) { - return false; + return null; } $parameters = []; @@ -60,10 +60,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute /* Remove global match */ if (count($parameters) > 1) { - $this->setParameters(array_slice($parameters, 1)); - //array_shift($parameters); - //$this->parameters = $parameters; } return true; diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 283e4d7..4d43be5 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -2,7 +2,6 @@ namespace Pecee\SimpleRouter\Route; use Pecee\Http\Request; -use Pecee\SimpleRouter\Exceptions\HttpException; use Pecee\SimpleRouter\Exceptions\NotFoundHttpException; abstract class Route implements IRoute @@ -43,6 +42,7 @@ abstract class Route implements IRoute protected $requestMethods = []; protected $where = []; protected $parameters = []; + protected $originalParameters = []; protected $middlewares = []; protected function loadClass($name) @@ -74,12 +74,12 @@ abstract class Route implements IRoute throw new NotFoundHttpException(sprintf('Method %s does not exist in class %s', $method, $className), 404); } - $parameters = []; + $parameters = $this->getParameters(); /* Filter parameters with null-value */ if ($this->filterEmptyParams === true) { - $parameters = array_filter($this->getParameters(), function ($var) { + $parameters = array_filter($parameters, function ($var) { return ($var !== null); }); } @@ -88,8 +88,12 @@ abstract class Route implements IRoute } } - protected function parseParameters($route, $url, $parameterRegex = '[\w]+') - { + protected function generateRouteRegEx($route, $parameterRegex = '[\w]+') { + + /* Make regular expression based on route */ + + $route = rtrim($route, '/') . '/'; + $parameterNames = []; $regex = ''; $lastCharacter = ''; @@ -103,81 +107,91 @@ abstract class Route implements IRoute if ($character === '{') { - /* Remove "/" and "\" from regex */ + /* Strip "/" and "\" from regex */ + if (substr($regex, strlen($regex) - 1) === '/') { $regex = substr($regex, 0, -2); } $isParameter = true; - } elseif ($isParameter === true && $character === '}') { - - $required = true; - - /* Check for optional parameter and use custom parameter regex if it exists */ - if (is_array($this->where) === true && isset($this->where[$parameter])) { - $parameterRegex = $this->where[$parameter]; - } - - if ($lastCharacter === '?') { - - $parameter = substr($parameter, 0, -1); - $regex .= '(?:\/?(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?)?'; - $required = false; - - } else { - - $regex .= '\/?(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?'; - - } - - $parameterNames[] = [ - 'name' => $parameter, - 'required' => $required, - ]; - - $parameter = ''; - $isParameter = false; - } elseif ($isParameter === true) { - $parameter .= $character; + if($character === '}') { - } elseif ($character === '/') { + $required = true; + /* Check for optional parameter and use custom parameter regex if it exists */ + + if (is_array($this->where) === true && isset($this->where[$parameter])) { + $parameterRegex = $this->where[$parameter]; + } + + if ($lastCharacter === '?') { + + $parameter = substr($parameter, 0, -1); + $regex .= '(?:\/(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?)?'; + $required = false; + + } else { + + $regex .= '\/(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?'; + } + + $parameterNames[] = [ + 'name' => $parameter, + 'required' => $required, + ]; + + $parameter = ''; + $isParameter = false; + + } else { + $parameter .= $character; + } + + + } else if ($character === '/') { $regex .= '\\' . $character; - } else { - $regex .= str_replace('.', '\\.', $character); - } $lastCharacter = $character; } - $parameterValues = []; + $this->regex = $regex; - if (preg_match('/^' . $regex . '\/?$/is', $url, $parameterValues)) { + return [ + 'regex' => $regex, + 'parameters' => $parameterNames + ]; + } + + protected function parseParameters($route, $url, $parameterRegex = '[\w]+') + { + $result = $this->generateRouteRegEx($route, $parameterRegex); + + $parameterNames = $result['parameters']; + + if (preg_match('/^' . $result['regex'] . '\/?$/is', $url, $matches)) { $parameters = []; + $max = count($parameterNames) - 1; for ($i = $max; $i >= 0; $i--) { - $name = $parameterNames[$i]; + $name = $parameterNames[$i]['name']; + $required = $parameterNames[$i]['required']; - $parameterValue = isset($parameterValues[$name['name']]) ? $parameterValues[$name['name']] : null; + $param = isset($matches[$name]) ? $matches[$name] : null; - if ($parameterValue === null && $name['required']) { - throw new HttpException('Missing required parameter ' . $name['name'], 404); + if ($required === true && isset($this->parameters[$name]) === true && trim($param) === '') { + $param = $this->parameters[$name]; } - if ($parameterValue === null && $name['required'] === false) { - continue; - } - - $parameters[$name['name']] = $parameterValue; + $parameters[$name] = $param; } return $parameters; @@ -405,9 +419,9 @@ abstract class Route implements IRoute $values['where'] = $this->where; } - if (count($this->parameters) > 0) { + /*if (count($this->parameters) > 0) { $values['parameters'] = $this->parameters; - } + }*/ if (count($this->middlewares) > 0) { $values['middleware'] = $this->middlewares; @@ -438,7 +452,7 @@ abstract class Route implements IRoute } if (isset($values['parameters'])) { - $this->setParameters($values['parameters']); + $this->setParameters(array_merge($this->parameters, (array)$values['parameters'])); } // Push middleware if multiple @@ -492,7 +506,14 @@ abstract class Route implements IRoute */ public function getParameters() { - return $this->parameters; + /* Sort the parameters after the user-defined param order, if any */ + $parameters = array(); + + if(count($this->originalParameters) > 0) { + $parameters = $this->originalParameters; + } + + return array_merge($parameters, $this->parameters); } /** @@ -503,10 +524,16 @@ abstract class Route implements IRoute */ public function setParameters(array $parameters) { - /* Ensure the right order + values */ + /* + * If this is the first time setting parameters we store them so we + * later can organize the array, in case somebody tried to sort the array. + */ - $this->parameters = array_fill_keys(array_keys($parameters), null) + $this->parameters; - $this->parameters = $parameters + $this->parameters; + if(count($parameters) > 0 && count($this->originalParameters) === 0) { + $this->originalParameters = $parameters; + } + + $this->parameters = $parameters; return $this; } diff --git a/src/Pecee/SimpleRouter/Route/RouteUrl.php b/src/Pecee/SimpleRouter/Route/RouteUrl.php index ff9be14..0206961 100644 --- a/src/Pecee/SimpleRouter/Route/RouteUrl.php +++ b/src/Pecee/SimpleRouter/Route/RouteUrl.php @@ -22,18 +22,14 @@ class RouteUrl extends LoadableRoute } /* Make regular expression based on route */ - $route = rtrim($this->url, '/') . '/'; - - $parameters = $this->parseParameters($route, $url); - - if ($parameters !== null) { + $parameters = $this->parseParameters($this->url, $url); + if($parameters !== null) { $this->setParameters($parameters); - //$this->parameters = array_merge($this->parameters, $parameters); - return true; } return false; + } } \ No newline at end of file From 74351e0330e1d4172191f19139bc19151ef11279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 27 Nov 2016 01:07:11 +0100 Subject: [PATCH 3/8] Bugfixes --- src/Pecee/SimpleRouter/Route/LoadableRoute.php | 3 ++- src/Pecee/SimpleRouter/Route/Route.php | 3 +-- src/Pecee/SimpleRouter/Route/RouteController.php | 2 +- src/Pecee/SimpleRouter/Route/RouteGroup.php | 4 +--- src/Pecee/SimpleRouter/Route/RouteResource.php | 10 +++++----- src/Pecee/SimpleRouter/Route/RouteUrl.php | 5 +++-- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Pecee/SimpleRouter/Route/LoadableRoute.php b/src/Pecee/SimpleRouter/Route/LoadableRoute.php index 8ab37fc..8696bfa 100644 --- a/src/Pecee/SimpleRouter/Route/LoadableRoute.php +++ b/src/Pecee/SimpleRouter/Route/LoadableRoute.php @@ -37,6 +37,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute $middleware = $this->getMiddlewares()[$i]; $middleware = $this->loadClass($middleware); + if (!($middleware instanceof IMiddleware)) { throw new HttpException($middleware . ' must be instance of Middleware'); } @@ -60,7 +61,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute /* Remove global match */ if (count($parameters) > 1) { - $this->setParameters(array_slice($parameters, 1)); + $this->parameters = array_slice($parameters, 1); } return true; diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 4d43be5..03b8093 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -47,7 +47,7 @@ abstract class Route implements IRoute protected function loadClass($name) { - if (!class_exists($name)) { + if (class_exists($name) === false) { throw new NotFoundHttpException(sprintf('Class %s does not exist', $name), 404); } @@ -528,7 +528,6 @@ abstract class Route implements IRoute * If this is the first time setting parameters we store them so we * later can organize the array, in case somebody tried to sort the array. */ - if(count($parameters) > 0 && count($this->originalParameters) === 0) { $this->originalParameters = $parameters; } diff --git a/src/Pecee/SimpleRouter/Route/RouteController.php b/src/Pecee/SimpleRouter/Route/RouteController.php index c4e5520..a47cf52 100644 --- a/src/Pecee/SimpleRouter/Route/RouteController.php +++ b/src/Pecee/SimpleRouter/Route/RouteController.php @@ -107,7 +107,7 @@ class RouteController extends LoadableRoute implements IControllerRoute //array_shift($path); //$this->parameters = $path; - $this->setParameters(array_slice($path, 1)); + $this->parameters = array_slice($path, 1); // Set callback $this->setCallback($this->controller . '@' . $this->method); diff --git a/src/Pecee/SimpleRouter/Route/RouteGroup.php b/src/Pecee/SimpleRouter/Route/RouteGroup.php index c466749..acf5323 100644 --- a/src/Pecee/SimpleRouter/Route/RouteGroup.php +++ b/src/Pecee/SimpleRouter/Route/RouteGroup.php @@ -28,9 +28,7 @@ class RouteGroup extends Route implements IGroupRoute if ($parameters !== null && count($parameters) > 0) { - $this->setParameters($parameters); - //$this->parameters = array_merge($this->parameters, $parameters); - + $this->parameters = $parameters; return true; } } diff --git a/src/Pecee/SimpleRouter/Route/RouteResource.php b/src/Pecee/SimpleRouter/Route/RouteResource.php index 2efdbd6..16e537a 100644 --- a/src/Pecee/SimpleRouter/Route/RouteResource.php +++ b/src/Pecee/SimpleRouter/Route/RouteResource.php @@ -82,19 +82,19 @@ class RouteResource extends LoadableRoute implements IControllerRoute $url = rtrim($url, '/') . '/'; /* Match global regular-expression for route */ - if($this->matchRegex($request, $url) === true) { - return true; + $domainMatch = $this->matchRegex($request, $url); + if($domainMatch !== null) { + return $domainMatch; } $route = rtrim($this->url, '/') . '/{id?}/{action?}'; $parameters = $this->parseParameters($route, $url); - if ($parameters === null) { return false; } - $this->setParameters((array)$parameters); + $this->parameters = (array)$parameters; $action = isset($this->parameters['action']) ? $this->parameters['action'] : null; unset($this->parameters['action']); @@ -107,7 +107,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute } // Update - if (isset($this->parameters['id']) && in_array($method, [ static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT ])) { + if (isset($this->parameters['id']) && in_array($method, [ static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT ], false)) { return $this->call($this->methodNames['update']); } diff --git a/src/Pecee/SimpleRouter/Route/RouteUrl.php b/src/Pecee/SimpleRouter/Route/RouteUrl.php index 0206961..0f2660d 100644 --- a/src/Pecee/SimpleRouter/Route/RouteUrl.php +++ b/src/Pecee/SimpleRouter/Route/RouteUrl.php @@ -17,8 +17,9 @@ class RouteUrl extends LoadableRoute $url = rtrim($url, '/') . '/'; /* Match global regular-expression for route */ - if($this->matchRegex($request, $url) === true) { - return true; + $domainMatch = $this->matchRegex($request, $url); + if($domainMatch !== null) { + return $domainMatch; } /* Make regular expression based on route */ From d9b97ccf4202d9ed88b0559ee994031c493dc4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 28 Nov 2016 04:20:34 +0100 Subject: [PATCH 4/8] Bugfixes --- src/Pecee/Http/Input/Input.php | 14 +- src/Pecee/Http/Input/InputFile.php | 5 +- .../Http/Middleware/BaseCsrfVerifier.php | 2 +- src/Pecee/Http/Request.php | 2 +- .../SimpleRouter/Route/LoadableRoute.php | 9 +- src/Pecee/SimpleRouter/Route/Route.php | 128 +++++------------- .../SimpleRouter/Route/RouteController.php | 3 - src/Pecee/SimpleRouter/Route/RouteGroup.php | 4 + src/Pecee/SimpleRouter/Route/RouteUrl.php | 9 +- test/RouterRouteTest.php | 30 ++-- 10 files changed, 74 insertions(+), 132 deletions(-) diff --git a/src/Pecee/Http/Input/Input.php b/src/Pecee/Http/Input/Input.php index 4c8fd71..6f3a9c4 100644 --- a/src/Pecee/Http/Input/Input.php +++ b/src/Pecee/Http/Input/Input.php @@ -51,18 +51,17 @@ class Input } /* Parse get requests */ - $this->file = $this->parseFiles(); + if (count($_FILES) > 0) { + $this->file = $this->parseFiles(); + } } public function parseFiles() { - if (count($_FILES) === 0) { - return []; - } - + $files = $_FILES; $list = []; - foreach ($_FILES as $key => $value) { + foreach ($files as $key => $value) { // Handle array input if (is_array($value['name']) === false) { @@ -95,7 +94,8 @@ class Input $path = $original[$property]; - foreach (array_values($index) as $i) { + $tmp = array_values($index); + foreach ($tmp as $i) { $path = $path[$i]; } diff --git a/src/Pecee/Http/Input/InputFile.php b/src/Pecee/Http/Input/InputFile.php index 6fdec72..6ec141b 100644 --- a/src/Pecee/Http/Input/InputFile.php +++ b/src/Pecee/Http/Input/InputFile.php @@ -42,14 +42,13 @@ class InputFile implements IInputItem 'error' => null, ], $values); - $input = new static($values['index']); - $input->setError($values['error']) + return (new static($values['index'])) + ->setError($values['error']) ->setSize($values['size']) ->setType($values['type']) ->setTmpName($values['tmp_name']) ->setFilename($values['name']); - return $input; } /** diff --git a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php index 046251b..7a96ba9 100644 --- a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php +++ b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php @@ -58,7 +58,7 @@ class BaseCsrfVerifier implements IMiddleware public function handle(Request $request, ILoadableRoute &$route = null) { - if ($this->skip($request) === false && in_array($request->getMethod(), ['post', 'put', 'delete']) === true) { + if ($this->skip($request) === false && in_array($request->getMethod(), ['post', 'put', 'delete'], false) === true) { $token = $request->getInput()->get(static::POST_KEY, null, 'post'); diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index 8215a27..eb2fe26 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -215,7 +215,7 @@ class Request public function __isset($name) { - return $this->data[$name] ?? null; + return array_key_exists($name, $this->data); } public function __set($name, $value = null) diff --git a/src/Pecee/SimpleRouter/Route/LoadableRoute.php b/src/Pecee/SimpleRouter/Route/LoadableRoute.php index 8696bfa..a6a40a5 100644 --- a/src/Pecee/SimpleRouter/Route/LoadableRoute.php +++ b/src/Pecee/SimpleRouter/Route/LoadableRoute.php @@ -7,8 +7,6 @@ use Pecee\SimpleRouter\Exceptions\HttpException; abstract class LoadableRoute extends Route implements ILoadableRoute { - const PARAMETERS_REGEX_MATCH = '%s([\w\-\_]*?)\%s{0,1}%s'; - /** * @var */ @@ -57,12 +55,10 @@ abstract class LoadableRoute extends Route implements ILoadableRoute $parameters = []; - if (preg_match($this->regex, $request->getHost() . $url, $parameters) !== false) { + if (preg_match($this->regex, $request->getHost() . $url, $parameters) > 0) { /* Remove global match */ - if (count($parameters) > 1) { - $this->parameters = array_slice($parameters, 1); - } + $this->parameters = array_slice($parameters, 1); return true; } @@ -147,6 +143,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute } } + /** @noinspection AliasFunctionsUsageInspection */ $url .= join('/', $unknownParams); return rtrim($url, '/') . '/'; diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 03b8093..ff62281 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -6,6 +6,8 @@ use Pecee\SimpleRouter\Exceptions\NotFoundHttpException; abstract class Route implements IRoute { + const PARAMETERS_REGEX_MATCH = '%s([\w\-\_]*?)(\%s{0,1})%s'; + const REQUEST_TYPE_GET = 'get'; const REQUEST_TYPE_POST = 'post'; const REQUEST_TYPE_PUT = 'put'; @@ -88,113 +90,49 @@ abstract class Route implements IRoute } } - protected function generateRouteRegEx($route, $parameterRegex = '[\w]+') { - - /* Make regular expression based on route */ - - $route = rtrim($route, '/') . '/'; - - $parameterNames = []; - $regex = ''; - $lastCharacter = ''; - $isParameter = false; - $parameter = ''; - $routeLength = strlen($route) - 1; - - for ($i = $routeLength; $i >= 0; $i--) { - - $character = strrev($route)[$i]; - - if ($character === '{') { - - /* Strip "/" and "\" from regex */ - - if (substr($regex, strlen($regex) - 1) === '/') { - $regex = substr($regex, 0, -2); - } - - $isParameter = true; - - } elseif ($isParameter === true) { - - if($character === '}') { - - $required = true; - - /* Check for optional parameter and use custom parameter regex if it exists */ - - if (is_array($this->where) === true && isset($this->where[$parameter])) { - $parameterRegex = $this->where[$parameter]; - } - - if ($lastCharacter === '?') { - - $parameter = substr($parameter, 0, -1); - $regex .= '(?:\/(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?)?'; - $required = false; - - } else { - - $regex .= '\/(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?'; - } - - $parameterNames[] = [ - 'name' => $parameter, - 'required' => $required, - ]; - - $parameter = ''; - $isParameter = false; - - } else { - $parameter .= $character; - } - - - } else if ($character === '/') { - $regex .= '\\' . $character; - } else { - $regex .= str_replace('.', '\\.', $character); - } - - $lastCharacter = $character; - } - - $this->regex = $regex; - - return [ - 'regex' => $regex, - 'parameters' => $parameterNames - ]; - } - protected function parseParameters($route, $url, $parameterRegex = '[\w]+') { - $result = $this->generateRouteRegEx($route, $parameterRegex); + $regex = sprintf(static::PARAMETERS_REGEX_MATCH, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]); - $parameterNames = $result['parameters']; + if (preg_match_all('/' . $regex . '/is', $route, $parameters)) { - if (preg_match('/^' . $result['regex'] . '\/?$/is', $url, $matches)) { + $parameterNamesRegex = []; + $parameterNames = $parameters[1]; + $parameterRequired = []; - $parameters = []; + $urlParts = preg_split('/\{[^}]+\}/is', rtrim($route, '/')); - $max = count($parameterNames) - 1; + foreach($urlParts as $key => $t) { - for ($i = $max; $i >= 0; $i--) { + $regex = ''; - $name = $parameterNames[$i]['name']; - $required = $parameterNames[$i]['required']; + if($key < (count($parameters[1]))) { - $param = isset($matches[$name]) ? $matches[$name] : null; + $name = $parameters[1][$key]; + $regex = isset($this->where[$name]) ? $this->where[$name] : $parameterRegex; + $regex = sprintf('(?P<%s>%s)', $name, $regex) . $parameters[2][$key]; - if ($required === true && isset($this->parameters[$name]) === true && trim($param) === '') { - $param = $this->parameters[$name]; } - $parameters[$name] = $param; + $urlParts[$key] = preg_quote($t, '/') . $regex; } - return $parameters; + $urlRegex = join('', $urlParts); + + } else { + $urlRegex = preg_quote($route, '/'); + } + + if(preg_match('/^' . $urlRegex . '(\/?)$/is', $url, $matches) > 0) { + + $values = []; + + /* Only take matched parameters with name */ + foreach($parameters[1] as $name) { + $values[$name] = $matches[$name]; + } + + return $values; } return null; @@ -419,10 +357,6 @@ abstract class Route implements IRoute $values['where'] = $this->where; } - /*if (count($this->parameters) > 0) { - $values['parameters'] = $this->parameters; - }*/ - if (count($this->middlewares) > 0) { $values['middleware'] = $this->middlewares; } diff --git a/src/Pecee/SimpleRouter/Route/RouteController.php b/src/Pecee/SimpleRouter/Route/RouteController.php index a47cf52..9d520fd 100644 --- a/src/Pecee/SimpleRouter/Route/RouteController.php +++ b/src/Pecee/SimpleRouter/Route/RouteController.php @@ -104,9 +104,6 @@ class RouteController extends LoadableRoute implements IControllerRoute $method = (!isset($path[0]) || trim($path[0]) === '') ? $this->defaultMethod : $path[0]; $this->method = $method; - //array_shift($path); - //$this->parameters = $path; - $this->parameters = array_slice($path, 1); // Set callback diff --git a/src/Pecee/SimpleRouter/Route/RouteGroup.php b/src/Pecee/SimpleRouter/Route/RouteGroup.php index acf5323..e24723b 100644 --- a/src/Pecee/SimpleRouter/Route/RouteGroup.php +++ b/src/Pecee/SimpleRouter/Route/RouteGroup.php @@ -171,6 +171,10 @@ class RouteGroup extends Route implements IGroupRoute $values['as'] = $this->name; } + if (count($this->parameters) > 0) { + $values['parameters'] = $this->parameters; + } + return array_merge($values, parent::toArray()); } diff --git a/src/Pecee/SimpleRouter/Route/RouteUrl.php b/src/Pecee/SimpleRouter/Route/RouteUrl.php index 0f2660d..9cc082f 100644 --- a/src/Pecee/SimpleRouter/Route/RouteUrl.php +++ b/src/Pecee/SimpleRouter/Route/RouteUrl.php @@ -24,12 +24,13 @@ class RouteUrl extends LoadableRoute /* Make regular expression based on route */ $parameters = $this->parseParameters($this->url, $url); - if($parameters !== null) { - $this->setParameters($parameters); - return true; + if($parameters === null) { + return false; } - return false; + $this->setParameters($parameters); + + return true; } diff --git a/test/RouterRouteTest.php b/test/RouterRouteTest.php index 23bdaff..5637f46 100644 --- a/test/RouterRouteTest.php +++ b/test/RouterRouteTest.php @@ -14,6 +14,26 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase { protected $result = false; + public function testMultiParam() + { + SimpleRouter::router()->reset(); + SimpleRouter::request()->setMethod('get'); + SimpleRouter::request()->setUri('/test-param1-param2'); + + SimpleRouter::get('/test-{param1}-{param2}', function($param1, $param2) { + + if($param1 === 'param1' && $param2 === 'param2') { + $this->result = true; + } + + }); + + SimpleRouter::start(); + + $this->assertTrue($this->result); + + } + /** * Redirects to another route through 3 exception handlers. * @@ -118,16 +138,6 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase SimpleRouter::start(); } - public function testMultiParam() - { - SimpleRouter::router()->reset(); - SimpleRouter::request()->setMethod('get'); - SimpleRouter::request()->setUri('/test-param1-param2'); - - SimpleRouter::get('/test-{param1}-{param2}', 'DummyController@param'); - SimpleRouter::start(); - } - public function testPathParamRegex() { SimpleRouter::router()->reset(); From 7847b71bbc290513a037f8b6ad74dcdea92d50ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 28 Nov 2016 04:38:38 +0100 Subject: [PATCH 5/8] Cleanup --- src/Pecee/Http/Input/Input.php | 3 +-- src/Pecee/SimpleRouter/Route/LoadableRoute.php | 3 ++- src/Pecee/SimpleRouter/Route/Route.php | 14 +++++++------- src/Pecee/SimpleRouter/Route/RouteController.php | 4 ++-- src/Pecee/SimpleRouter/Route/RouteGroup.php | 3 ++- src/Pecee/SimpleRouter/Route/RouteResource.php | 4 ++-- src/Pecee/SimpleRouter/Route/RouteUrl.php | 4 ++-- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Pecee/Http/Input/Input.php b/src/Pecee/Http/Input/Input.php index 6f3a9c4..a1aa0b1 100644 --- a/src/Pecee/Http/Input/Input.php +++ b/src/Pecee/Http/Input/Input.php @@ -94,8 +94,7 @@ class Input $path = $original[$property]; - $tmp = array_values($index); - foreach ($tmp as $i) { + foreach (array_values($index) as $i) { $path = $path[$i]; } diff --git a/src/Pecee/SimpleRouter/Route/LoadableRoute.php b/src/Pecee/SimpleRouter/Route/LoadableRoute.php index a6a40a5..656cd5c 100644 --- a/src/Pecee/SimpleRouter/Route/LoadableRoute.php +++ b/src/Pecee/SimpleRouter/Route/LoadableRoute.php @@ -45,7 +45,8 @@ abstract class LoadableRoute extends Route implements ILoadableRoute } } - public function matchRegex(Request $request, $url) { + public function matchRegex(Request $request, $url) + { /* Match on custom defined regular expression */ diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index ff62281..0c12af9 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -102,11 +102,11 @@ abstract class Route implements IRoute $urlParts = preg_split('/\{[^}]+\}/is', rtrim($route, '/')); - foreach($urlParts as $key => $t) { + foreach ($urlParts as $key => $t) { $regex = ''; - if($key < (count($parameters[1]))) { + if ($key < (count($parameters[1]))) { $name = $parameters[1][$key]; $regex = isset($this->where[$name]) ? $this->where[$name] : $parameterRegex; @@ -123,12 +123,12 @@ abstract class Route implements IRoute $urlRegex = preg_quote($route, '/'); } - if(preg_match('/^' . $urlRegex . '(\/?)$/is', $url, $matches) > 0) { + if (preg_match('/^' . $urlRegex . '(\/?)$/is', $url, $matches) > 0) { $values = []; /* Only take matched parameters with name */ - foreach($parameters[1] as $name) { + foreach ($parameters[1] as $name) { $values[$name] = $matches[$name]; } @@ -441,9 +441,9 @@ abstract class Route implements IRoute public function getParameters() { /* Sort the parameters after the user-defined param order, if any */ - $parameters = array(); + $parameters = []; - if(count($this->originalParameters) > 0) { + if (count($this->originalParameters) > 0) { $parameters = $this->originalParameters; } @@ -462,7 +462,7 @@ abstract class Route implements IRoute * If this is the first time setting parameters we store them so we * later can organize the array, in case somebody tried to sort the array. */ - if(count($parameters) > 0 && count($this->originalParameters) === 0) { + if (count($parameters) > 0 && count($this->originalParameters) === 0) { $this->originalParameters = $parameters; } diff --git a/src/Pecee/SimpleRouter/Route/RouteController.php b/src/Pecee/SimpleRouter/Route/RouteController.php index 9d520fd..7f12d09 100644 --- a/src/Pecee/SimpleRouter/Route/RouteController.php +++ b/src/Pecee/SimpleRouter/Route/RouteController.php @@ -63,7 +63,7 @@ class RouteController extends LoadableRoute implements IControllerRoute if ($method !== null) { /* Remove requestType from method-name, if it exists */ - foreach(static::$requestTypes as $requestType) { + foreach (static::$requestTypes as $requestType) { if (stripos($method, $requestType) === 0) { $method = substr($method, strlen($requestType)); @@ -89,7 +89,7 @@ class RouteController extends LoadableRoute implements IControllerRoute $url = rtrim($url, '/') . '/'; /* Match global regular-expression for route */ - if($this->matchRegex($request, $url) === true) { + if ($this->matchRegex($request, $url) === true) { return true; } diff --git a/src/Pecee/SimpleRouter/Route/RouteGroup.php b/src/Pecee/SimpleRouter/Route/RouteGroup.php index e24723b..ca5aa04 100644 --- a/src/Pecee/SimpleRouter/Route/RouteGroup.php +++ b/src/Pecee/SimpleRouter/Route/RouteGroup.php @@ -22,13 +22,14 @@ class RouteGroup extends Route implements IGroupRoute return true; } - foreach($this->domains as $domain) { + foreach ($this->domains as $domain) { $parameters = $this->parseParameters($domain, $request->getHost(), '.*'); if ($parameters !== null && count($parameters) > 0) { $this->parameters = $parameters; + return true; } } diff --git a/src/Pecee/SimpleRouter/Route/RouteResource.php b/src/Pecee/SimpleRouter/Route/RouteResource.php index 16e537a..05ba6c0 100644 --- a/src/Pecee/SimpleRouter/Route/RouteResource.php +++ b/src/Pecee/SimpleRouter/Route/RouteResource.php @@ -83,7 +83,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute /* Match global regular-expression for route */ $domainMatch = $this->matchRegex($request, $url); - if($domainMatch !== null) { + if ($domainMatch !== null) { return $domainMatch; } @@ -107,7 +107,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute } // Update - if (isset($this->parameters['id']) && in_array($method, [ static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT ], false)) { + if (isset($this->parameters['id']) && in_array($method, [static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT], false)) { return $this->call($this->methodNames['update']); } diff --git a/src/Pecee/SimpleRouter/Route/RouteUrl.php b/src/Pecee/SimpleRouter/Route/RouteUrl.php index 9cc082f..3b2b985 100644 --- a/src/Pecee/SimpleRouter/Route/RouteUrl.php +++ b/src/Pecee/SimpleRouter/Route/RouteUrl.php @@ -18,13 +18,13 @@ class RouteUrl extends LoadableRoute /* Match global regular-expression for route */ $domainMatch = $this->matchRegex($request, $url); - if($domainMatch !== null) { + if ($domainMatch !== null) { return $domainMatch; } /* Make regular expression based on route */ $parameters = $this->parseParameters($this->url, $url); - if($parameters === null) { + if ($parameters === null) { return false; } From b694a7c0c96d07297f7579b81b1d3171f2f6d5c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 28 Nov 2016 04:39:34 +0100 Subject: [PATCH 6/8] More cleanup --- src/Pecee/Http/Input/Input.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Pecee/Http/Input/Input.php b/src/Pecee/Http/Input/Input.php index a1aa0b1..ae86bca 100644 --- a/src/Pecee/Http/Input/Input.php +++ b/src/Pecee/Http/Input/Input.php @@ -58,10 +58,9 @@ class Input public function parseFiles() { - $files = $_FILES; $list = []; - foreach ($files as $key => $value) { + foreach ($_FILES as $key => $value) { // Handle array input if (is_array($value['name']) === false) { From 5c89ae2aaf62d6a90794b60a19b3ad6fb28644ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 28 Nov 2016 04:45:46 +0100 Subject: [PATCH 7/8] Moved regex/match functionality to LoadableRoute. --- .../SimpleRouter/Route/ILoadableRoute.php | 15 +++++++++++ src/Pecee/SimpleRouter/Route/IRoute.php | 15 ----------- .../SimpleRouter/Route/LoadableRoute.php | 27 ++++++++++++++++++- src/Pecee/SimpleRouter/Route/Route.php | 24 ----------------- 4 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/Pecee/SimpleRouter/Route/ILoadableRoute.php b/src/Pecee/SimpleRouter/Route/ILoadableRoute.php index 92ef82a..4036337 100644 --- a/src/Pecee/SimpleRouter/Route/ILoadableRoute.php +++ b/src/Pecee/SimpleRouter/Route/ILoadableRoute.php @@ -51,4 +51,19 @@ interface ILoadableRoute extends IRoute */ public function setName($name); + /** + * Get regular expression match used for matching route (if defined). + * + * @return string + */ + public function getMatch(); + + /** + * Add regular expression match for the entire route. + * + * @param string $regex + * @return static + */ + public function setMatch($regex); + } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/Route/IRoute.php b/src/Pecee/SimpleRouter/Route/IRoute.php index a8df2da..175cd68 100644 --- a/src/Pecee/SimpleRouter/Route/IRoute.php +++ b/src/Pecee/SimpleRouter/Route/IRoute.php @@ -113,21 +113,6 @@ interface IRoute public function getDefaultNamespace(); - /** - * Get regular expression match used for matching route (if defined). - * - * @return string - */ - public function getMatch(); - - /** - * Add regular expression match for the entire route. - * - * @param string $regex - * @return static - */ - public function setMatch($regex); - /** * Get parameter names. * diff --git a/src/Pecee/SimpleRouter/Route/LoadableRoute.php b/src/Pecee/SimpleRouter/Route/LoadableRoute.php index 656cd5c..39e9d0a 100644 --- a/src/Pecee/SimpleRouter/Route/LoadableRoute.php +++ b/src/Pecee/SimpleRouter/Route/LoadableRoute.php @@ -8,7 +8,7 @@ use Pecee\SimpleRouter\Exceptions\HttpException; abstract class LoadableRoute extends Route implements ILoadableRoute { /** - * @var + * @var string */ protected $url; @@ -17,6 +17,8 @@ abstract class LoadableRoute extends Route implements ILoadableRoute */ protected $name; + protected $regex; + /** * Loads and renders middlewares-classes * @@ -171,6 +173,29 @@ abstract class LoadableRoute extends Route implements ILoadableRoute return (strtolower($this->name) === strtolower($name)); } + /** + * Add regular expression match for the entire route. + * + * @param string $regex + * @return static + */ + public function setMatch($regex) + { + $this->regex = $regex; + + return $this; + } + + /** + * Get regular expression match used for matching route (if defined). + * + * @return string + */ + public function getMatch() + { + return $this->regex; + } + /** * Sets the router name, which makes it easier to obtain the url or router at a later point. * Alias for LoadableRoute::setName(). diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 0c12af9..978a1f5 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -40,7 +40,6 @@ abstract class Route implements IRoute /* Default options */ protected $namespace; - protected $regex; protected $requestMethods = []; protected $where = []; protected $parameters = []; @@ -313,29 +312,6 @@ abstract class Route implements IRoute return ($this->namespace === null) ? $this->defaultNamespace : $this->namespace; } - /** - * Add regular expression match for the entire route. - * - * @param string $regex - * @return static - */ - public function setMatch($regex) - { - $this->regex = $regex; - - return $this; - } - - /** - * Get regular expression match used for matching route (if defined). - * - * @return string - */ - public function getMatch() - { - return $this->regex; - } - /** * Export route settings to array so they can be merged with another route. * From e8f19fbeae90cd1e961fa9824a18134a7692eab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 28 Nov 2016 05:24:12 +0100 Subject: [PATCH 8/8] Simplified `PARAMETERS_REGEX_MATCH` in Route class. --- src/Pecee/SimpleRouter/Route/Route.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 978a1f5..59987e9 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -6,7 +6,7 @@ use Pecee\SimpleRouter\Exceptions\NotFoundHttpException; abstract class Route implements IRoute { - const PARAMETERS_REGEX_MATCH = '%s([\w\-\_]*?)(\%s{0,1})%s'; + const PARAMETERS_REGEX_MATCH = '%s([\w]+)(\%s?)%s'; const REQUEST_TYPE_GET = 'get'; const REQUEST_TYPE_POST = 'post';