[BUGFIX] Bugfixes

This commit is contained in:
Simon Sessingø
2015-10-07 00:14:59 +02:00
parent 02a874d01c
commit 2ff88f9ed4
5 changed files with 140 additions and 73 deletions
+57 -43
View File
@@ -14,15 +14,18 @@ class RouterBase {
protected $backstack; protected $backstack;
protected $requestUri; protected $requestUri;
protected $requestMethod; protected $requestMethod;
protected $loadedClass; protected $loadedRoute;
protected $defaultNamespace; protected $defaultNamespace;
// TODO: make interface for controller routers, so they can be easily detected
// TODO: clean up - cut some of the methods down to smaller pieces
public function __construct() { public function __construct() {
$this->routes = array(); $this->routes = array();
$this->backstack = array(); $this->backstack = array();
$this->controllerUrlMap = array(); $this->controllerUrlMap = array();
$this->requestUri = $_SERVER['REQUEST_URI']; $this->requestUri = $_SERVER['REQUEST_URI'];
$this->requestMethod = ($_SERVER['REQUEST_METHOD'] != 'GET') ? 'post' : 'get'; $this->requestMethod = (isset($_POST['_method'])) ? strtolower($_POST['_method']) : strtolower($_SERVER['REQUEST_METHOD']);
} }
public function addRoute(RouterEntry $route) { public function addRoute(RouterEntry $route) {
@@ -33,11 +36,11 @@ class RouterBase {
} }
} }
protected function processRoutes(array $routes, array &$settings = array(), array &$prefixes = array(), $match = false, $backstack = false) { protected function processRoutes(array $routes, array $settings = array(), array $prefixes = array(), $backstack = false) {
// Loop through each route-request // Loop through each route-request
/* @var $route RouterEntry */ /* @var $route RouterEntry */
foreach($routes as $i => $route) { foreach($routes as $route) {
if($this->defaultNamespace) { if($this->defaultNamespace) {
$namespace = null; $namespace = null;
@@ -51,54 +54,51 @@ class RouterBase {
$route->setNamespace($namespace); $route->setNamespace($namespace);
} }
$settings = array_merge($settings, $route->getMergeableSettings()); $newPrefixes = $prefixes;
$mergedSettings = array_merge($settings, $route->getMergeableSettings());
if($route->getPrefix()) { if($route->getPrefix()) {
array_push($prefixes, $route->getPrefix()); array_push($newPrefixes, rtrim($route->getPrefix(), '/'));
}
$route->addSettings($mergedSettings);
if(!($route instanceof RouterGroup) && is_array($newPrefixes) && count($newPrefixes) && $backstack) {
$route->setUrl( join('/', $newPrefixes) . $route->getUrl() );
} }
$route->setSettings($settings); $this->controllerUrlMap[] = $route;
if(($route instanceof RouterRoute || $route instanceof RouterController)) {
if(is_array($prefixes) && count($prefixes)) {
$route->setUrl( '/' . join('/', $prefixes) . $route->getUrl() );
}
}
$this->currentRoute = $route; $this->currentRoute = $route;
if($route instanceof RouterGroup && is_callable($route->getCallback())) {
if($route instanceof RouterRoute && !is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) { $route->renderRoute($this->requestMethod);
$this->controllerUrlMap[] = $route;
} else if($route instanceof RouterController) {
$this->controllerUrlMap[] = $route;
}
$routeMatch = $route->matchRoute($this->requestMethod, rtrim($this->requestUri, '/') . '/');
if($routeMatch && $match) {
$this->loadedClass = $routeMatch->renderRoute($this->requestMethod);
} }
$this->currentRoute = null;
if(count($this->backstack)) { if(count($this->backstack)) {
$backstack = $this->backstack;
if($backstack) { $this->backstack = array();
array_shift($this->backstack);
}
// Route any routes added to the backstack // Route any routes added to the backstack
$this->processRoutes($this->backstack, $settings, $prefixes, $match, true); $this->processRoutes($backstack, $mergedSettings, $newPrefixes, true);
} }
} }
} }
public function routeRequest() { public function routeRequest() {
// Loop through each route-request // Loop through each route-request
$settings = array();
$prefixes = array();
$this->processRoutes($this->routes, $settings, $prefixes, true); $this->processRoutes($this->routes);
if(!$this->loadedClass) { foreach($this->controllerUrlMap as $route) {
$routeMatch = $route->matchRoute($this->requestMethod, rtrim($this->requestUri, '/') . '/');
if($routeMatch && !($routeMatch instanceof RouterGroup)) {
$this->loadedRoute = $routeMatch;
$routeMatch->renderRoute($this->requestMethod);
break;
}
}
if(!$this->loadedRoute) {
throw new RouterException(sprintf('Route not found: %s', $this->requestUri), 404); throw new RouterException(sprintf('Route not found: %s', $this->requestUri), 404);
} }
} }
@@ -149,10 +149,7 @@ class RouterBase {
* @return RouterEntry * @return RouterEntry
*/ */
public function getCurrentRoute(){ public function getCurrentRoute(){
if($this->currentRoute !== null && !($this->currentRoute instanceof RouterGroup)) { return $this->currentRoute;
return $this->currentRoute;
}
return null;
} }
/** /**
@@ -169,12 +166,12 @@ class RouterBase {
$url .= $method . '/'; $url .= $method . '/';
} }
if($route instanceof RouterController) { if($route instanceof RouterController || $route instanceof RouterRessource) {
if(count($parameters)) { if(count($parameters)) {
$url .= join('/', $parameters); $url .= join('/', $parameters);
} }
} else { } else {
/* @var $route RouterEntry */
$params = $route->getParameters(); $params = $route->getParameters();
if(count($params)) { if(count($params)) {
$i = 0; $i = 0;
@@ -187,7 +184,7 @@ class RouterBase {
} }
$p = ''; $p = '';
if($getParams !== null) { if($getParams !== null && count($getParams)) {
$p = '?'.Url::arrayToParams($getParams); $p = '?'.Url::arrayToParams($getParams);
} }
@@ -197,6 +194,15 @@ class RouterBase {
} }
public function getRoute($controller = null, $parameters = null, $getParams = null) { public function getRoute($controller = null, $parameters = null, $getParams = null) {
if($parameters !== null && !is_array($parameters)) {
throw new \InvalidArgumentException('Invalid type for parameter. Must be array or null');
}
if($getParams !== null && !is_array($getParams)) {
throw new \InvalidArgumentException('Invalid type for getParams. Must be array or null');
}
$c = ''; $c = '';
$method = null; $method = null;
@@ -205,7 +211,7 @@ class RouterBase {
if($route instanceof RouterRoute && !is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) { if($route instanceof RouterRoute && !is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) {
$c = $route->getCallback(); $c = $route->getCallback();
} else if($route instanceof RouterController) { } else if($route instanceof RouterController || $route instanceof RouterRessource) {
$c = $route->getController(); $c = $route->getController();
} }
@@ -228,7 +234,7 @@ class RouterBase {
$c = $tmp[0]; $c = $tmp[0];
} }
} else if($route instanceof RouterController) { } else if($route instanceof RouterController || $route instanceof RouterRessource) {
$c = $route->getController(); $c = $route->getController();
} }
@@ -243,6 +249,14 @@ class RouterBase {
} }
} }
// Nothing found - return current route
if($this->loadedRoute) {
$getParams = ($getParams === null) ? array() : $getParams;
$params = ($this->loadedRoute->getParameters() == null) ? array() : $this->loadedRoute->getParameters();
$parameters = ($parameters === null) ? array() : $parameters;
return $this->processUrl($this->loadedRoute, null, array_merge($params, $parameters), array_merge($_GET, $getParams));
}
return '/'; return '/';
} }
+1 -17
View File
@@ -8,13 +8,11 @@ class RouterController extends RouterEntry {
protected $url; protected $url;
protected $controller; protected $controller;
protected $method; protected $method;
protected $parameters;
public function __construct($url, $controller) { public function __construct($url, $controller) {
parent::__construct(); parent::__construct();
$this->url = $url; $this->url = $url;
$this->controller = $controller; $this->controller = $controller;
$this->parameters;
} }
public function matchRoute($requestMethod, $url) { public function matchRoute($requestMethod, $url) {
@@ -22,7 +20,7 @@ class RouterController extends RouterEntry {
$url = parse_url($url); $url = parse_url($url);
$url = $url['path']; $url = $url['path'];
if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url) !== false) { if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url) === 0) {
$strippedUrl = trim(str_ireplace($this->url, '/', $url), '/'); $strippedUrl = trim(str_ireplace($this->url, '/', $url), '/');
@@ -60,20 +58,6 @@ class RouterController extends RouterEntry {
$this->url = $url; $this->url = $url;
} }
/**
* @return array
*/
public function getParameters() {
return $this->parameters;
}
/**
* @param array $parameters
*/
public function setParameters($parameters) {
$this->parameters = $parameters;
}
/** /**
* @return string * @return string
*/ */
+15 -1
View File
@@ -70,7 +70,7 @@ abstract class RouterEntry {
* @return self * @return self
*/ */
public function setPrefix($prefix) { public function setPrefix($prefix) {
$this->prefix = trim($prefix, '/'); $this->prefix = '/' . trim($prefix, '/') . '/';
return $this; return $this;
} }
@@ -139,12 +139,26 @@ abstract class RouterEntry {
return $settings; return $settings;
} }
/**
* @param array $settings
* @return self
*/
public function addSettings(array $settings) {
array_merge($this->settings, $settings);
return $this;
}
/** /**
* @param array $settings * @param array $settings
* @return self * @return self
*/ */
public function setSettings($settings) { public function setSettings($settings) {
$this->settings = $settings; $this->settings = $settings;
if($settings['prefix']) {
$this->setPrefix($settings['prefix']);
}
return $this; return $this;
} }
+16 -1
View File
@@ -11,7 +11,22 @@ class RouterGroup extends RouterEntry {
public function matchRoute($requestMethod, $url) { public function matchRoute($requestMethod, $url) {
// Check if request method is allowed // Check if request method is allowed
if(count($this->method) === 0 || strtolower($this->method) == strtolower($requestMethod) || is_array($this->method) && in_array($this->method, self::$allowedRequestTypes)) { if(strtolower($url) == strtolower($this->prefix) || stripos($url, $this->prefix) === 0) {
$hasAccess = (!$this->method);
if($this->method) {
if(is_array($this->method)) {
$hasAccess = (in_array($requestMethod, $this->method));
} else {
$hasAccess = strtolower($this->method) == strtolower($requestMethod);
}
}
if(!$hasAccess) {
throw new RouterException('Method not allowed');
}
return $this; return $this;
} }
+51 -11
View File
@@ -8,15 +8,13 @@ class RouterRessource extends RouterEntry {
protected $url; protected $url;
protected $controller; protected $controller;
protected $method; protected $method;
protected $parameters;
protected $postMethod; protected $postMethod;
public function __construct($url, $controller) { public function __construct($url, $controller) {
parent::__construct(); parent::__construct();
$this->url = $url; $this->url = $url;
$this->controller = $controller; $this->controller = $controller;
$this->parameters; $this->postMethod = strtolower(($_SERVER['REQUEST_METHOD'] != 'GET') ? 'post' : 'get');
$this->postMethod = strtoupper(isset($_POST['_method']) ? $_POST['_method'] : $_SERVER['REQUEST_METHOD']);
} }
public function renderRoute($requestMethod) { public function renderRoute($requestMethod) {
@@ -26,7 +24,6 @@ class RouterRessource extends RouterEntry {
} }
if(is_object($this->getCallback()) && is_callable($this->getCallback())) { if(is_object($this->getCallback()) && is_callable($this->getCallback())) {
// When the callback is a function // When the callback is a function
call_user_func_array($this->getCallback(), $this->getParameters()); call_user_func_array($this->getCallback(), $this->getParameters());
} else { } else {
@@ -58,7 +55,7 @@ class RouterRessource extends RouterEntry {
$url = parse_url($url); $url = parse_url($url);
$url = $url['path']; $url = $url['path'];
if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url) !== false) { if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url . '/') === 0) {
$url = rtrim($url, '/'); $url = rtrim($url, '/');
$strippedUrl = trim(substr($url, strlen($this->url)), '/'); $strippedUrl = trim(substr($url, strlen($this->url)), '/');
@@ -75,32 +72,32 @@ class RouterRessource extends RouterEntry {
if (count($path)) { if (count($path)) {
// Delete // Delete
if($this->postMethod === 'DELETE' && $requestMethod === self::REQUEST_TYPE_POST) { if($requestMethod === self::REQUEST_TYPE_DELETE && $this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('destroy', $args); return $this->call('destroy', $args);
} }
// Update // Update
if(in_array($this->postMethod, array('PUT', 'PATCH')) && $requestMethod === self::REQUEST_TYPE_POST) { if(in_array($requestMethod, array('put', 'patch')) && $this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('update', array_merge(array($action), $args)); return $this->call('update', array_merge(array($action), $args));
} }
// Edit // Edit
if(isset($args[0]) && strtolower($args[0]) === 'edit' && $requestMethod === self::REQUEST_TYPE_GET) { if(isset($args[0]) && strtolower($args[0]) === 'edit' && $this->postMethod === self::REQUEST_TYPE_GET) {
return $this->call('edit', array_merge(array($action), array_slice($args, 1))); return $this->call('edit', array_merge(array($action), array_slice($args, 1)));
} }
// Create // Create
if(strtolower($action) === 'create' && $this->postMethod === 'GET') { if(strtolower($action) === 'create' && $requestMethod === self::REQUEST_TYPE_GET) {
return $this->call('create', $args); return $this->call('create', $args);
} }
// Save // Save
if($requestMethod === self::REQUEST_TYPE_POST) { if($this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('store', $args); return $this->call('store', $args);
} }
// Show // Show
if($action && $requestMethod === self::REQUEST_TYPE_GET) { if($action && $this->postMethod === self::REQUEST_TYPE_GET) {
return $this->call('show', array_merge(array($action), $args)); return $this->call('show', array_merge(array($action), $args));
} }
@@ -112,4 +109,47 @@ class RouterRessource extends RouterEntry {
return null; return null;
} }
/**
* @return string
*/
public function getUrl() {
return $this->url;
}
/**
* @param string $url
*/
public function setUrl($url) {
$url = rtrim($url, '/') . '/';
$this->url = $url;
}
/**
* @return string
*/
public function getController() {
return $this->controller;
}
/**
* @param string $controller
*/
public function setController($controller) {
$this->controller = $controller;
}
/**
* @return string
*/
public function getMethod() {
return $this->method;
}
/**
* @param string $method
*/
public function setMethod($method) {
$this->method = $method;
}
} }