Development

- Fixed: namespace being prepended on `RouterController` routes with absolute namespaces.
- Fixed: match domain on `RouteController` and `RouteResource`.
- Fixed: strict url-matching on `RouteController`. Fix should provide better url-matching.
- Fixed: `RouterResource` always matching first url when having simular urls (ex: `/funny-cat` and `/funny-dog`).
- Added `loadRoutes` method to `Router` class so routes now can be loaded without routing the request (useful when running in Cli etc).
- Removed `getInstance` from `Router` class. Please use `SimpleRouter::router()` for singleton usage instead.
- Added `getRemoteAddr` alias-method for `getIp` in `Request` class.
- Added `getValue` to `IInputItem` interface.
- Other minor optimizations.
- Updated documentation with note on absolute/relative namespaces.
This commit is contained in:
Simon Sessingø
2017-02-26 09:18:35 +01:00
parent 2a448fccd2
commit 8c5d8c2dc9
12 changed files with 133 additions and 101 deletions
+2
View File
@@ -12,6 +12,8 @@ interface IInputItem
public function setName($name);
public function getValue();
public function __toString();
}
+7 -2
View File
@@ -43,8 +43,8 @@ class InputFile implements IInputItem
], $values);
return (new static($values['index']))
->setError($values['error'])
->setSize($values['size'])
->setError($values['error'])
->setType($values['type'])
->setTmpName($values['tmp_name'])
->setFilename($values['name']);
@@ -199,7 +199,7 @@ class InputFile implements IInputItem
}
/**
* Return true if an upload error occured.
* Return true if an upload error occurred.
*
* @return bool
*/
@@ -256,6 +256,11 @@ class InputFile implements IInputItem
return $this->getTmpName();
}
public function getValue()
{
return $this->getFilename();
}
public function toArray()
{
return [
+12 -1
View File
@@ -125,6 +125,17 @@ class Request
return $this->getHeader('remote-addr');
}
/**
* Get remote address/ip
*
* @alias static::getIp
* @return string
*/
public function getRemoteAddr()
{
return $this->getIp();
}
/**
* Get referer
* @return string
@@ -240,7 +251,7 @@ class Request
$callback = $route->getCallback();
/* Only add default namespace on relative callbacks */
if($callback === null || $callback[0] !== '\\') {
if ($callback === null || $callback[0] !== '\\') {
$namespace = SimpleRouter::getDefaultNamespace();
@@ -81,7 +81,7 @@ 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)) {
if (preg_match_all('/' . $regex . '/', $this->url, $matches)) {
$this->parameters = array_fill_keys($matches[1], null);
}
}
@@ -145,8 +145,6 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
$url .= join('/', $unknownParams);
return rtrim($url, '/') . '/';
}
+13 -8
View File
@@ -71,7 +71,7 @@ abstract class Route implements IRoute
$namespace = $this->getNamespace();
$className = ($namespace !== null) ? $namespace . '\\' . $controller[0] : $controller[0];
$className = ($namespace !== null && $controller[0][0] !== '\\') ? $namespace . '\\' . $controller[0] : $controller[0];
$class = $this->loadClass($className);
$method = $controller[1];
@@ -98,15 +98,17 @@ abstract class Route implements IRoute
{
$regex = sprintf(static::PARAMETERS_REGEX_MATCH, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]);
if (preg_match_all('/' . $regex . '/is', $route, $parameters)) {
$parameters = [];
$urlParts = preg_split('/((\-?\/?)\{[^}]+\})/is', rtrim($route, '/'));
if (preg_match_all('/' . $regex . '/', $route, $parameters)) {
$urlParts = preg_split('/((\-?\/?)\{[^}]+\})/', rtrim($route, '/'));
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,13 +125,16 @@ abstract class Route implements IRoute
$urlRegex = preg_quote($route, '/');
}
if (preg_match('/^' . $urlRegex . '(\/?)$/is', $url, $matches) > 0) {
if (preg_match('/^' . $urlRegex . '(\/?)$/', $url, $matches) > 0) {
$values = [];
/* Only take matched parameters with name */
foreach ($parameters[1] as $name) {
$values[$name] = (isset($matches[$name]) && $matches[$name] !== '') ? $matches[$name] : null;
if (isset($parameters[1])) {
/* Only take matched parameters with name */
foreach ($parameters[1] as $name) {
$values[$name] = (isset($matches[$name]) && $matches[$name] !== '') ? $matches[$name] : null;
}
}
return $values;
@@ -89,28 +89,26 @@ class RouteController extends LoadableRoute implements IControllerRoute
$url = rtrim($url, '/') . '/';
/* Match global regular-expression for route */
if ($this->matchRegex($request, $url) === true) {
return true;
$regexMatch = $this->matchRegex($request, $url);
if ($regexMatch === false || stripos($url, $this->url) !== 0 || strtolower($url) !== strtolower($this->url)) {
return false;
}
if (stripos($url, $this->url) === 0 && strtolower($url) === strtolower($this->url)) {
$strippedUrl = trim(str_ireplace($this->url, '/', $url), '/');
$path = explode('/', $strippedUrl);
$strippedUrl = trim(str_ireplace($this->url, '/', $url), '/');
if (count($path) > 0) {
$path = explode('/', $strippedUrl);
$method = (isset($path[0]) === false || trim($path[0]) === '') ? $this->defaultMethod : $path[0];
$this->method = $request->getMethod() . ucfirst($method);
if (count($path) > 0) {
$this->parameters = array_slice($path, 1);
$method = (!isset($path[0]) || trim($path[0]) === '') ? $this->defaultMethod : $path[0];
$this->method = $method;
// Set callback
$this->setCallback($this->controller . '@' . $this->method);
$this->parameters = array_slice($path, 1);
// Set callback
$this->setCallback($this->controller . '@' . $this->method);
return true;
}
return true;
}
return false;
@@ -82,9 +82,10 @@ class RouteResource extends LoadableRoute implements IControllerRoute
$url = rtrim($url, '/') . '/';
/* Match global regular-expression for route */
$domainMatch = $this->matchRegex($request, $url);
if ($domainMatch !== null) {
return $domainMatch;
$regexMatch = $this->matchRegex($request, $url);
if ($regexMatch === false || stripos($url, $this->url) !== 0 || strtolower($url) !== strtolower($this->url)) {
return false;
}
$route = rtrim($this->url, '/') . '/{id?}/{action?}';
+3 -4
View File
@@ -17,9 +17,9 @@ class RouteUrl extends LoadableRoute
$url = rtrim($url, '/') . '/';
/* Match global regular-expression for route */
$domainMatch = $this->matchRegex($request, $url);
if ($domainMatch !== null) {
return $domainMatch;
$regexMatch = $this->matchRegex($request, $url);
if ($regexMatch === false) {
return false;
}
/* Make regular expression based on route */
@@ -31,7 +31,6 @@ class RouteUrl extends LoadableRoute
$this->setParameters($parameters);
return true;
}
}
+26 -30
View File
@@ -69,20 +69,7 @@ class Router
*/
protected $exceptionHandlers;
/**
* Get current router instance
* @return static
*/
public static function getInstance()
{
if (static::$instance === null) {
static::$instance = new static();
}
return static::$instance;
}
protected function __construct()
public function __construct()
{
$this->reset();
}
@@ -187,7 +174,7 @@ class Router
if (count($this->routeStack) > 0) {
/* Pop and grap the routes added when executing group callback earlier */
/* Pop and grab the routes added when executing group callback earlier */
$stack = $this->routeStack;
$this->routeStack = [];
@@ -199,6 +186,29 @@ class Router
$this->exceptionHandlers = array_unique(array_merge($exceptionHandlers, $this->exceptionHandlers));
}
/**
* Load routes
* @throws NotFoundHttpException
* @return void
*/
public function loadRoutes()
{
/* Initialize boot-managers */
if (count($this->bootManagers) > 0) {
$max = count($this->bootManagers) - 1;
/* @var $manager IRouterBootManager */
for ($i = $max; $i >= 0; $i--) {
$manager = $this->bootManagers[$i];
$manager->boot($this->request);
}
}
/* Loop through each route-request */
$this->processRoutes($this->routes);
}
public function routeRequest($rewrite = false)
{
$routeNotAllowed = false;
@@ -206,21 +216,7 @@ class Router
try {
if ($rewrite === false) {
/* Initialize boot-managers */
if (count($this->bootManagers) > 0) {
$max = count($this->bootManagers) - 1;
/* @var $manager IRouterBootManager */
for ($i = $max; $i >= 0; $i--) {
$manager = $this->bootManagers[$i];
$manager->boot($this->request);
}
}
/* Loop through each route-request */
$this->processRoutes($this->routes);
$this->loadRoutes();
if ($this->csrfVerifier !== null) {
+8 -2
View File
@@ -33,6 +33,8 @@ class SimpleRouter
*/
protected static $response;
protected static $router;
/**
* Start/route request
*
@@ -349,7 +351,11 @@ class SimpleRouter
*/
public static function router()
{
return Router::getInstance();
if(static::$router === null) {
static::$router = new Router();
}
return static::$router;
}
/**
@@ -365,7 +371,7 @@ class SimpleRouter
$callback = $route->getCallback();
/* Only add default namespace on relative callbacks */
if($callback === null || $callback[0] !== '\\') {
if ($callback === null || $callback[0] !== '\\') {
$namespace = static::$defaultNamespace;