Compare commits

...

32 Commits

Author SHA1 Message Date
Simon Sessingø 9304b9f866 Merge pull request #54 from skipperbent/development
Development
2015-12-19 16:28:17 +01:00
Simon Sessingø ed886cb7b3 Merge pull request #53 from skipperbent/feature-resource
[FEATURE] ResourceControllers now support nested ressources
2015-12-19 16:28:06 +01:00
Simon Sessingø cbaa0bcaac [FEATURE] getRoute now support domains.
- Optimisations + bugfixes.
2015-12-19 09:21:12 +01:00
Simon Sessingø 98b1759967 [TASK] Updated documentation. 2015-12-19 07:19:49 +01:00
Simon Sessingø b9be7695a7 [TASK] Fixed parameter matching regex when using multiple optional parameters. 2015-12-19 07:15:32 +01:00
Simon Sessingø 97e2edd207 [FEATURE] ResourceControllers now support nested ressources 2015-12-17 14:39:47 +01:00
Simon Sessingø 87fbbcbba2 Merge pull request #52 from skipperbent/development
[TASK] Csrf-token fixes + readded BaseCsrfVerifier.
2015-12-14 13:40:19 +01:00
Simon Sessingø 5a501db767 [TASK] Csrf-token fixes + readded BaseCsrfVerifier.
- Readded BaseCsrfVerifier middleware.
- Csrf-token expire time is now updated on each page refresh.
- CSRF-token update now happens after the route has been loaded, to ensure
  no faulty "Invalid csrf-token" exceptions.
2015-12-14 13:36:38 +01:00
Simon Sessingø 669bfa0a86 Merge pull request #51 from skipperbent/development
Latest development
2015-12-13 03:07:20 +01:00
Simon Sessingø 4f07f38cf5 [BUGFIX] Fixed getting current route not always returning current url. 2015-12-12 23:38:48 +01:00
Simon Sessingø c67ab20ddd [BUGFIX] Merge current parameters with new provided ones. 2015-12-12 22:53:25 +01:00
Simon Sessingø ad1ce21c66 [BUGFIX] Fixed getParams not being passed when using getRoute on current
route.
2015-12-12 20:42:06 +01:00
Simon Sessingø 5a19d6339c Merge pull request #50 from skipperbent/development
Development
2015-12-11 18:23:53 +01:00
Simon Sessingø 23ee53060e Merge branch 'development' of https://github.com/skipperbent/simple-php-router into development
Conflicts:
	src/Pecee/SimpleRouter/RouterBase.php
2015-12-11 18:23:19 +01:00
Simon Sessingø 77ba9f165e [BUGFIX] Fixed get params warning. 2015-12-11 18:21:00 +01:00
Simon Sessingø 4dd6417f71 Merge pull request #49 from skipperbent/development
Development
2015-12-11 18:11:03 +01:00
Simon Sessingø 3012435caa Merge pull request #48 from skipperbent/feature-optimisations
[OPTIMISATION] Optimisations + bugfixes.
2015-12-11 18:10:53 +01:00
Simon Sessingø 0bec524606 [OPTIMISATION] Optimisations + bugfixes.
- Fixed references to Pecee framework.
- Fixed variables not being initialised before usage.
- Cleaned up duplicate checks.
- Other small optimisations and bugfixes.
2015-12-11 18:06:52 +01:00
Simon Sessingø d4e9ef7744 Merge pull request #47 from skipperbent/development
[BUGFIX] Fixed error with RouterGroup.
2015-12-10 21:23:05 +01:00
Simon Sessingø cede827a45 [BUGFIX] Fixed error with RouterGroup. 2015-12-10 21:22:14 +01:00
Simon Sessingø 9da90d1435 Merge pull request #46 from skipperbent/development
Development
2015-12-10 20:05:49 +01:00
Simon Sessingø 4d70efcc4d Merge branch 'development' of https://github.com/skipperbent/simple-php-router into development 2015-12-10 19:56:12 +01:00
Simon Sessingø e1c549bfdb [OPTIMISATION] Added missing return statement 2015-12-10 19:55:48 +01:00
Simon Sessingø b9f426989b Merge pull request #45 from skipperbent/development
Development
2015-12-10 04:44:03 +01:00
Simon Sessingø f1f5faa81e Merge pull request #44 from skipperbent/master
...
2015-12-10 04:43:48 +01:00
Simon Sessingø 6c56947792 [FEATURE] Added support for domains array on group.
- Group will not render if one or more domain does not match.
2015-12-10 04:42:50 +01:00
Simon Sessingø 925b9761f4 Merge pull request #43 from skipperbent/development
[FEATURE] Subdomain-routing + Improvements
2015-12-10 04:14:58 +01:00
Simon Sessingø 59956d5fca [BUGFIX] Optimisations + bugfixes. 2015-12-10 04:12:44 +01:00
Simon Sessingø 3ba2cec8af [OPTIMISATION] Optimised more foreach loops to improve performance. 2015-12-10 03:41:10 +01:00
Simon Sessingø d36880e9a0 [OPTIMISATION] Optimised routes loop. 2015-12-10 03:36:50 +01:00
Simon Sessingø c74d83796f [FEATURE] Added sub-domain routing.
- Updated documentation.
2015-12-10 03:31:57 +01:00
Simon Sessingø 2128a24f1c [FEATURE] Added support for domain regex matching.
- Also improved regex matching when using custom regular expressions.
2015-12-10 01:34:35 +01:00
10 changed files with 324 additions and 201 deletions
+24 -7
View File
@@ -1,8 +1,8 @@
# Simple PHP router
Simple, fast and yet powerful PHP router that is easy to get integrated and in any project. Heavily inspired by the Laravel router.
Simple, fast and yet powerful PHP router that is easy to get integrated and in any project. Heavily inspired by the way Laravel handles routing.
## Installation
Add the latest version pf Simple PHP Router to your ```composer.json```
Add the latest version of Simple PHP Router to your ```composer.json```
```json
{
@@ -17,6 +17,8 @@ Add the latest version pf Simple PHP Router to your ```composer.json```
## Notes
The goal of this project is to create a router that is 100% compatible with the Laravel documentation, but as simple as possible and as easy to integrate and change as possible.
### Features
- Basic routing (get, post, put, delete) with support for custom multiple verbs.
@@ -29,11 +31,11 @@ Add the latest version pf Simple PHP Router to your ```composer.json```
- Route prefixes.
- CSRF protection.
- Optional parameters
- Sub-domain routing
### Features currently "in-the-works"
- Global Constraints
- Sub-domain routing
## Initialising the router
@@ -81,9 +83,9 @@ SimpleRouter::group(['prefix' => 'v1', 'middleware' => '\MyWebsite\Middleware\So
/**
* This example will route url when matching the regular expression to the method.
* For example route: /ajax/music/world -> ControllerAjax@process (parameter: music/world)
* For example route: domain.com/ajax/music/world -> ControllerAjax@process (parameter: music/world)
*/
SimpleRouter::all('/ajax', 'ControllerAjax@process')->match('ajax\\/([A-Za-z0-9\\/]+)');
SimpleRouter::all('/ajax', 'ControllerAjax@process')->match('.*?\\/ajax\\/([A-Za-z0-9\\/]+)');
// Restful resource
SimpleRouter::resource('/rest', 'ControllerRessource');
@@ -100,6 +102,20 @@ SimpleRouter::group(['prefix' => 'v1', 'middleware' => '\MyWebsite\Middleware\So
});
```
### Sub-domain routing
Route groups may also be used to route wildcard sub-domains. Sub-domains may be assigned route parameters just like route URIs, allowing you to capture a portion of the sub-domain for usage in your route or controller. The sub-domain may be specified using the ```domain``` key on the group attribute array:
```php
Route::group(['domain' => '{account}.myapp.com'], function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
```
The prefix group array attribute may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with admin:
### Doing it the object oriented (hardcore) way
The ```SimpleRouter``` class referenced in the previous example, is just a simple helper class that knows how to communicate with the ```RouterBase``` class.
@@ -187,7 +203,8 @@ class Router extends SimpleRouter {
}
```
This is a basic example of a helper function for generating urls.
#### Helper functions examples
**This is a basic example of a helper function for generating urls.**
```php
use Pecee\SimpleRouter\RouterBase;
@@ -196,7 +213,7 @@ function url($controller, $parameters = null, $getParams = null) {
}
```
This is a basic example for getting the current csrf token
**This is a basic example for getting the current csrf token**
```php
/**
+9 -7
View File
@@ -7,12 +7,6 @@ class CsrfToken {
protected $token;
public function __construct() {
if($this->getToken() === null) {
$this->setToken($this->generateToken());
}
}
/**
* Generate random identifier for CSRF token
* @return string
@@ -51,10 +45,18 @@ class CsrfToken {
* @return string|null
*/
public function getToken(){
if(isset($_COOKIE[self::CSRF_KEY])) {
if($this->hasToken()) {
return $_COOKIE[self::CSRF_KEY];
}
return null;
}
/**
* Returns whether the csrf token has been defined
* @return bool
*/
public function hasToken() {
return isset($_COOKIE[self::CSRF_KEY]);
}
}
+1 -1
View File
@@ -26,7 +26,7 @@ class Response {
}
public function refresh() {
$this->redirect(url());
$this->redirect(Request::getInstance()->getUri());
}
/**
+109 -43
View File
@@ -1,10 +1,9 @@
<?php
namespace Pecee\SimpleRouter;
use Pecee\ArrayUtil;
use Pecee\CsrfToken;
use Pecee\Http\Middleware\BaseCsrfVerifier;
use Pecee\Http\Request;
use Pecee\Url;
class RouterBase {
@@ -15,7 +14,7 @@ class RouterBase {
protected $routes;
protected $processedRoutes;
protected $controllerUrlMap;
protected $backstack;
protected $backStack;
protected $loadedRoute;
protected $defaultNamespace;
protected $baseCsrfVerifier;
@@ -25,27 +24,36 @@ class RouterBase {
public function __construct() {
$this->routes = array();
$this->backstack = array();
$this->backStack = array();
$this->controllerUrlMap = array();
$this->baseCsrfVerifier = new BaseCsrfVerifier();
$this->request = Request::getInstance();
$csrf = new CsrfToken();
$token = ($csrf->hasToken()) ? $csrf->getToken() : $csrf->generateToken();
$csrf->setToken($token);
}
public function addRoute(RouterEntry $route) {
if($this->currentRoute !== null) {
$this->backstack[] = $route;
$this->backStack[] = $route;
} else {
$this->routes[] = $route;
}
}
protected function processRoutes(array $routes, array $settings = array(), array $prefixes = array(), $backstack = false, $group = null) {
protected function processRoutes(array $routes, array $settings = array(), array $prefixes = array(), $backStack = false, $group = null) {
// Loop through each route-request
$activeGroup = null;
$routesCount = count($routes);
$mergedSettings = array();
/* @var $route RouterEntry */
foreach($routes as $route) {
for($i = 0; $i < $routesCount; $i++) {
$route = $routes[$i];
$route->addSettings($settings);
$route->setGroup($group);
if($this->defaultNamespace && !$route->getNamespace()) {
@@ -60,34 +68,36 @@ class RouterBase {
}
$newPrefixes = $prefixes;
$mergedSettings = array_merge($settings, $route->getMergeableSettings());
if($route->getPrefix()) {
array_push($newPrefixes, rtrim($route->getPrefix(), '/'));
}
$route->addSettings($mergedSettings);
if(!($route instanceof RouterGroup)) {
if(is_array($newPrefixes) && count($newPrefixes) && $backstack) {
if(is_array($newPrefixes) && count($newPrefixes) && $backStack) {
$route->setUrl( join('/', $newPrefixes) . $route->getUrl() );
}
$group = null;
$this->controllerUrlMap[] = $route;
}
$this->currentRoute = $route;
if($route instanceof RouterGroup && is_callable($route->getCallback())) {
$group = $route;
$route->renderRoute($this->request);
$activeGroup = $route;
$mergedSettings = array_merge($route->getMergeableSettings(), $settings);
}
$this->currentRoute = null;
if(count($this->backstack)) {
$backstack = $this->backstack;
$this->backstack = array();
if(count($this->backStack)) {
$backStack = $this->backStack;
$this->backStack = array();
// Route any routes added to the backstack
$this->processRoutes($backstack, $mergedSettings, $newPrefixes, true, $activeGroup);
$this->processRoutes($backStack, $mergedSettings, $newPrefixes, true, $group);
}
}
}
@@ -107,11 +117,16 @@ class RouterBase {
$routeNotAllowed = false;
$max = count($this->controllerUrlMap);
/* @var $route RouterEntry */
foreach($this->controllerUrlMap as $route) {
for($i = 0; $i < $max; $i++) {
$route = $this->controllerUrlMap[$i];
$routeMatch = $route->matchRoute($this->request);
if($routeMatch && !($routeMatch instanceof RouterGroup)) {
if($routeMatch) {
if(count($route->getRequestMethods()) && !in_array($this->request->getMethod(), $route->getRequestMethods())) {
$routeNotAllowed = true;
@@ -120,9 +135,9 @@ class RouterBase {
$routeNotAllowed = false;
$this->loadedRoute = $routeMatch;
$routeMatch->loadMiddleware($this->request);
$routeMatch->renderRoute($this->request);
$this->loadedRoute = $route;
$route->loadMiddleware($this->request);
$route->renderRoute($this->request);
break;
}
}
@@ -164,7 +179,7 @@ class RouterBase {
* @return array
*/
public function getBackstack() {
return $this->backstack;
return $this->backStack;
}
/**
@@ -209,9 +224,34 @@ class RouterBase {
return $this;
}
public function arrayToParams(array $getParams = null, $includeEmpty = true) {
if (is_array($getParams) && count($getParams) > 0) {
foreach ($getParams as $key => $val) {
if (!empty($val) || empty($val) && $includeEmpty) {
$getParams[$key] = $key . '=' . $val;
}
}
return join('&', $getParams);
}
return '';
}
protected function processUrl($route, $method = null, $parameters = null, $getParams = null) {
$url = '/' . trim($route->getUrl(), '/');
$domain = '';
if($route->getGroup() !== null && $route->getGroup()->getDomain() !== null) {
if(is_array($route->getGroup()->getDomain())) {
$domains = $route->getGroup()->getDomain();
$domain = array_shift($domains);
} else {
$domain = $route->getGroup()->getDomain();
}
$domain = '//' . $domain;
}
$url = $domain . '/' . trim($route->getUrl(), '/');
if(($route instanceof RouterController || $route instanceof RouterResource) && $method !== null) {
$url .= $method;
@@ -223,26 +263,32 @@ class RouterBase {
}
} else {
/* @var $route RouterEntry */
$params = $route->getParameters();
if(count($params)) {
$i = 0;
foreach($params as $param => $value) {
$value = (isset($parameters[$param])) ? $parameters[$param] : $value;
$url = str_ireplace(array('{' . $param. '}', '{' . $param. '?}'), $value, $url);
$i++;
}
if(is_array($parameters)) {
$params = array_merge($route->getParameters(), $parameters);
} else {
// If no parameters are specified in the route, assume that the provided parameters should be used.
if(count($parameters)) {
$url = rtrim($url, '/') . '/' . join('/', $parameters);
}
$params = $route->getParameters();
}
$otherParams = [];
$i = 0;
foreach($params as $param => $value) {
$value = (isset($parameters[$param])) ? $parameters[$param] : $value;
if(stripos($url, '{' . $param. '}') !== false || stripos($url, '{' . $param . '?}') !== false) {
$url = str_ireplace(array('{' . $param . '}', '{' . $param . '?}'), $value, $url);
} else {
$otherParams[$param] = $value;
}
$i++;
}
$url = rtrim($url, '/') . '/' . join('/', $otherParams);
}
$url = rtrim($url, '/') . '/';
if($getParams !== null && count($getParams)) {
$url .= '?'.Url::arrayToParams($getParams);
$url .= '?' . $this->arrayToParams($getParams);
}
return $url;
@@ -258,15 +304,29 @@ class RouterBase {
throw new \InvalidArgumentException('Invalid type for getParams. Must be array or null');
}
if($controller === null && $parameters === null && $this->loadedRoute !== null) {
return $this->processUrl($this->loadedRoute, null, $getParams);
// Return current route if no options has been specified
if($controller === null && $parameters === null) {
$getParams = (is_array($getParams)) ? array_merge($_GET, $getParams) : $_GET;
$url = parse_url(Request::getInstance()->getUri());
$url = $url['path'];
if(count($getParams)) {
$url .= '?' . $this->arrayToParams($getParams);
}
return $url;
}
$c = '';
$method = null;
$max = count($this->controllerUrlMap);
/* @var $route RouterRoute */
foreach($this->controllerUrlMap as $route) {
for($i = 0; $i < $max; $i++) {
$route = $this->controllerUrlMap[$i];
// Check an alias exist, if the matches - use it
if($route instanceof RouterRoute && strtolower($route->getAlias()) === strtolower($controller)) {
@@ -287,7 +347,10 @@ class RouterBase {
$c = '';
// No match has yet been found, let's try to guess what url that should be returned
foreach($this->controllerUrlMap as $route) {
for($i = 0; $i < $max; $i++) {
$route = $this->controllerUrlMap[$i];
if($route instanceof RouterRoute && !is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) {
$c = $route->getClass();
} else if($route instanceof RouterController || $route instanceof RouterResource) {
@@ -309,13 +372,16 @@ class RouterBase {
$url = array($controller);
if(is_array($parameters)) {
ArrayUtil::append($url, $parameters);
foreach($parameters as $key => $value) {
array_push($url,$value);
}
}
$url = '/' . trim(join('/', $url), '/') . '/';
if(is_array($getParams)) {
$url .= '?' . Url::arrayToParams($getParams);
if($getParams !== null && count($getParams)) {
$url .= '?' . $this->arrayToParams($getParams);
}
return $url;
+3 -1
View File
@@ -38,6 +38,8 @@ class RouterController extends RouterEntry {
return $class;
}
return null;
}
public function matchRoute(Request $request) {
@@ -61,7 +63,7 @@ class RouterController extends RouterEntry {
// Set callback
$this->setCallback($this->controller . '@' . $this->method);
return $this;
return true;
}
}
return null;
+86 -6
View File
@@ -23,13 +23,12 @@ abstract class RouterEntry {
protected $settings;
protected $callback;
protected $parameters;
public function __construct() {
$this->settings = array();
$this->settings['requestMethods'] = array();
$this->settings['parametersRegex'] = array();
$this->parameters = array();
$this->settings['parameters'] = array();
}
/**
@@ -137,7 +136,7 @@ abstract class RouterEntry {
* @return mixed
*/
public function getParameters(){
return $this->parameters;
return ($this->parameters === null) ? array() : $this->parameters;
}
/**
@@ -216,7 +215,7 @@ abstract class RouterEntry {
}
/**
* Dynamicially access settings value
* Dynamically access settings value
*
* @param $name
* @return mixed|null
@@ -243,6 +242,87 @@ abstract class RouterEntry {
return new $name();
}
protected function parseParameters($route, $url, $parameterRegex = '[a-z0-9]*?') {
$parameterNames = array();
$regex = '';
$lastCharacter = '';
$isParameter = false;
$parameter = '';
// Use custom parameter regex if it exists
if(is_array($this->parametersRegex) && isset($this->parametersRegex[$parameter])) {
$parameterRegex = $this->parametersRegex[$parameter];
}
$routeLength = strlen($route);
for($i = 0; $i < $routeLength; $i++) {
$character = $route[$i];
// Skip "/" if we are at the end of a parameter
if($lastCharacter === '}' && $character === '/') {
$lastCharacter = $character;
continue;
}
if($character === '{') {
// Remove "/" and "\" from regex
if(substr($regex, strlen($regex)-1) === '/') {
$regex = substr($regex, 0, strlen($regex) - 2);
}
$isParameter = true;
} elseif($isParameter && $character === '}') {
$required = true;
// Check for optional parameter
if($lastCharacter === '?') {
$parameter = substr($parameter, 0, strlen($parameter)-1);
$regex .= '(?:(?:\/{0,1}(?P<'.$parameter.'>[^\/]*)))\\/{0,1}';
$required = false;
} else {
$regex .= '(?:\\/{0,1}(?P<' . $parameter . '>'. $parameterRegex .')\\/{0,1})';
}
$parameterNames[] = array('name' => $parameter, 'required' => $required);
$parameter = '';
$isParameter = false;
} elseif($isParameter) {
$parameter .= $character;
} elseif($character === '/') {
$regex .= '\\' . $character;
} else {
$regex .= str_replace('.', '\\.', $character);
}
$lastCharacter = $character;
}
$parameterValues = array();
if(preg_match('/^'.$regex.'$/is', $url, $parameterValues)) {
$parameters = array();
$max = count($parameterNames);
if($max) {
for($i = 0; $i < $max; $i++) {
$name = $parameterNames[$i];
$parameterValue = (isset($parameterValues[$name['name']]) && !empty($parameterValues[$name['name']])) ? $parameterValues[$name['name']] : null;
if($name['required'] && $parameterValue === null) {
throw new RouterException('Missing required parameter ' . $name['name'], 404);
}
$parameters[$name['name']] = $parameterValue;
}
}
return $parameters;
}
return null;
}
public function loadMiddleware(Request $request) {
if($this->getMiddleware()) {
if(is_array($this->getMiddleware())) {
@@ -252,7 +332,7 @@ abstract class RouterEntry {
throw new RouterException($middleware . ' must be instance of Middleware');
}
/* @var $class Middleware */
/* @var $class IMiddleware */
$middleware->handle($request);
}
} else {
@@ -261,7 +341,7 @@ abstract class RouterEntry {
throw new RouterException($this->getMiddleware() . ' must be instance of Middleware');
}
/* @var $class Middleware */
/* @var $class IMiddleware */
$middleware->handle($request);
}
}
+40
View File
@@ -10,6 +10,40 @@ class RouterGroup extends RouterEntry {
parent::__construct();
}
protected function matchDomain(Request $request) {
if($this->domain !== null) {
if(is_array($this->domain)) {
$max = count($this->domain);
for($i = 0; $i < $max; $i++) {
$domain = $this->domain[$i];
$parameters = $this->parseParameters($domain, $request->getHost(), '[^.]*');
if($parameters !== null) {
$this->parameters = $parameters;
return true;
}
}
return null;
}
$parameters = $this->parseParameters($this->domain, $request->getHost(), '[^.]*');
if ($parameters !== null) {
$this->parameters = $parameters;
return true;
}
return null;
}
return false;
}
public function renderRoute(Request $request) {
// Check if request method is allowed
$hasAccess = (!$this->method);
@@ -26,6 +60,8 @@ class RouterGroup extends RouterEntry {
throw new RouterException('Method not allowed');
}
$this->matchDomain($request);
return parent::renderRoute($request);
}
@@ -42,4 +78,8 @@ class RouterGroup extends RouterEntry {
return $this->exceptionHandler;
}
public function getDomain() {
return $this->domain;
}
}
+39 -60
View File
@@ -5,11 +5,8 @@ use Pecee\Http\Request;
class RouterResource extends RouterEntry {
const DEFAULT_METHOD = 'index';
protected $url;
protected $controller;
protected $method;
protected $postMethod;
public function __construct($url, $controller) {
@@ -45,62 +42,58 @@ class RouterResource extends RouterEntry {
protected function call($method, $parameters) {
$this->setCallback($this->controller . '@' . $method);
$this->parameters = $parameters;
return $this;
return true;
}
public function matchRoute(Request $request) {
$url = parse_url($request->getUri());
$url = rtrim($url['path'], '/') . '/';
if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url) === 0) {
$url = rtrim($url, '/');
$route = rtrim($this->url, '/') . '/{id?}/{action?}';
$strippedUrl = trim(substr($url, strlen($this->url)), '/');
$path = explode('/', $strippedUrl);
$parameters = $this->parseParameters($route, $url, '[0-9]*?');
$args = $path;
$action = '';
if($parameters !== null) {
if(count($args)) {
$action = $args[0];
array_shift($args);
if(is_array($parameters)) {
$parameters = array_merge($this->parameters, $parameters);
}
if (count($path)) {
$action = $parameters['action'];
unset($parameters['action']);
// Delete
if($request->getMethod() === self::REQUEST_TYPE_DELETE && $this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('destroy', $args);
}
// Update
if(in_array($request->getMethod(), array('put', 'patch')) && $this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('update', array_merge(array($action), $args));
}
// Edit
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)));
}
// Create
if(strtolower($action) === 'create' && $request->getMethod() === self::REQUEST_TYPE_GET) {
return $this->call('create', $args);
}
// Save
if($this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('store', $args);
}
// Show
if($action && $this->postMethod === self::REQUEST_TYPE_GET) {
return $this->call('show', array_merge(array($action), $args));
}
// Index
return $this->call('index', $args);
// Delete
if($request->getMethod() === self::REQUEST_TYPE_DELETE && $this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('destroy', $parameters);
}
// Update
if(in_array($request->getMethod(), array(self::REQUEST_TYPE_PATCH, self::REQUEST_TYPE_PUT)) && $this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('update', $parameters);
}
// Edit
if(isset($action) && strtolower($action) === 'edit' && $this->postMethod === self::REQUEST_TYPE_GET) {
return $this->call('edit', $parameters);
}
// Create
if(strtolower($action) === 'create' && $request->getMethod() === self::REQUEST_TYPE_GET) {
return $this->call('create', $parameters);
}
// Save
if($this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('store', $parameters);
}
// Show
if($action && $this->postMethod === self::REQUEST_TYPE_GET) {
return $this->call('show', $parameters);
}
// Index
return $this->call('index', $parameters);
}
return null;
@@ -135,18 +128,4 @@ class RouterResource extends RouterEntry {
$this->controller = $controller;
}
/**
* @return string
*/
public function getMethod() {
return $this->method;
}
/**
* @param string $method
*/
public function setMethod($method) {
$this->method = $method;
}
}
+12 -75
View File
@@ -26,91 +26,27 @@ class RouterRoute extends RouterEntry {
// Match on custom defined regular expression
if($this->regexMatch) {
$parameters = array();
if(preg_match('/('.$this->regexMatch.')/is', $url, $parameters)) {
if(preg_match('/('.$this->regexMatch.')/is', $request->getHost() . $url, $parameters)) {
$this->parameters = (!is_array($parameters[0]) ? array($parameters[0]) : $parameters[0]);
return $this;
return true;
}
return null;
}
// Make regular expression based on route
$route = rtrim($this->url, '/') . '/';
$parameterNames = array();
$regex = '';
$lastCharacter = '';
$isParameter = false;
$parameter = '';
$parameters = $this->parseParameters($route, $url);
for($i = 0; $i < strlen($route); $i++) {
if($parameters !== null) {
$character = $route[$i];
// Skip "/" if we are at the end of a parameter
if($lastCharacter === '}' && $character === '/') {
$lastCharacter = $character;
continue;
}
if($character === '{') {
// Remove "/" and "\" from regex
if(substr($regex, strlen($regex)-1) === '/') {
$regex = substr($regex, 0, strlen($regex) - 2);
}
$isParameter = true;
} elseif($isParameter && $character === '}') {
$required = true;
// Check for optional parameter
if($lastCharacter === '?') {
$parameter = substr($parameter, 0, strlen($parameter)-1);
$regex .= '(?:(?:\/{0,1}(?P<'.$parameter.'>[a-z0-9]*?)){0,1}\\/)';
$required = false;
} else {
// Use custom parameter regex if it exists
$parameterRegex = '[a-z0-9]*?';
if(is_array($this->parametersRegex) && isset($this->parametersRegex[$parameter])) {
$parameterRegex = $this->parametersRegex[$parameter];
}
$regex .= '(?:\\/{0,1}(?P<' . $parameter . '>'. $parameterRegex .')\\/)';
}
$parameterNames[] = array('name' => $parameter, 'required' => $required);
$parameter = '';
$isParameter = false;
} elseif($isParameter) {
$parameter .= $character;
} elseif($character === '/') {
$regex .= '\\' . $character;
if(is_array($this->parameters)) {
$this->parameters = array_merge($this->parameters, $parameters);
} else {
$regex .= $character;
$this->parameters = $parameters;
}
$lastCharacter = $character;
}
$parameterValues = array();
if(preg_match('/^'.$regex.'$/is', $url, $parameterValues)) {
$parameters = array();
if(count($parameterNames)) {
foreach($parameterNames as $name) {
$parameterValue = (isset($parameterValues[$name['name']]) && !empty($parameterValues[$name['name']])) ? $parameterValues[$name['name']] : null;
if($name['required'] && $parameterValue === null) {
throw new RouterException('Missing required parameter ' . $name['name'], 404);
}
$parameters[$name['name']] = $parameterValue;
}
}
$this->parameters = $parameters;
return $this;
return true;
}
return null;
@@ -128,7 +64,6 @@ class RouterRoute extends RouterEntry {
* @return self
*/
public function setUrl($url) {
$parameters = array();
$matches = array();
@@ -137,9 +72,11 @@ class RouterRoute extends RouterEntry {
}
if(count($parameters)) {
$tmp = array();
foreach($parameters as $param) {
$this->parameters[$param] = '';
$tmp[$param] = '';
}
$this->parameters = $tmp;
}
$this->url = $url;
+1 -1
View File
@@ -19,7 +19,7 @@ class SimpleRouter {
* @throws RouterException
*/
public static function start($defaultNamespace = null) {
$router = RouterBase::GetInstance();
$router = RouterBase::getInstance();
$router->setDefaultNamespace($defaultNamespace);
$router->routeRequest();
}