mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-06-17 00:37:52 +00:00
Development
- Fixed updatae causing middlewares to sometimes load on wrong routes. - Converted project to PSR/2. - Updated InputCollection class and added get method for easy access to values. - Complete refactor of RouterBase. - Added findRoute method to RouterBase. - It's now possible to change parameter modifiers and symbol by overwriting properties on RouterBase. - Added RouterUrlTest unit-test for testing route-urls. - Added IRestController that can be easily implemented in custom ResourceController-classes. - It's now possible to use "-" instead of "_" when using getHeader method in Request class. - Added PHPDocs. - Fixed "/" route sometimes returning "//" as url. - Optimisations and bugfixes.
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
<?php
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
interface IControllerRoute {
|
||||
interface IControllerRoute
|
||||
{
|
||||
public function getController();
|
||||
|
||||
public function getController();
|
||||
public function setController($controller);
|
||||
public function getMethod();
|
||||
public function setMethod($method);
|
||||
public function setController($controller);
|
||||
|
||||
public function getMethod();
|
||||
|
||||
public function setMethod($method);
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
interface ILoadableRoute {
|
||||
|
||||
public function getUrl();
|
||||
public function setUrl($url);
|
||||
interface ILoadableRoute
|
||||
{
|
||||
public function getUrl();
|
||||
|
||||
public function setUrl($url);
|
||||
}
|
||||
@@ -1,84 +1,90 @@
|
||||
<?php
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
abstract class LoadableRoute extends RouterEntry implements ILoadableRoute {
|
||||
abstract class LoadableRoute extends RouterEntry implements ILoadableRoute
|
||||
{
|
||||
const PARAMETERS_REGEX_MATCH = '{([A-Za-z\-\_]*?)\?{0,1}}';
|
||||
|
||||
const PARAMETERS_REGEX_MATCH = '{([A-Za-z\-\_]*?)\?{0,1}}';
|
||||
protected $url;
|
||||
protected $alias;
|
||||
|
||||
protected $url;
|
||||
protected $alias;
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function getUrl() {
|
||||
return $this->url;
|
||||
}
|
||||
/**
|
||||
* Set url
|
||||
*
|
||||
* @param string $url
|
||||
* @return static
|
||||
*/
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = ($url === '/') ? '/' : '/' . trim($url, '/') . '/';
|
||||
|
||||
/**
|
||||
* Set url
|
||||
*
|
||||
* @param string $url
|
||||
* @return static
|
||||
*/
|
||||
public function setUrl($url) {
|
||||
$this->url = '/' . trim($url, '/') . '/';
|
||||
if (preg_match_all('/' . static::PARAMETERS_REGEX_MATCH . '/is', $this->url, $matches)) {
|
||||
if (count($matches[1]) > 0) {
|
||||
foreach ($matches[1] as $key) {
|
||||
$this->parameters[$key] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(preg_match_all('/' . static::PARAMETERS_REGEX_MATCH . '/is', $this->url, $matches)) {
|
||||
if (count($matches[1])) {
|
||||
foreach ($matches[1] as $key) {
|
||||
$this->parameters[$key] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Get alias for the url which can be used when getting the url route.
|
||||
* @return string|array
|
||||
*/
|
||||
public function getAlias()
|
||||
{
|
||||
return $this->alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alias for the url which can be used when getting the url route.
|
||||
* @return string|array
|
||||
*/
|
||||
public function getAlias(){
|
||||
return $this->alias;
|
||||
}
|
||||
/**
|
||||
* Check if route has given alias.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAlias($name)
|
||||
{
|
||||
if ($this->getAlias() !== null) {
|
||||
if (is_array($this->getAlias()) === true) {
|
||||
foreach ($this->getAlias() as $alias) {
|
||||
if (strtolower($alias) === strtolower($name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return strtolower($this->getAlias()) === strtolower($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if route has given alias.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAlias($name) {
|
||||
if ($this->getAlias() !== null) {
|
||||
if (is_array($this->getAlias())) {
|
||||
foreach ($this->getAlias() as $alias) {
|
||||
if (strtolower($alias) === strtolower($name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return strtolower($this->getAlias()) === strtolower($name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Set the url alias for easier getting the url route.
|
||||
* @param string|array $alias
|
||||
* @return static
|
||||
*/
|
||||
public function setAlias($alias)
|
||||
{
|
||||
$this->alias = $alias;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the url alias for easier getting the url route.
|
||||
* @param string|array $alias
|
||||
* @return static
|
||||
*/
|
||||
public function setAlias($alias){
|
||||
$this->alias = $alias;
|
||||
return $this;
|
||||
}
|
||||
public function setData(array $settings)
|
||||
{
|
||||
|
||||
public function setData(array $settings) {
|
||||
// Change as to alias
|
||||
if (isset($settings['as'])) {
|
||||
$this->setAlias($settings['as']);
|
||||
}
|
||||
|
||||
// Change as to alias
|
||||
if(isset($settings['as'])) {
|
||||
$this->setAlias($settings['as']);
|
||||
}
|
||||
|
||||
return parent::setData($settings);
|
||||
}
|
||||
return parent::setData($settings);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,7 @@ namespace Pecee\SimpleRouter;
|
||||
|
||||
use Pecee\Http\Request;
|
||||
|
||||
abstract class RouterBootManager {
|
||||
|
||||
abstract public function boot(Request $request);
|
||||
|
||||
abstract class RouterBootManager
|
||||
{
|
||||
abstract public function boot(Request $request);
|
||||
}
|
||||
@@ -4,100 +4,107 @@ namespace Pecee\SimpleRouter;
|
||||
use Pecee\Exception\RouterException;
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class RouterController extends LoadableRoute implements IControllerRoute {
|
||||
class RouterController extends LoadableRoute implements IControllerRoute
|
||||
{
|
||||
protected $defaultMethod = 'index';
|
||||
protected $controller;
|
||||
protected $method;
|
||||
|
||||
const DEFAULT_METHOD = 'index';
|
||||
public function __construct($url, $controller)
|
||||
{
|
||||
$this->setUrl($url);
|
||||
$this->controller = $controller;
|
||||
}
|
||||
|
||||
protected $controller;
|
||||
protected $method;
|
||||
public function renderRoute(Request $request)
|
||||
{
|
||||
if ($this->getCallback() !== null && is_callable($this->getCallback())) {
|
||||
|
||||
public function __construct($url, $controller) {
|
||||
$this->setUrl($url);
|
||||
$this->controller = $controller;
|
||||
}
|
||||
// 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];
|
||||
|
||||
public function renderRoute(Request $request) {
|
||||
if($this->getCallback() !== null && is_callable($this->getCallback())) {
|
||||
$class = $this->loadClass($className);
|
||||
$method = $request->getMethod() . ucfirst($controller[1]);
|
||||
|
||||
// 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];
|
||||
if (!method_exists($class, $method)) {
|
||||
throw new RouterException(sprintf('Method %s does not exist in class %s', $method, $className), 404);
|
||||
}
|
||||
|
||||
$class = $this->loadClass($className);
|
||||
$method = $request->getMethod() . ucfirst($controller[1]);
|
||||
call_user_func_array(array($class, $method), $this->getParameters());
|
||||
|
||||
if (!method_exists($class, $method)) {
|
||||
throw new RouterException(sprintf('Method %s does not exist in class %s', $method, $className), 404);
|
||||
}
|
||||
return $class;
|
||||
}
|
||||
|
||||
call_user_func_array(array($class, $method), $this->getParameters());
|
||||
return null;
|
||||
}
|
||||
|
||||
return $class;
|
||||
}
|
||||
public function matchRoute(Request $request)
|
||||
{
|
||||
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
|
||||
$url = rtrim($url, '/') . '/';
|
||||
|
||||
return null;
|
||||
}
|
||||
if (strtolower($url) == strtolower($this->url) || stripos($url, $this->url) === 0) {
|
||||
|
||||
public function matchRoute(Request $request) {
|
||||
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
|
||||
$url = rtrim($url, '/') . '/';
|
||||
$strippedUrl = trim(str_ireplace($this->url, '/', $url), '/');
|
||||
|
||||
if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url) === 0) {
|
||||
$path = explode('/', $strippedUrl);
|
||||
|
||||
$strippedUrl = trim(str_ireplace($this->url, '/', $url), '/');
|
||||
if (count($path) > 0) {
|
||||
|
||||
$path = explode('/', $strippedUrl);
|
||||
$method = (!isset($path[0]) || trim($path[0]) === '') ? $this->defaultMethod : $path[0];
|
||||
$this->method = $method;
|
||||
|
||||
if(count($path)) {
|
||||
array_shift($path);
|
||||
$this->parameters = $path;
|
||||
|
||||
$method = (!isset($path[0]) || trim($path[0]) === '') ? static::DEFAULT_METHOD : $path[0];
|
||||
$this->method = $method;
|
||||
// Set callback
|
||||
$this->setCallback($this->controller . '@' . $this->method);
|
||||
|
||||
array_shift($path);
|
||||
$this->parameters = $path;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Set callback
|
||||
$this->setCallback($this->controller . '@' . $this->method);
|
||||
return null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getController()
|
||||
{
|
||||
return $this->controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getController() {
|
||||
return $this->controller;
|
||||
}
|
||||
/**
|
||||
* @param string $controller
|
||||
* @return static
|
||||
*/
|
||||
public function setController($controller)
|
||||
{
|
||||
$this->controller = $controller;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controller
|
||||
* @return static
|
||||
*/
|
||||
public function setController($controller) {
|
||||
$this->controller = $controller;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod() {
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return static
|
||||
*/
|
||||
public function setMethod($method) {
|
||||
$this->method = $method;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @param string $method
|
||||
* @return static
|
||||
*/
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->method = $method;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,405 +1,428 @@
|
||||
<?php
|
||||
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
use Pecee\Exception\RouterException;
|
||||
use Pecee\Http\Middleware\IMiddleware;
|
||||
use Pecee\Http\Request;
|
||||
|
||||
abstract class RouterEntry {
|
||||
|
||||
const REQUEST_TYPE_GET = 'get';
|
||||
const REQUEST_TYPE_POST = 'post';
|
||||
const REQUEST_TYPE_PUT = 'put';
|
||||
const REQUEST_TYPE_PATCH = 'patch';
|
||||
const REQUEST_TYPE_OPTIONS = 'options';
|
||||
const REQUEST_TYPE_DELETE = 'delete';
|
||||
|
||||
public static $allowedRequestTypes = [
|
||||
self::REQUEST_TYPE_GET,
|
||||
self::REQUEST_TYPE_POST,
|
||||
self::REQUEST_TYPE_PUT,
|
||||
self::REQUEST_TYPE_PATCH,
|
||||
self::REQUEST_TYPE_OPTIONS,
|
||||
self::REQUEST_TYPE_DELETE,
|
||||
];
|
||||
|
||||
protected $parent;
|
||||
protected $callback;
|
||||
|
||||
protected $namespace;
|
||||
protected $regex;
|
||||
protected $requestMethods = array();
|
||||
protected $where = array();
|
||||
protected $parameters = array();
|
||||
protected $middlewares = array();
|
||||
|
||||
protected function loadClass($name) {
|
||||
if(!class_exists($name)) {
|
||||
throw new RouterException(sprintf('Class %s does not exist', $name));
|
||||
}
|
||||
|
||||
return new $name();
|
||||
}
|
||||
|
||||
protected function parseParameters($route, $url, $parameterRegex = '[\w]+') {
|
||||
$parameterNames = array();
|
||||
$regex = '';
|
||||
$lastCharacter = '';
|
||||
$isParameter = false;
|
||||
$parameter = '';
|
||||
|
||||
$routeLength = strlen($route);
|
||||
for($i = 0; $i < $routeLength; $i++) {
|
||||
|
||||
$character = $route[$i];
|
||||
|
||||
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
|
||||
|
||||
// Use custom parameter regex if it exists
|
||||
if(is_array($this->where) && isset($this->where[$parameter])) {
|
||||
$parameterRegex = $this->where[$parameter];
|
||||
}
|
||||
|
||||
if($lastCharacter === '?') {
|
||||
$parameter = substr($parameter, 0, strlen($parameter)-1);
|
||||
$regex .= '(?:\/?(?P<' . $parameter . '>'. $parameterRegex .')[^\/]?)?';
|
||||
$required = false;
|
||||
} else {
|
||||
$regex .= '\/?(?P<' . $parameter . '>'. $parameterRegex .')[^\/]?';
|
||||
}
|
||||
|
||||
$parameterNames[] = [
|
||||
'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);
|
||||
|
||||
for($i = 0; $i < $max; $i++) {
|
||||
$name = $parameterNames[$i];
|
||||
$parameterValue = isset($parameterValues[$name['name']]) ? $parameterValues[$name['name']] : null;
|
||||
|
||||
if($name['required'] && $parameterValue === null) {
|
||||
throw new RouterException('Missing required parameter ' . $name['name'], 404);
|
||||
}
|
||||
|
||||
if(!$name['required'] && $parameterValue === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parameters[$name['name']] = $parameterValue;
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadMiddleware(Request $request, RouterEntry &$route) {
|
||||
if(count($this->getMiddlewares())) {
|
||||
foreach($this->getMiddlewares() as $middleware) {
|
||||
$middleware = $this->loadClass($middleware);
|
||||
if (!($middleware instanceof IMiddleware)) {
|
||||
throw new RouterException($middleware . ' must be instance of Middleware');
|
||||
}
|
||||
|
||||
/* @var $class IMiddleware */
|
||||
$middleware->handle($request, $route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 = $controller[1];
|
||||
|
||||
if (!method_exists($class, $method)) {
|
||||
throw new RouterException(sprintf('Method %s does not exist in class %s', $method, $className), 404);
|
||||
}
|
||||
|
||||
$parameters = array_filter($this->getParameters(), function($var){
|
||||
return ($var !== null);
|
||||
});
|
||||
|
||||
call_user_func_array(array($class, $method), $parameters);
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* when using translations etc.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier() {
|
||||
if(strpos($this->callback, '@') !== false) {
|
||||
return $this->callback;
|
||||
}
|
||||
return 'function_' . md5($this->callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set allowed request methods
|
||||
*
|
||||
* @param array $methods
|
||||
* @return static $this
|
||||
*/
|
||||
public function setRequestMethods(array $methods) {
|
||||
$this->requestMethods = $methods;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed request methods
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRequestMethods() {
|
||||
return $this->requestMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RouterEntry
|
||||
*/
|
||||
public function getParent() {
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parent route
|
||||
* @param RouterEntry $parent
|
||||
* @return static $this
|
||||
*/
|
||||
public function setParent(RouterEntry $parent) {
|
||||
$this->parent = $parent;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $callback
|
||||
* @return static
|
||||
*/
|
||||
public function setCallback($callback) {
|
||||
$this->callback = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCallback() {
|
||||
return $this->callback;
|
||||
}
|
||||
|
||||
public function getMethod() {
|
||||
if(strpos($this->callback, '@') !== false) {
|
||||
$tmp = explode('@', $this->callback);
|
||||
return $tmp[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getClass() {
|
||||
if(strpos($this->callback, '@') !== false) {
|
||||
$tmp = explode('@', $this->callback);
|
||||
return $tmp[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setMethod($method) {
|
||||
$this->callback = sprintf('%s@%s', $this->getClass(), $method);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setClass($class) {
|
||||
$this->callback = sprintf('%s@%s', $class, $this->getMethod());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $middleware
|
||||
* @return static
|
||||
*/
|
||||
public function setMiddleware($middleware) {
|
||||
$this->middlewares[] = $middleware;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMiddlewares(array $middlewares) {
|
||||
$this->middlewares = $middlewares;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @return static
|
||||
*/
|
||||
public function setNamespace($namespace) {
|
||||
$this->namespace = $namespace;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|array
|
||||
*/
|
||||
public function getMiddlewares() {
|
||||
return $this->middlewares;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace() {
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters(){
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $parameters
|
||||
* @return static
|
||||
*/
|
||||
public function setParameters($parameters) {
|
||||
$this->parameters = $parameters;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add regular expression parameter match
|
||||
*
|
||||
* @param array $options
|
||||
* @return static
|
||||
*/
|
||||
public function where(array $options) {
|
||||
$this->where = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add regular expression match for url
|
||||
*
|
||||
* @param string $regex
|
||||
* @return static
|
||||
*/
|
||||
public function match($regex) {
|
||||
$this->regex = $regex;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get arguments that can be inherited by child routes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMergeableData() {
|
||||
|
||||
$output = array();
|
||||
|
||||
if($this->namespace !== null) {
|
||||
$output['namespace'] = $this->namespace;
|
||||
}
|
||||
|
||||
if(count($this->middlewares)) {
|
||||
$output['middleware'] = $this->middlewares;
|
||||
}
|
||||
|
||||
if(count($this->where)) {
|
||||
$output['where'] = $this->where;
|
||||
}
|
||||
|
||||
if(count($this->requestMethods)) {
|
||||
$output['method'] = $this->requestMethods;
|
||||
}
|
||||
|
||||
if(count($this->parameters)) {
|
||||
$output['parameters'] = $this->parameters;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set arguments/data by array
|
||||
*
|
||||
* @param array $settings
|
||||
* @return static
|
||||
*/
|
||||
public function setData(array $settings) {
|
||||
|
||||
if (isset($settings['namespace']) && $this->namespace === null) {
|
||||
$this->setNamespace($settings['namespace']);
|
||||
}
|
||||
|
||||
// Push middleware if multiple
|
||||
if (isset($settings['middleware'])) {
|
||||
$this->middlewares = array_merge((array)$settings['middleware'], $this->middlewares);
|
||||
}
|
||||
|
||||
if(isset($settings['method'])) {
|
||||
$this->setRequestMethods((array)$settings['method']);
|
||||
}
|
||||
|
||||
if(isset($settings['where'])) {
|
||||
$this->where($settings['where']);
|
||||
}
|
||||
|
||||
if(isset($settings['parameters'])) {
|
||||
$this->setParameters($settings['parameters']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
abstract function matchRoute(Request $request);
|
||||
abstract class RouterEntry
|
||||
{
|
||||
const REQUEST_TYPE_GET = 'get';
|
||||
const REQUEST_TYPE_POST = 'post';
|
||||
const REQUEST_TYPE_PUT = 'put';
|
||||
const REQUEST_TYPE_PATCH = 'patch';
|
||||
const REQUEST_TYPE_OPTIONS = 'options';
|
||||
const REQUEST_TYPE_DELETE = 'delete';
|
||||
|
||||
public static $requestTypes = [
|
||||
self::REQUEST_TYPE_GET,
|
||||
self::REQUEST_TYPE_POST,
|
||||
self::REQUEST_TYPE_PUT,
|
||||
self::REQUEST_TYPE_PATCH,
|
||||
self::REQUEST_TYPE_OPTIONS,
|
||||
self::REQUEST_TYPE_DELETE,
|
||||
];
|
||||
|
||||
protected $parent;
|
||||
protected $callback;
|
||||
|
||||
protected $namespace;
|
||||
protected $regex;
|
||||
protected $requestMethods = array();
|
||||
protected $where = array();
|
||||
protected $parameters = array();
|
||||
protected $middlewares = array();
|
||||
|
||||
protected function loadClass($name)
|
||||
{
|
||||
if (!class_exists($name)) {
|
||||
throw new RouterException(sprintf('Class %s does not exist', $name));
|
||||
}
|
||||
|
||||
return new $name();
|
||||
}
|
||||
|
||||
protected function parseParameters($route, $url, $parameterRegex = '[\w]+')
|
||||
{
|
||||
$parameterNames = array();
|
||||
$regex = '';
|
||||
$lastCharacter = '';
|
||||
$isParameter = false;
|
||||
$parameter = '';
|
||||
|
||||
$routeLength = strlen($route);
|
||||
for ($i = 0; $i < $routeLength; $i++) {
|
||||
|
||||
$character = $route[$i];
|
||||
|
||||
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 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, strlen($parameter) - 1);
|
||||
$regex .= '(?:\/?(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?)?';
|
||||
$required = false;
|
||||
} else {
|
||||
$regex .= '\/?(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?';
|
||||
}
|
||||
|
||||
$parameterNames[] = [
|
||||
'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();
|
||||
|
||||
foreach ($parameterNames as $name) {
|
||||
$parameterValue = isset($parameterValues[$name['name']]) ? $parameterValues[$name['name']] : null;
|
||||
|
||||
if ($name['required'] && $parameterValue === null) {
|
||||
throw new RouterException('Missing required parameter ' . $name['name'], 404);
|
||||
}
|
||||
|
||||
if ($name['required'] === false && $parameterValue === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parameters[$name['name']] = $parameterValue;
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadMiddleware(Request $request, RouterEntry &$route)
|
||||
{
|
||||
if (count($this->getMiddlewares()) > 0) {
|
||||
foreach ($this->getMiddlewares() as $middleware) {
|
||||
|
||||
$middleware = $this->loadClass($middleware);
|
||||
if (!($middleware instanceof IMiddleware)) {
|
||||
throw new RouterException($middleware . ' must be instance of Middleware');
|
||||
}
|
||||
|
||||
/* @var $class IMiddleware */
|
||||
$middleware->handle($request, $route);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 = $controller[1];
|
||||
|
||||
if (!method_exists($class, $method)) {
|
||||
throw new RouterException(sprintf('Method %s does not exist in class %s', $method, $className), 404);
|
||||
}
|
||||
|
||||
$parameters = array_filter($this->getParameters(), function ($var) {
|
||||
return ($var !== null);
|
||||
});
|
||||
|
||||
call_user_func_array(array($class, $method), $parameters);
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* when using translations etc.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier()
|
||||
{
|
||||
if (strpos($this->callback, '@') !== false) {
|
||||
return $this->callback;
|
||||
}
|
||||
return 'function_' . md5($this->callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set allowed request methods
|
||||
*
|
||||
* @param array $methods
|
||||
* @return static $this
|
||||
*/
|
||||
public function setRequestMethods(array $methods)
|
||||
{
|
||||
$this->requestMethods = $methods;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed request methods
|
||||
* @return array
|
||||
*/
|
||||
public function getRequestMethods()
|
||||
{
|
||||
return $this->requestMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RouterEntry
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parent route
|
||||
*
|
||||
* @param RouterEntry $parent
|
||||
* @return static $this
|
||||
*/
|
||||
public function setParent(RouterEntry $parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $callback
|
||||
* @return static
|
||||
*/
|
||||
public function setCallback($callback)
|
||||
{
|
||||
$this->callback = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCallback()
|
||||
{
|
||||
return $this->callback;
|
||||
}
|
||||
|
||||
public function getMethod()
|
||||
{
|
||||
if (strpos($this->callback, '@') !== false) {
|
||||
$tmp = explode('@', $this->callback);
|
||||
return $tmp[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getClass()
|
||||
{
|
||||
if (strpos($this->callback, '@') !== false) {
|
||||
$tmp = explode('@', $this->callback);
|
||||
return $tmp[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->callback = sprintf('%s@%s', $this->getClass(), $method);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setClass($class)
|
||||
{
|
||||
$this->callback = sprintf('%s@%s', $class, $this->getMethod());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $middleware
|
||||
* @return static
|
||||
*/
|
||||
public function setMiddleware($middleware)
|
||||
{
|
||||
$this->middlewares[] = $middleware;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMiddlewares(array $middlewares)
|
||||
{
|
||||
$this->middlewares = $middlewares;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @return static
|
||||
*/
|
||||
public function setNamespace($namespace)
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|array
|
||||
*/
|
||||
public function getMiddlewares()
|
||||
{
|
||||
return $this->middlewares;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $parameters
|
||||
* @return static
|
||||
*/
|
||||
public function setParameters($parameters)
|
||||
{
|
||||
$this->parameters = $parameters;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add regular expression parameter match
|
||||
*
|
||||
* @param array $options
|
||||
* @return static
|
||||
*/
|
||||
public function where(array $options)
|
||||
{
|
||||
$this->where = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add regular expression match for url
|
||||
*
|
||||
* @param string $regex
|
||||
* @return static
|
||||
*/
|
||||
public function match($regex)
|
||||
{
|
||||
$this->regex = $regex;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get arguments that can be inherited by child routes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMergeableData()
|
||||
{
|
||||
$output = array();
|
||||
|
||||
if ($this->namespace !== null) {
|
||||
$output['namespace'] = $this->namespace;
|
||||
}
|
||||
|
||||
if (count($this->middlewares) > 0) {
|
||||
$output['middleware'] = $this->middlewares;
|
||||
}
|
||||
|
||||
if (count($this->where) > 0) {
|
||||
$output['where'] = $this->where;
|
||||
}
|
||||
|
||||
if (count($this->requestMethods) > 0) {
|
||||
$output['method'] = $this->requestMethods;
|
||||
}
|
||||
|
||||
if (count($this->parameters) > 0) {
|
||||
$output['parameters'] = $this->parameters;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set arguments/data by array
|
||||
*
|
||||
* @param array $settings
|
||||
* @return static
|
||||
*/
|
||||
public function setData(array $settings)
|
||||
{
|
||||
if (isset($settings['namespace']) && $this->namespace === null) {
|
||||
$this->setNamespace($settings['namespace']);
|
||||
}
|
||||
|
||||
// Push middleware if multiple
|
||||
if (isset($settings['middleware'])) {
|
||||
$this->middlewares = array_merge((array)$settings['middleware'], $this->middlewares);
|
||||
}
|
||||
|
||||
if (isset($settings['method'])) {
|
||||
$this->setRequestMethods((array)$settings['method']);
|
||||
}
|
||||
|
||||
if (isset($settings['where'])) {
|
||||
$this->where($settings['where']);
|
||||
}
|
||||
|
||||
if (isset($settings['parameters'])) {
|
||||
$this->setParameters($settings['parameters']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
abstract function matchRoute(Request $request);
|
||||
|
||||
}
|
||||
@@ -1,93 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class RouterGroup extends RouterEntry {
|
||||
class RouterGroup extends RouterEntry
|
||||
{
|
||||
protected $prefix;
|
||||
protected $domains = array();
|
||||
protected $exceptionHandlers = array();
|
||||
|
||||
protected $prefix;
|
||||
protected $domains = array();
|
||||
protected $exceptionHandlers = array();
|
||||
public function matchDomain(Request $request)
|
||||
{
|
||||
if (count($this->domains) > 0) {
|
||||
foreach ($this->domains as $domain) {
|
||||
|
||||
public function matchDomain(Request $request) {
|
||||
if(count($this->domains)) {
|
||||
for($i = 0; $i < count($this->domains); $i++) {
|
||||
$domain = $this->domains[$i];
|
||||
$parameters = $this->parseParameters($domain, $request->getHost(), '.*');
|
||||
|
||||
$parameters = $this->parseParameters($domain, $request->getHost(), '.*');
|
||||
if ($parameters !== null) {
|
||||
$this->parameters = $parameters;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if($parameters !== null) {
|
||||
$this->parameters = $parameters;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public function matchRoute(Request $request)
|
||||
{
|
||||
// Skip if prefix doesn't match
|
||||
if ($this->prefix !== null && stripos($request->getUri(), $this->prefix) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchRoute(Request $request) {
|
||||
// Skip if prefix doesn't match
|
||||
if($this->prefix !== null && stripos($request->getUri(), $this->prefix) === false) {
|
||||
return false;
|
||||
}
|
||||
return $this->matchDomain($request);
|
||||
}
|
||||
|
||||
return $this->matchDomain($request);
|
||||
}
|
||||
public function setExceptionHandlers(array $handlers)
|
||||
{
|
||||
$this->exceptionHandlers = $handlers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setExceptionHandlers(array $handlers) {
|
||||
$this->exceptionHandlers = $handlers;
|
||||
return $this;
|
||||
}
|
||||
public function getExceptionHandlers()
|
||||
{
|
||||
return $this->exceptionHandlers;
|
||||
}
|
||||
|
||||
public function getExceptionHandlers() {
|
||||
return $this->exceptionHandlers;
|
||||
}
|
||||
public function getDomains()
|
||||
{
|
||||
return $this->domains;
|
||||
}
|
||||
|
||||
public function getDomains() {
|
||||
return $this->domains;
|
||||
}
|
||||
public function setDomains(array $domains)
|
||||
{
|
||||
$this->domains = $domains;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDomains(array $domains) {
|
||||
$this->domains = $domains;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @param string $prefix
|
||||
* @return static
|
||||
*/
|
||||
public function setPrefix($prefix)
|
||||
{
|
||||
$this->prefix = '/' . trim($prefix, '/');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $prefix
|
||||
* @return static
|
||||
*/
|
||||
public function setPrefix($prefix) {
|
||||
$this->prefix = '/' . trim($prefix, '/');
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPrefix()
|
||||
{
|
||||
return $this->prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPrefix() {
|
||||
return $this->prefix;
|
||||
}
|
||||
public function setData(array $settings)
|
||||
{
|
||||
if (isset($settings['prefix'])) {
|
||||
$this->setPrefix($settings['prefix']);
|
||||
}
|
||||
|
||||
public function setData(array $settings) {
|
||||
if (isset($settings['exceptionHandler'])) {
|
||||
$this->setExceptionHandlers((array)$settings['exceptionHandler']);
|
||||
}
|
||||
|
||||
if(isset($settings['prefix'])) {
|
||||
$this->setPrefix($settings['prefix']);
|
||||
}
|
||||
if (isset($settings['domain'])) {
|
||||
$this->setDomains((array)$settings['domain']);
|
||||
}
|
||||
|
||||
if(isset($settings['exceptionHandler'])) {
|
||||
$this->setExceptionHandlers((array)$settings['exceptionHandler']);
|
||||
}
|
||||
|
||||
if(isset($settings['domain'])) {
|
||||
$this->setDomains((array)$settings['domain']);
|
||||
}
|
||||
|
||||
return parent::setData($settings);
|
||||
|
||||
}
|
||||
return parent::setData($settings);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,112 +4,120 @@ namespace Pecee\SimpleRouter;
|
||||
use Pecee\Exception\RouterException;
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class RouterResource extends LoadableRoute implements IControllerRoute {
|
||||
class RouterResource extends LoadableRoute implements IControllerRoute
|
||||
{
|
||||
protected $controller;
|
||||
|
||||
protected $controller;
|
||||
public function __construct($url, $controller)
|
||||
{
|
||||
$this->setUrl($url);
|
||||
$this->controller = $controller;
|
||||
}
|
||||
|
||||
public function __construct($url, $controller) {
|
||||
$this->setUrl($url);
|
||||
$this->controller = $controller;
|
||||
}
|
||||
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]);
|
||||
|
||||
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 RouterException(sprintf('Method %s does not exist in class %s', $method, $className), 404);
|
||||
}
|
||||
|
||||
if (!method_exists($class, $method)) {
|
||||
throw new RouterException(sprintf('Method %s does not exist in class %s', $method, $className), 404);
|
||||
}
|
||||
call_user_func_array([$class, $method], $this->getParameters());
|
||||
|
||||
call_user_func_array(array($class, $method), $this->getParameters());
|
||||
return $class;
|
||||
}
|
||||
|
||||
return $class;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
protected function call($method, $parameters)
|
||||
{
|
||||
$this->setCallback($this->controller . '@' . $method);
|
||||
$this->parameters = $parameters;
|
||||
|
||||
protected function call($method, $parameters) {
|
||||
$this->setCallback($this->controller . '@' . $method);
|
||||
$this->parameters = $parameters;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function matchRoute(Request $request) {
|
||||
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
|
||||
$url = rtrim($url, '/') . '/';
|
||||
public function matchRoute(Request $request)
|
||||
{
|
||||
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
|
||||
$url = rtrim($url, '/') . '/';
|
||||
|
||||
$route = rtrim($this->url, '/') . '/{id?}/{action?}';
|
||||
$route = rtrim($this->url, '/') . '/{id?}/{action?}';
|
||||
|
||||
$parameters = $this->parseParameters($route, $url);
|
||||
$parameters = $this->parseParameters($route, $url);
|
||||
|
||||
if($parameters !== null) {
|
||||
if ($parameters !== null) {
|
||||
|
||||
if(is_array($parameters)) {
|
||||
$parameters = array_merge($this->parameters, $parameters);
|
||||
}
|
||||
$parameters = array_merge($this->parameters, (array)$parameters);
|
||||
|
||||
$action = isset($parameters['action']) ? $parameters['action'] : null;
|
||||
unset($parameters['action']);
|
||||
$action = isset($parameters['action']) ? $parameters['action'] : null;
|
||||
unset($parameters['action']);
|
||||
|
||||
// Delete
|
||||
if($request->getMethod() === static::REQUEST_TYPE_DELETE && $request->getMethod() === static::REQUEST_TYPE_POST) {
|
||||
return $this->call('destroy', $parameters);
|
||||
}
|
||||
$method = request()->getMethod();
|
||||
|
||||
// Update
|
||||
if(in_array($request->getMethod(), array(static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT)) && $request->getMethod() === static::REQUEST_TYPE_POST) {
|
||||
return $this->call('update', $parameters);
|
||||
}
|
||||
// Delete
|
||||
if (isset($parameters['id']) && $method === static::REQUEST_TYPE_DELETE) {
|
||||
return $this->call('destroy', $parameters);
|
||||
}
|
||||
|
||||
// Edit
|
||||
if(isset($action) && strtolower($action) === 'edit' && $request->getMethod() === static::REQUEST_TYPE_GET) {
|
||||
return $this->call('edit', $parameters);
|
||||
}
|
||||
// Update
|
||||
if (isset($parameters['id']) && in_array($method, [static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT])) {
|
||||
return $this->call('update', $parameters);
|
||||
}
|
||||
|
||||
// Create
|
||||
if(strtolower($action) === 'create' && $request->getMethod() === static::REQUEST_TYPE_GET) {
|
||||
return $this->call('create', $parameters);
|
||||
}
|
||||
// Edit
|
||||
if (isset($parameters['id']) && strtolower($action) === 'edit' && $method === static::REQUEST_TYPE_GET) {
|
||||
return $this->call('edit', $parameters);
|
||||
}
|
||||
|
||||
// Save
|
||||
if($request->getMethod() === static::REQUEST_TYPE_POST) {
|
||||
return $this->call('store', $parameters);
|
||||
}
|
||||
// Create
|
||||
if (strtolower($action) === 'create' && $method === static::REQUEST_TYPE_GET) {
|
||||
return $this->call('create', $parameters);
|
||||
}
|
||||
|
||||
// Show
|
||||
if(isset($parameters['id']) && $request->getMethod() === static::REQUEST_TYPE_GET) {
|
||||
return $this->call('show', $parameters);
|
||||
}
|
||||
// Save
|
||||
if ($method === static::REQUEST_TYPE_POST) {
|
||||
return $this->call('store', $parameters);
|
||||
}
|
||||
|
||||
// Index
|
||||
return $this->call('index', $parameters);
|
||||
}
|
||||
// Show
|
||||
if (isset($parameters['id']) && $method === static::REQUEST_TYPE_GET) {
|
||||
return $this->call('show', $parameters);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
// Index
|
||||
return $this->call('index', $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getController() {
|
||||
return $this->controller;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controller
|
||||
* @return static
|
||||
*/
|
||||
public function setController($controller) {
|
||||
$this->controller = $controller;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getController()
|
||||
{
|
||||
return $this->controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controller
|
||||
* @return static
|
||||
*/
|
||||
public function setController($controller)
|
||||
{
|
||||
$this->controller = $controller;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class RouterRoute extends LoadableRoute {
|
||||
class RouterRoute extends LoadableRoute
|
||||
{
|
||||
public function __construct($url, $callback)
|
||||
{
|
||||
$this->setUrl($url);
|
||||
$this->setCallback($callback);
|
||||
}
|
||||
|
||||
public function __construct($url, $callback) {
|
||||
$this->setUrl($url);
|
||||
$this->setCallback($callback);
|
||||
}
|
||||
public function matchRoute(Request $request)
|
||||
{
|
||||
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
|
||||
$url = rtrim($url, '/') . '/';
|
||||
|
||||
public function matchRoute(Request $request) {
|
||||
// Match on custom defined regular expression
|
||||
if ($this->regex !== null) {
|
||||
$parameters = array();
|
||||
if (preg_match('/(' . $this->regex . ')/is', $request->getHost() . $url, $parameters)) {
|
||||
$this->parameters = (array)$parameters[0];
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
|
||||
$url = rtrim($url, '/') . '/';
|
||||
// Make regular expression based on route
|
||||
$route = rtrim($this->url, '/') . '/';
|
||||
|
||||
// Match on custom defined regular expression
|
||||
if($this->regex !== null) {
|
||||
$parameters = array();
|
||||
if(preg_match('/(' . $this->regex . ')/is', $request->getHost() . $url, $parameters)) {
|
||||
$this->parameters = (!is_array($parameters[0]) ? array($parameters[0]) : $parameters[0]);
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
$parameters = $this->parseParameters($route, $url);
|
||||
|
||||
// Make regular expression based on route
|
||||
$route = rtrim($this->url, '/') . '/';
|
||||
if ($parameters !== null) {
|
||||
$this->parameters = array_merge($this->parameters, $parameters);
|
||||
return true;
|
||||
}
|
||||
|
||||
$parameters = $this->parseParameters($route, $url);
|
||||
|
||||
if($parameters !== null) {
|
||||
$this->parameters = array_merge($this->parameters, $parameters);
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,158 +1,347 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ---------------------------
|
||||
* Router helper class
|
||||
* ---------------------------
|
||||
* This class is added so calls can be made statically like Router::get() making the code look more pretty.
|
||||
*/
|
||||
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
use Pecee\Exception\RouterException;
|
||||
use Pecee\Http\Middleware\BaseCsrfVerifier;
|
||||
|
||||
class SimpleRouter {
|
||||
class SimpleRouter
|
||||
{
|
||||
protected static $defaultNamespace;
|
||||
|
||||
/**
|
||||
* Start/route request
|
||||
* @throws \Pecee\Exception\RouterException
|
||||
*/
|
||||
public static function start() {
|
||||
RouterBase::getInstance()->routeRequest();
|
||||
}
|
||||
/**
|
||||
* Start/route request
|
||||
*
|
||||
* @throws \Pecee\Exception\RouterException
|
||||
*/
|
||||
public static function start()
|
||||
{
|
||||
static::router()->routeRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default namespace for all routes
|
||||
* @param string $defaultNamespace
|
||||
*/
|
||||
public static function setDefaultNamespace($defaultNamespace) {
|
||||
RouterBase::getInstance()->setDefaultNamespace($defaultNamespace);
|
||||
}
|
||||
/**
|
||||
* Set default namespace which will be prepended to all routes.
|
||||
*
|
||||
* @param string $defaultNamespace
|
||||
*/
|
||||
public static function setDefaultNamespace($defaultNamespace)
|
||||
{
|
||||
static::$defaultNamespace = $defaultNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set base csrf verifier
|
||||
* @param BaseCsrfVerifier $baseCsrfVerifier
|
||||
*/
|
||||
public static function csrfVerifier(BaseCsrfVerifier $baseCsrfVerifier) {
|
||||
RouterBase::getInstance()->setCsrfVerifier($baseCsrfVerifier);
|
||||
}
|
||||
/**
|
||||
* Base CSRF verifier
|
||||
*
|
||||
* @param BaseCsrfVerifier $baseCsrfVerifier
|
||||
*/
|
||||
public static function csrfVerifier(BaseCsrfVerifier $baseCsrfVerifier)
|
||||
{
|
||||
static::router()->setCsrfVerifier($baseCsrfVerifier);
|
||||
}
|
||||
|
||||
public static function addBootManager(RouterBootManager $bootManager) {
|
||||
RouterBase::getInstance()->addBootManager($bootManager);
|
||||
}
|
||||
/**
|
||||
* Boot managers allows you to alter the routes before the routing occurs.
|
||||
* Perfect if you want to load pretty-urls from a file or database.
|
||||
*
|
||||
* @param RouterBootManager $bootManager
|
||||
*/
|
||||
public static function addBootManager(RouterBootManager $bootManager)
|
||||
{
|
||||
static::router()->addBootManager($bootManager);
|
||||
}
|
||||
|
||||
public static function get($url, $callback, array $settings = null) {
|
||||
return static::match(['get'], $url, $callback, $settings);
|
||||
}
|
||||
/**
|
||||
* Route the given url to your callback on GET request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouterRoute
|
||||
*/
|
||||
public static function get($url, $callback, array $settings = null)
|
||||
{
|
||||
return static::match(['get'], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
public static function post($url, $callback, array $settings = null) {
|
||||
return static::match(['post'], $url, $callback, $settings);
|
||||
}
|
||||
/**
|
||||
* Route the given url to your callback on POST request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouterRoute
|
||||
*/
|
||||
public static function post($url, $callback, array $settings = null)
|
||||
{
|
||||
return static::match(['post'], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
public static function put($url, $callback, array $settings = null) {
|
||||
return static::match(['put'], $url, $callback, $settings);
|
||||
}
|
||||
/**
|
||||
* Route the given url to your callback on PUT request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouterRoute
|
||||
*/
|
||||
public static function put($url, $callback, array $settings = null)
|
||||
{
|
||||
return static::match(['put'], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
public static function patch($url, $callback, array $settings = null) {
|
||||
return static::match(['patch'], $url, $callback, $settings);
|
||||
}
|
||||
/**
|
||||
* Route the given url to your callback on PATCH request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouterRoute
|
||||
*/
|
||||
public static function patch($url, $callback, array $settings = null)
|
||||
{
|
||||
return static::match(['patch'], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
public static function options($url, $callback, array $settings = null) {
|
||||
return static::match(['options'], $url, $callback, $settings);
|
||||
}
|
||||
/**
|
||||
* Route the given url to your callback on OPTIONS request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouterRoute
|
||||
*/
|
||||
public static function options($url, $callback, array $settings = null)
|
||||
{
|
||||
return static::match(['options'], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
public static function delete($url, $callback, array $settings = null) {
|
||||
return static::match(['delete'], $url, $callback, $settings);
|
||||
}
|
||||
/**
|
||||
* Route the given url to your callback on DELETE request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouterRoute
|
||||
*/
|
||||
public static function delete($url, $callback, array $settings = null)
|
||||
{
|
||||
return static::match(['delete'], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
public static function group($settings = array(), $callback) {
|
||||
$group = new RouterGroup();
|
||||
$group->setCallback($callback);
|
||||
/**
|
||||
* Groups allows for encapsulating routes with special settings.
|
||||
*
|
||||
* @param array $settings
|
||||
* @param \Closure $callback
|
||||
* @throws RouterException
|
||||
* @return RouterGroup
|
||||
*/
|
||||
public static function group($settings = array(), \Closure $callback)
|
||||
{
|
||||
$group = new RouterGroup();
|
||||
$group->setCallback($callback);
|
||||
|
||||
if($settings !== null && is_array($settings)) {
|
||||
$group->setData($settings);
|
||||
}
|
||||
if ($settings !== null && is_array($settings) === true) {
|
||||
$group->setData($settings);
|
||||
}
|
||||
|
||||
RouterBase::getInstance()->addRoute($group);
|
||||
if (is_callable($callback) === false) {
|
||||
throw new RouterException('Invalid callback provided. Only functions or methods supported');
|
||||
}
|
||||
|
||||
return $group;
|
||||
}
|
||||
static::router()->addRoute($group);
|
||||
|
||||
/**
|
||||
* Adds get + post route
|
||||
*
|
||||
* @param string $url
|
||||
* @param callable $callback
|
||||
* @param array|null $settings
|
||||
* @return RouterRoute
|
||||
*/
|
||||
public static function basic($url, $callback, array $settings = null) {
|
||||
return static::match(['get', 'post'], $url, $callback, $settings);
|
||||
}
|
||||
return $group;
|
||||
}
|
||||
|
||||
public static function match(array $requestMethods, $url, $callback, array $settings = null) {
|
||||
$route = new RouterRoute($url, $callback);
|
||||
$route->setRequestMethods($requestMethods);
|
||||
/**
|
||||
* Alias for the form method
|
||||
*
|
||||
* @param string $url
|
||||
* @param callable $callback
|
||||
* @param array|null $settings
|
||||
* @see SimpleRouter::form
|
||||
* @return RouterRoute
|
||||
*/
|
||||
public static function basic($url, $callback, array $settings = null)
|
||||
{
|
||||
return static::match(['get', 'post'], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
if($settings !== null) {
|
||||
$route->setData($settings);
|
||||
}
|
||||
/**
|
||||
* This type will route the given url to your callback on the provided request methods.
|
||||
* Route the given url to your callback on POST and GET request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @see SimpleRouter::form
|
||||
* @return RouterRoute
|
||||
*/
|
||||
public static function form($url, $callback, array $settings = null)
|
||||
{
|
||||
return static::match(['get', 'post'], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
RouterBase::getInstance()->addRoute($route);
|
||||
/**
|
||||
* This type will route the given url to your callback on the provided request methods.
|
||||
*
|
||||
* @param array $requestMethods
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouterEntry|RouterRoute
|
||||
*/
|
||||
public static function match(array $requestMethods, $url, $callback, array $settings = null)
|
||||
{
|
||||
$route = new RouterRoute($url, $callback);
|
||||
$route->setRequestMethods($requestMethods);
|
||||
|
||||
return $route;
|
||||
}
|
||||
if ($settings !== null) {
|
||||
$route->setData($settings);
|
||||
}
|
||||
|
||||
public static function all($url, $callback, array $settings = null) {
|
||||
$route = new RouterRoute($url, $callback);
|
||||
$route = static::addDefaultNamespace($route);
|
||||
|
||||
if($settings !== null) {
|
||||
$route->setData($settings);
|
||||
}
|
||||
static::router()->addRoute($route);
|
||||
|
||||
RouterBase::getInstance()->addRoute($route);
|
||||
return $route;
|
||||
}
|
||||
|
||||
return $route;
|
||||
}
|
||||
/**
|
||||
* This type will route the given url to your callback and allow any type of request method
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouterRoute
|
||||
*/
|
||||
public static function all($url, $callback, array $settings = null)
|
||||
{
|
||||
$route = new RouterRoute($url, $callback);
|
||||
|
||||
public static function controller($url, $controller, array $settings = null) {
|
||||
$route = new RouterController($url, $controller);
|
||||
if ($settings !== null) {
|
||||
$route->setData($settings);
|
||||
}
|
||||
|
||||
if($settings !== null) {
|
||||
$route->setData($settings);
|
||||
}
|
||||
$route = static::addDefaultNamespace($route);
|
||||
|
||||
RouterBase::getInstance()->addRoute($route);
|
||||
static::router()->addRoute($route);
|
||||
|
||||
return $route;
|
||||
}
|
||||
return $route;
|
||||
}
|
||||
|
||||
public static function resource($url, $controller, array $settings = null) {
|
||||
$route = new RouterResource($url, $controller);
|
||||
/**
|
||||
* This route will route request from the given url to the controller.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $controller
|
||||
* @param array|null $settings
|
||||
* @return RouterController
|
||||
*/
|
||||
public static function controller($url, $controller, array $settings = null)
|
||||
{
|
||||
$route = new RouterController($url, $controller);
|
||||
|
||||
if($settings !== null) {
|
||||
$route->setData($settings);
|
||||
}
|
||||
if ($settings !== null) {
|
||||
$route->setData($settings);
|
||||
}
|
||||
|
||||
static::router()->addRoute($route);
|
||||
$route = static::addDefaultNamespace($route);
|
||||
|
||||
return $route;
|
||||
}
|
||||
static::router()->addRoute($route);
|
||||
|
||||
public static function getRoute($controller = null, $parameters = null, $getParams = null) {
|
||||
return static::router()->getRoute($controller, $parameters, $getParams);
|
||||
}
|
||||
return $route;
|
||||
}
|
||||
|
||||
public static function request() {
|
||||
return static::router()->getRequest();
|
||||
}
|
||||
/**
|
||||
* This type will route all REST-supported requests to different methods in the provided controller.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $controller
|
||||
* @param array|null $settings
|
||||
* @return RouterResource
|
||||
*/
|
||||
public static function resource($url, $controller, array $settings = null)
|
||||
{
|
||||
$route = new RouterResource($url, $controller);
|
||||
|
||||
public static function response() {
|
||||
return static::router()->getResponse();
|
||||
}
|
||||
if ($settings !== null) {
|
||||
$route->setData($settings);
|
||||
}
|
||||
|
||||
protected static function router() {
|
||||
return RouterBase::getInstance();
|
||||
}
|
||||
static::router()->addRoute($route);
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get url by controller or alias.
|
||||
*
|
||||
* @param string $controller
|
||||
* @param array|null $parameters
|
||||
* @param array|null $getParams
|
||||
* @return string
|
||||
*/
|
||||
public static function getRoute($controller = null, $parameters = null, $getParams = null)
|
||||
{
|
||||
return static::router()->getRoute($controller, $parameters, $getParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request
|
||||
*
|
||||
* @return \Pecee\Http\Request
|
||||
*/
|
||||
public static function request()
|
||||
{
|
||||
return static::router()->getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response object
|
||||
*
|
||||
* @return \Pecee\Http\Response
|
||||
*/
|
||||
public static function response()
|
||||
{
|
||||
return static::router()->getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the router instance
|
||||
*
|
||||
* @return RouterBase
|
||||
*/
|
||||
public static function router()
|
||||
{
|
||||
return RouterBase::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends the default namespace to all new routes added.
|
||||
*
|
||||
* @param RouterEntry $route
|
||||
* @return RouterEntry
|
||||
*/
|
||||
protected static function addDefaultNamespace(RouterEntry $route)
|
||||
{
|
||||
if (static::$defaultNamespace !== null) {
|
||||
$namespace = static::$defaultNamespace;
|
||||
|
||||
if ($route->getNamespace() !== null) {
|
||||
$namespace .= '\\' . $route->getNamespace();
|
||||
}
|
||||
|
||||
$route->setNamespace($namespace);
|
||||
}
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user