Merge pull request #192 from skipperbent/v2-development

V2 development
This commit is contained in:
Simon Sessingø
2016-11-26 05:03:36 +01:00
committed by GitHub
27 changed files with 683 additions and 416 deletions
+5 -6
View File
@@ -92,8 +92,7 @@ composer require pecee/simple-router
## Requirements ## Requirements
- PHP 5.4 or greater - PHP 5.5 or greater
- mcrypt extension
## Notes ## Notes
@@ -756,7 +755,7 @@ If items is grouped in the html, it will return an array of items.
**Note:** `get` will automatically trim the value and ensure that it's not empty. If it's empty the `$defaultValue` will be returned. **Note:** `get` will automatically trim the value and ensure that it's not empty. If it's empty the `$defaultValue` will be returned.
```php ```php
$value = input()->get($index, $defaultValue); $value = input()->get($index, $defaultValue, $methods);
``` ```
**Return parameter object (matches both GET, POST, FILE):** **Return parameter object (matches both GET, POST, FILE):**
@@ -772,7 +771,7 @@ If items is grouped in the html, it will return an array of items.
**Note:** `getObject` will only return `$defaultValue` if the item doesn't exist. If you want `$defaultValue` to be returned if the item is empty, please use `input()->get()` instead. **Note:** `getObject` will only return `$defaultValue` if the item doesn't exist. If you want `$defaultValue` to be returned if the item is empty, please use `input()->get()` instead.
```php ```php
$object = input()->getObject($index); $object = input()->getObject($index, $defaultValue = null, $methods = null);
``` ```
**Return specific GET parameter (where name is the name of your parameter):** **Return specific GET parameter (where name is the name of your parameter):**
@@ -853,8 +852,8 @@ All object implements the `IInputItem` interface and will always contain these m
Below example requires you to have the helper functions added. Please refer to the helper functions section in the documentation. Below example requires you to have the helper functions added. Please refer to the helper functions section in the documentation.
```php ```php
// Get parameter site_id or default-value 2 /* Get parameter site_id or default-value 2 from either post-value or query-string */
$siteId = input()->get('site_id', 2); $siteId = input()->get('site_id', 2, ['post', 'get']);
``` ```
--- ---
+7 -7
View File
@@ -7,41 +7,41 @@ interface IRestController
/** /**
* @return void * @return void
*/ */
function index(); public function index();
/** /**
* @param mixed $id * @param mixed $id
* @return void * @return void
*/ */
function show($id); public function show($id);
/** /**
* @return void * @return void
*/ */
function store(); public function store();
/** /**
* @return void * @return void
*/ */
function create(); public function create();
/** /**
* View * View
* @param mixed $id * @param mixed $id
* @return void * @return void
*/ */
function edit($id); public function edit($id);
/** /**
* @param mixed $id * @param mixed $id
* @return void * @return void
*/ */
function update($id); public function update($id);
/** /**
* @param mixed $id * @param mixed $id
* @return void * @return void
*/ */
function destroy($id); public function destroy($id);
} }
-4
View File
@@ -12,10 +12,6 @@ interface IInputItem
public function setName($name); public function setName($name);
public function getValue();
public function setValue($value);
public function __toString(); public function __toString();
} }
+140 -74
View File
@@ -32,7 +32,7 @@ class Input
$this->parseInputs(); $this->parseInputs();
} }
protected function parseInputs() public function parseInputs()
{ {
/* Parse get requests */ /* Parse get requests */
if (count($_GET) > 0) { if (count($_GET) > 0) {
@@ -42,7 +42,7 @@ class Input
/* Parse post requests */ /* Parse post requests */
$postVars = $_POST; $postVars = $_POST;
if (in_array($this->request->getMethod(), ['put', 'patch', 'delete']) === true) { if (in_array($this->request->getMethod(), ['put', 'patch', 'delete'], false) === true) {
parse_str(file_get_contents('php://input'), $postVars); parse_str(file_get_contents('php://input'), $postVars);
} }
@@ -51,49 +51,86 @@ class Input
} }
/* Parse get requests */ /* Parse get requests */
$this->parseFiles();
if (count($_FILES) > 0) {
$max = count($_FILES) - 1;
$keys = array_keys($_FILES);
for ($i = $max; $i >= 0; $i--) {
$key = $keys[$i];
$value = $_FILES[$key];
// Handle array input
if (is_array($value['name']) === false) {
$values['index'] = $key;
$this->file[$key] = InputFile::createFromArray(array_merge($value, $values));
continue;
}
$subMax = count($value['name']) - 1;
$keys = array_keys($value['name']);
$output = [];
for ($i = $subMax; $i >= 0; $i--) {
$output[$keys[$i]] = InputFile::createFromArray([
'index' => $key,
'error' => $value['error'][$keys[$i]],
'tmp_name' => $value['tmp_name'][$keys[$i]],
'type' => $value['type'][$keys[$i]],
'size' => $value['size'][$keys[$i]],
'name' => $value['name'][$keys[$i]],
]);
}
$this->file[$key] = $output;
}
}
} }
protected function handleGetPost($array) public function parseFiles()
{ {
$tmp = []; if (count($_FILES) === 0) {
return [];
}
$list = [];
foreach ($_FILES as $key => $value) {
// Handle array input
if (is_array($value['name']) === false) {
$values['index'] = $key;
$list[$key] = InputFile::createFromArray(array_merge($value, $values));
continue;
}
$keys = [];
$list = array_merge_recursive($list, [$key => $this->rearrangeFiles($value['name'], $keys, $value)]);
}
return $list;
}
protected function rearrangeFiles(array $values, &$index, $original)
{
$output = [];
$getItem = function ($key, $property = 'name') use ($original, $index) {
$path = $original[$property];
foreach (array_values($index) as $i) {
$path = $path[$i];
}
return $path[$key];
};
foreach ($values as $key => $value) {
if (is_array($getItem($key)) === false) {
$file = InputFile::createFromArray([
'index' => $key,
'error' => $getItem($key, 'error'),
'tmp_name' => $getItem($key, 'tmp_name'),
'type' => $getItem($key, 'type'),
'size' => $getItem($key, 'size'),
'filename' => $getItem($key, 'name'),
]);
$output = array_merge_recursive($output, [$key => $file]);
if (isset($output[$key])) {
$output[$key][] = $file;
} else {
$output[$key] = $file;
}
continue;
}
$index[] = $key;
$output = array_merge_recursive($output, [$key => $this->rearrangeFiles($value, $index, $original)]);
}
return $output;
}
protected function handleGetPost(array $array)
{
$list = [];
$max = count($array) - 1; $max = count($array) - 1;
$keys = array_keys($array); $keys = array_keys($array);
@@ -105,77 +142,110 @@ class Input
// Handle array input // Handle array input
if (is_array($value) === false) { if (is_array($value) === false) {
$tmp[$key] = new InputItem($key, $value); $list[$key] = new InputItem($key, $value);
continue; continue;
} }
$subMax = count($value) - 1; $output = $this->handleGetPost($value);
$keys = array_keys($value);
$output = [];
for ($i = $subMax; $i >= 0; $i--) { $list[$key] = $output;
$output[$keys[$i]] = new InputItem($key, $value[$keys[$i]]);
}
$tmp[$key] = $output;
} }
return $tmp; return $list;
} }
public function findPost($index, $default = null) /**
* Find post-value by index or return default value.
*
* @param string $index
* @param string|null $defaultValue
* @return InputItem|string
*/
public function findPost($index, $defaultValue = null)
{ {
return isset($this->post[$index]) ? $this->post[$index] : $default; return isset($this->post[$index]) ? $this->post[$index] : $defaultValue;
} }
public function findFile($index, $default = null) /**
* Find file by index or return default value.
*
* @param string $index
* @param string|null $defaultValue
* @return InputFile|string
*/
public function findFile($index, $defaultValue = null)
{ {
return isset($this->file[$index]) ? $this->file[$index] : $default; return isset($this->file[$index]) ? $this->file[$index] : $defaultValue;
} }
public function findGet($index, $default = null) /**
* Find parameter/query-string by index or return default value.
*
* @param string $index
* @param string|null $defaultValue
* @return InputItem|string
*/
public function findGet($index, $defaultValue = null)
{ {
return isset($this->get[$index]) ? $this->get[$index] : $default; return isset($this->get[$index]) ? $this->get[$index] : $defaultValue;
} }
public function getObject($index, $default = null, $method = null) /**
* Get input object
*
* @param string $index
* @param string|null $defaultValue
* @param array|string|null $methods
* @return IInputItem|string
*/
public function getObject($index, $defaultValue = null, $methods = null)
{ {
if ($methods !== null && is_string($methods) === true) {
$methods = [$methods];
}
$element = null; $element = null;
if ($method === null || strtolower($method) === 'get') { if ($methods === null || in_array('get', $methods)) {
$element = $this->findGet($index); $element = $this->findGet($index);
} }
if ($element === null && $method === null || strtolower($method) === 'post') { if (($element === null && $methods === null) || ($methods !== null && in_array('post', $methods))) {
$element = $this->findPost($index); $element = $this->findPost($index);
} }
if ($element === null && $method === null || strtolower($method) === 'file') { if (($element === null && $methods === null) || ($methods !== null && in_array('file', $methods))) {
$element = $this->findFile($index); $element = $this->findFile($index);
} }
return ($element === null) ? $default : $element; return ($element !== null) ? $element : $defaultValue;
} }
/** /**
* Get input element value matching index * Get input element value matching index
* *
* @param string $index * @param string $index
* @param string|null $default * @param string|null $defaultValue
* @param string|null $method * @param array|string|null $methods
* @return InputItem|string * @return InputItem|string
*/ */
public function get($index, $default = null, $method = null) public function get($index, $defaultValue = null, $methods = null)
{ {
$input = $this->getObject($index, $default, $method); $input = $this->getObject($index, $defaultValue, $methods);
if ($input instanceof InputItem) { if ($input instanceof InputItem) {
return (trim($input->getValue()) === '') ? $default : $input->getValue(); return (trim($input->getValue()) === '') ? $defaultValue : $input->getValue();
} }
return $input; return $input;
} }
/**
* Check if a input-item exist
*
* @param string $index
* @return bool
*/
public function exists($index) public function exists($index)
{ {
return ($this->getObject($index) !== null); return ($this->getObject($index) !== null);
@@ -194,7 +264,7 @@ class Input
$contents = file_get_contents('php://input'); $contents = file_get_contents('php://input');
if (stripos(trim($contents), '{') === 0) { if (strpos(trim($contents), '{') === 0) {
$output = json_decode($contents, true); $output = json_decode($contents, true);
if ($output === false) { if ($output === false) {
$output = []; $output = [];
@@ -206,11 +276,7 @@ class Input
if ($filter !== null) { if ($filter !== null) {
$output = array_filter($output, function ($key) use ($filter) { $output = array_filter($output, function ($key) use ($filter) {
if (in_array($key, $filter)) { return (in_array($key, $filter) === true);
return true;
}
return false;
}, ARRAY_FILTER_USE_KEY); }, ARRAY_FILTER_USE_KEY);
} }
+100 -34
View File
@@ -4,8 +4,8 @@ namespace Pecee\Http\Input;
class InputFile implements IInputItem class InputFile implements IInputItem
{ {
public $index; public $index;
public $value;
public $name; public $name;
public $filename;
public $size; public $size;
public $type; public $type;
public $error; public $error;
@@ -21,7 +21,9 @@ class InputFile implements IInputItem
/** /**
* Create from array * Create from array
*
* @param array $values * @param array $values
* @throws \InvalidArgumentException
* @return static * @return static
*/ */
public static function createFromArray(array $values) public static function createFromArray(array $values)
@@ -30,12 +32,22 @@ class InputFile implements IInputItem
throw new \InvalidArgumentException('Index key is required'); throw new \InvalidArgumentException('Index key is required');
} }
/* Easy way of ensuring that all indexes-are set and not filling the screen with isset() */
$values = array_merge([
'tmp_name' => null,
'type' => null,
'size' => null,
'name' => null,
'error' => null,
], $values);
$input = new static($values['index']); $input = new static($values['index']);
$input->setError(isset($values['error']) ? $values['error'] : null); $input->setError($values['error'])
$input->setName(isset($values['name']) ? $values['name'] : null); ->setSize($values['size'])
$input->setSize(isset($values['size']) ? $values['size'] : null); ->setType($values['type'])
$input->setType(isset($values['type']) ? $values['type'] : null); ->setTmpName($values['tmp_name'])
$input->setTmpName(isset($values['tmp_name']) ? $values['tmp_name'] : null); ->setFilename($values['name']);
return $input; return $input;
} }
@@ -48,6 +60,11 @@ class InputFile implements IInputItem
return $this->index; return $this->index;
} }
/**
* Set input index
* @param string $index
* @return static $this
*/
public function setIndex($index) public function setIndex($index)
{ {
$this->index = $index; $this->index = $index;
@@ -75,6 +92,10 @@ class InputFile implements IInputItem
return $this; return $this;
} }
/**
* Get mime-type of file
* @return string
*/
public function getMime() public function getMime()
{ {
return $this->getType(); return $this->getType();
@@ -100,12 +121,19 @@ class InputFile implements IInputItem
return $this; return $this;
} }
/**
* Returns extension without "."
*
* @return string
*/
public function getExtension() public function getExtension()
{ {
return pathinfo($this->getName(), PATHINFO_EXTENSION); return pathinfo($this->getName(), PATHINFO_EXTENSION);
} }
/** /**
* Get human friendly name
*
* @return string * @return string
*/ */
public function getName() public function getName()
@@ -113,6 +141,13 @@ class InputFile implements IInputItem
return $this->name; return $this->name;
} }
/**
* Set human friendly name.
* Useful for adding validation etc.
*
* @param string $name
* @return static $this
*/
public function setName($name) public function setName($name)
{ {
$this->name = $name; $this->name = $name;
@@ -120,29 +155,63 @@ class InputFile implements IInputItem
return $this; return $this;
} }
/**
* Set filename
*
* @param string $name
* @return static $this
*/
public function setFilename($name)
{
$this->filename = $name;
return $this;
}
/**
* Get filename
*
* @return string mixed
*/
public function getFilename()
{
return $this->filename;
}
/**
* Move the uploaded temporary file to it's new home
*
* @param string $destination
* @return bool
*/
public function move($destination) public function move($destination)
{ {
return move_uploaded_file($this->tmpName, $destination); return move_uploaded_file($this->tmpName, $destination);
} }
/**
* Get file contents
*
* @return string
*/
public function getContents() public function getContents()
{ {
return file_get_contents($this->tmpName); return file_get_contents($this->tmpName);
} }
public function setValue($value) /**
{ * Return true if an upload error occured.
$this->value = $value; *
* @return bool
return $this; */
}
public function hasError() public function hasError()
{ {
return ($this->getError() !== 0); return ($this->getError() !== 0);
} }
/** /**
* Get upload-error code.
*
* @return string * @return string
*/ */
public function getError() public function getError()
@@ -152,6 +221,7 @@ class InputFile implements IInputItem
/** /**
* Set error * Set error
*
* @param int $error * @param int $error
* @return static $this * @return static $this
*/ */
@@ -162,27 +232,6 @@ class InputFile implements IInputItem
return $this; return $this;
} }
public function toArray()
{
return [
'tmp_name' => $this->tmpName,
'type' => $this->type,
'size' => $this->size,
'name' => $this->name,
'error' => $this->error,
];
}
public function __toString()
{
return $this->getValue();
}
public function getValue()
{
return $this->getTmpName();
}
/** /**
* @return string * @return string
*/ */
@@ -202,4 +251,21 @@ class InputFile implements IInputItem
return $this; return $this;
} }
public function __toString()
{
return $this->getTmpName();
}
public function toArray()
{
return [
'tmp_name' => $this->tmpName,
'type' => $this->type,
'size' => $this->size,
'name' => $this->filename,
'error' => $this->error,
];
}
} }
+1
View File
@@ -75,4 +75,5 @@ class InputItem implements IInputItem
{ {
return (string)$this->value; return (string)$this->value;
} }
} }
@@ -58,7 +58,7 @@ class BaseCsrfVerifier implements IMiddleware
public function handle(Request $request, ILoadableRoute &$route = null) public function handle(Request $request, ILoadableRoute &$route = null)
{ {
if (in_array($request->getMethod(), ['post', 'put', 'delete']) === true && $this->skip($request) === false) { if ($this->skip($request) === false && in_array($request->getMethod(), ['post', 'put', 'delete']) === true) {
$token = $request->getInput()->get(static::POST_KEY, null, 'post'); $token = $request->getInput()->get(static::POST_KEY, null, 'post');
@@ -77,7 +77,7 @@ class BaseCsrfVerifier implements IMiddleware
public function generateToken() public function generateToken()
{ {
$token = $this->csrfToken->generateToken(); $token = CsrfToken::generateToken();
$this->csrfToken->setToken($token); $this->csrfToken->setToken($token);
return $token; return $token;
@@ -85,7 +85,7 @@ class BaseCsrfVerifier implements IMiddleware
public function hasToken() public function hasToken()
{ {
if ($this->token != null) { if ($this->token !== null) {
return true; return true;
} }
+10 -9
View File
@@ -15,10 +15,10 @@ class Request
public function __construct() public function __construct()
{ {
$this->parseHeaders(); $this->parseHeaders();
$this->host = $this->getHeader('http-host');; $this->host = $this->getHeader('http-host');
$this->uri = $this->getHeader('request-uri'); $this->uri = $this->getHeader('request-uri');
$this->input = new Input($this); $this->input = new Input($this);
$this->method = strtolower($this->input->get('_method', $this->getHeader('request-method'))); $this->method = strtolower($this->input->get('_method', $this->getHeader('request-method'), 'post'));
} }
protected function parseHeaders() protected function parseHeaders()
@@ -40,11 +40,7 @@ class Request
public function isSecure() public function isSecure()
{ {
if ($this->getHeader('http-x-forwarded-proto') === 'https' || $this->getHeader('https') !== null || $this->getHeader('server-port') === 443) { return $this->getHeader('http-x-forwarded-proto') === 'https' || $this->getHeader('https') !== null || $this->getHeader('server-port') === 443;
return true;
}
return false;
} }
/** /**
@@ -108,7 +104,7 @@ class Request
return $this->getHeader('http-cf-connecting-ip'); return $this->getHeader('http-cf-connecting-ip');
} }
if ($this->getHeader('http-x-forwarded-for') !== null && strlen($this->getHeader('http-x-forwarded-for'))) { if ($this->getHeader('http-x-forwarded-for') !== null) {
return $this->getHeader('http-x-forwarded_for'); return $this->getHeader('http-x-forwarded_for');
} }
@@ -137,7 +133,7 @@ class Request
* Get header value by name * Get header value by name
* *
* @param string $name * @param string $name
* @param object|null $defaultValue * @param string|null $defaultValue
* *
* @return string|null * @return string|null
*/ */
@@ -217,6 +213,11 @@ class Request
$this->method = $method; $this->method = $method;
} }
public function __isset($name)
{
return $this->data[$name] ?? null;
}
public function __set($name, $value = null) public function __set($name, $value = null)
{ {
$this->data[$name] = $value; $this->data[$name] = $value;
+4 -5
View File
@@ -64,14 +64,14 @@ class Response
$this->headers([ $this->headers([
'Cache-Control: public', 'Cache-Control: public',
'Last-Modified: ' . gmdate("D, d M Y H:i:s", $lastModified) . ' GMT', 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT',
'Etag: ' . $eTag, 'Etag: ' . $eTag,
]); ]);
$httpModified = $this->request->getHeader('http-if-modified-since'); $httpModified = $this->request->getHeader('http-if-modified-since');
$httpIfNoneMatch = $this->request->getHeader('http-if-none-match'); $httpIfNoneMatch = $this->request->getHeader('http-if-none-match');
if ($httpModified !== null && strtotime($httpModified) == $lastModified || $httpIfNoneMatch !== null && $httpIfNoneMatch === $eTag) { if (($httpIfNoneMatch !== null && $httpIfNoneMatch === $eTag) || ($httpModified !== null && strtotime($httpModified) === $lastModified)) {
$this->header('HTTP/1.1 304 Not Modified'); $this->header('HTTP/1.1 304 Not Modified');
@@ -111,9 +111,8 @@ class Response
*/ */
public function headers(array $headers) public function headers(array $headers)
{ {
$max = count($headers); foreach ($headers as $header) {
for ($i = 0; $i < $max; $i++) { $this->header($header);
$this->header($headers[$i]);
} }
return $this; return $this;
@@ -22,7 +22,7 @@ interface ILoadableRoute extends IRoute
* @param Request $request * @param Request $request
* @param ILoadableRoute $route * @param ILoadableRoute $route
*/ */
public function loadMiddleware(Request $request, ILoadableRoute &$route); public function loadMiddleware(Request $request, ILoadableRoute $route);
public function getUrl(); public function getUrl();
+1 -1
View File
@@ -18,7 +18,7 @@ interface IRoute
* Returns class to be rendered. * Returns class to be rendered.
* *
* @param Request $request * @param Request $request
* @return object * @return \Closure|string
*/ */
public function renderRoute(Request $request); public function renderRoute(Request $request);
@@ -9,7 +9,14 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
{ {
const PARAMETERS_REGEX_MATCH = '%s([\w\-\_]*?)\%s{0,1}%s'; const PARAMETERS_REGEX_MATCH = '%s([\w\-\_]*?)\%s{0,1}%s';
/**
* @var
*/
protected $url; protected $url;
/**
* @var string
*/
protected $name; protected $name;
/** /**
@@ -19,7 +26,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
* @param ILoadableRoute $route * @param ILoadableRoute $route
* @throws HttpException * @throws HttpException
*/ */
public function loadMiddleware(Request $request, ILoadableRoute &$route) public function loadMiddleware(Request $request, ILoadableRoute $route)
{ {
if (count($this->getMiddlewares()) > 0) { if (count($this->getMiddlewares()) > 0) {
@@ -114,7 +121,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
$param = $keys[$i]; $param = $keys[$i];
$value = $params[$param]; $value = $params[$param];
$value = (isset($parameters[$param])) ? $parameters[$param] : $value; $value = isset($parameters[$param]) ? $parameters[$param] : $value;
if (stripos($url, $param1) !== false || stripos($url, $param) !== false) { if (stripos($url, $param1) !== false || stripos($url, $param) !== false) {
$url = str_ireplace([sprintf($param1, $param), sprintf($param2, $param)], $value, $url); $url = str_ireplace([sprintf($param1, $param), sprintf($param2, $param)], $value, $url);
+9 -6
View File
@@ -86,7 +86,7 @@ abstract class Route implements IRoute
if ($character === '{') { if ($character === '{') {
/* Remove "/" and "\" from regex */ /* Remove "/" and "\" from regex */
if (substr($regex, strlen($regex) - 1) === '/') { if (substr($regex, strlen($regex) - 1) === '/') {
$regex = substr($regex, 0, strlen($regex) - 2); $regex = substr($regex, 0, -2);
} }
$isParameter = true; $isParameter = true;
@@ -99,7 +99,7 @@ abstract class Route implements IRoute
} }
if ($lastCharacter === '?') { if ($lastCharacter === '?') {
$parameter = substr($parameter, 0, strlen($parameter) - 1); $parameter = substr($parameter, 0, -1);
$regex .= '(?:\/?(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?)?'; $regex .= '(?:\/?(?P<' . $parameter . '>' . $parameterRegex . ')[^\/]?)?';
$required = false; $required = false;
} else { } else {
@@ -138,11 +138,11 @@ abstract class Route implements IRoute
$parameterValue = isset($parameterValues[$name['name']]) ? $parameterValues[$name['name']] : null; $parameterValue = isset($parameterValues[$name['name']]) ? $parameterValues[$name['name']] : null;
if ($name['required'] && $parameterValue === null) { if ($parameterValue === null && $name['required']) {
throw new HttpException('Missing required parameter ' . $name['name'], 404); throw new HttpException('Missing required parameter ' . $name['name'], 404);
} }
if ($name['required'] === false && $parameterValue === null) { if ($parameterValue === null && $name['required'] === false) {
continue; continue;
} }
@@ -384,10 +384,13 @@ abstract class Route implements IRoute
} }
if (count($this->parameters) > 0) { if (count($this->parameters) > 0) {
/* Ensure the right order + values */ /* Ensure the right order + values */
$parameters = ($values['parameters'] + $this->parameters); $parameters = (isset($values['parameters']) ? $values['parameters'] : []) + $this->parameters;
$parameters = array_merge($parameters, $this->parameters); $parameters = array_merge($parameters, $this->parameters);
$this->setParameters($parameters); $this->setParameters($parameters);
$values['parameters'] = $parameters;
} }
if (count($this->middlewares) > 0) { if (count($this->middlewares) > 0) {
@@ -406,7 +409,7 @@ abstract class Route implements IRoute
*/ */
public function setSettings(array $values, $merge = false) public function setSettings(array $values, $merge = false)
{ {
if (isset($values['namespace']) && $this->namespace === null) { if ($this->namespace === null && isset($values['namespace'])) {
$this->setNamespace($values['namespace']); $this->setNamespace($values['namespace']);
} }
@@ -31,11 +31,11 @@ class RouteController extends LoadableRoute implements IControllerRoute
} }
/* Remove method/type */ /* Remove method/type */
if (stripos($name, '.') !== false) { if (strpos($name, '.') !== false) {
$method = substr($name, strrpos($name, '.') + 1); $method = substr($name, strrpos($name, '.') + 1);
$newName = substr($name, 0, strrpos($name, '.')); $newName = substr($name, 0, strrpos($name, '.'));
if (strtolower($this->name) === strtolower($newName) && in_array($method, $this->names)) { if (in_array($method, $this->names) === true && strtolower($this->name) === strtolower($newName)) {
return true; return true;
} }
} }
@@ -43,10 +43,15 @@ class RouteController extends LoadableRoute implements IControllerRoute
return parent::hasName($name); return parent::hasName($name);
} }
/**
* @param string|null $method
* @param string|array|null $parameters
* @param string|null $name
* @return string
*/
public function findUrl($method = null, $parameters = null, $name = null) public function findUrl($method = null, $parameters = null, $name = null)
{ {
if (strpos($name, '.') !== false) {
if (stripos($name, '.') !== false) {
$found = array_search(substr($name, strrpos($name, '.') + 1), $this->names); $found = array_search(substr($name, strrpos($name, '.') + 1), $this->names);
if ($found !== false) { if ($found !== false) {
$method = $found; $method = $found;
@@ -54,7 +59,6 @@ class RouteController extends LoadableRoute implements IControllerRoute
} }
$url = ''; $url = '';
$parameters = (array)$parameters; $parameters = (array)$parameters;
/* Remove requestType from method-name, if it exists */ /* Remove requestType from method-name, if it exists */
@@ -115,7 +119,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH); $url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
$url = rtrim($url, '/') . '/'; $url = rtrim($url, '/') . '/';
if (strtolower($url) == strtolower($this->url) || stripos($url, $this->url) === 0) { if (stripos($url, $this->url) === 0 && strtolower($url) === strtolower($this->url)) {
$strippedUrl = trim(str_ireplace($this->url, '/', $url), '/'); $strippedUrl = trim(str_ireplace($this->url, '/', $url), '/');
@@ -127,6 +131,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
$this->method = $method; $this->method = $method;
array_shift($path); array_shift($path);
$this->parameters = $path; $this->parameters = $path;
// Set callback // Set callback
+2 -2
View File
@@ -27,8 +27,8 @@ class RouteGroup extends Route implements IGroupRoute
$domain = $this->domains[$i]; $domain = $this->domains[$i];
$parameters = $this->parseParameters($domain, $request->getHost(), '.*'); $parameters = $this->parseParameters($domain, $request->getHost(), '.*');
if ($parameters !== null) { if ($parameters !== null && count($parameters) > 0) {
$this->parameters = $parameters; $this->parameters = array_merge($this->parameters, $parameters);
return true; return true;
} }
+51 -13
View File
@@ -15,6 +15,17 @@ class RouteResource extends LoadableRoute implements IControllerRoute
'update' => '', 'update' => '',
'destroy' => '', 'destroy' => '',
]; ];
protected $methodNames = [
'index' => 'index',
'create' => 'create',
'store' => 'store',
'show' => 'show',
'edit' => 'edit',
'update' => 'update',
'destroy' => 'destroy',
];
protected $names = []; protected $names = [];
protected $controller; protected $controller;
@@ -42,7 +53,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute
} }
/* Remove method/type */ /* Remove method/type */
if (stripos($name, '.') !== false) { if (strpos($name, '.') !== false) {
$name = substr($name, 0, strrpos($name, '.')); $name = substr($name, 0, strrpos($name, '.'));
} }
@@ -51,7 +62,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute
public function findUrl($method = null, $parameters = null, $name = null) public function findUrl($method = null, $parameters = null, $name = null)
{ {
$method = array_search($name, $this->names); $method = array_search($name, $this->names, false);
if ($method !== false) { if ($method !== false) {
return rtrim($this->url . $this->urls[$method], '/') . '/'; return rtrim($this->url . $this->urls[$method], '/') . '/';
} }
@@ -110,37 +121,37 @@ class RouteResource extends LoadableRoute implements IControllerRoute
$method = $request->getMethod(); $method = $request->getMethod();
// Delete // Delete
if (isset($parameters['id']) && $method === static::REQUEST_TYPE_DELETE) { if ($method === static::REQUEST_TYPE_DELETE && isset($parameters['id'])) {
return $this->call('destroy', $parameters); return $this->call($this->methodNames['destroy'], $parameters);
} }
// Update // Update
if (isset($parameters['id']) && in_array($method, [static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT])) { if (isset($parameters['id']) && in_array($method, [static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT])) {
return $this->call('update', $parameters); return $this->call($this->methodNames['update'], $parameters);
} }
// Edit // Edit
if (isset($parameters['id']) && strtolower($action) === 'edit' && $method === static::REQUEST_TYPE_GET) { if ($method === static::REQUEST_TYPE_GET && isset($parameters['id']) && strtolower($action) === 'edit') {
return $this->call('edit', $parameters); return $this->call($this->methodNames['edit'], $parameters);
} }
// Create // Create
if (strtolower($action) === 'create' && $method === static::REQUEST_TYPE_GET) { if ($method === static::REQUEST_TYPE_GET && strtolower($action) === 'create') {
return $this->call('create', $parameters); return $this->call($this->methodNames['create'], $parameters);
} }
// Save // Save
if ($method === static::REQUEST_TYPE_POST) { if ($method === static::REQUEST_TYPE_POST) {
return $this->call('store', $parameters); return $this->call($this->methodNames['store'], $parameters);
} }
// Show // Show
if (isset($parameters['id']) && $method === static::REQUEST_TYPE_GET) { if ($method === static::REQUEST_TYPE_GET && isset($parameters['id'])) {
return $this->call('show', $parameters); return $this->call($this->methodNames['show'], $parameters);
} }
// Index // Index
return $this->call('index', $parameters); return $this->call($this->methodNames['index'], $parameters);
} }
return null; return null;
@@ -182,6 +193,29 @@ class RouteResource extends LoadableRoute implements IControllerRoute
return $this; return $this;
} }
/**
* Define custom method name for resource controller
*
* @param array $names
* @return static $this
*/
public function setMethodNames(array $names)
{
$this->methodNames = $names;
return $this;
}
/**
* Get method names
*
* @return array $this
*/
public function getMethodNames()
{
return $this->methodNames;
}
/** /**
* Merge with information from another route. * Merge with information from another route.
* *
@@ -195,6 +229,10 @@ class RouteResource extends LoadableRoute implements IControllerRoute
$this->names = $values['names']; $this->names = $values['names'];
} }
if (isset($values['methods'])) {
$this->methodNames = $values['methods'];
}
parent::setSettings($values, $merge); parent::setSettings($values, $merge);
return $this; return $this;
+21 -9
View File
@@ -100,7 +100,7 @@ class Router
return static::$instance; return static::$instance;
} }
public function __construct() protected function __construct()
{ {
$this->reset(); $this->reset();
} }
@@ -137,16 +137,26 @@ class Router
return $route; return $route;
} }
/**
* Process added routes.
*
* @param array $routes
* @param IGroupRoute|null $group
* @param IRoute|null $parent
*/
protected function processRoutes(array $routes, IGroupRoute $group = null, IRoute $parent = null) protected function processRoutes(array $routes, IGroupRoute $group = null, IRoute $parent = null)
{ {
// Loop through each route-request // Loop through each route-request
$max = count($routes) - 1; $max = count($routes) - 1;
$exceptionHandlers = [];
/* @var $route IRoute */ /* @var $route IRoute */
for ($i = $max; $i >= 0; $i--) { for ($i = $max; $i >= 0; $i--) {
$route = $routes[$i]; $route = $routes[$i];
/* @var $route IGroupRoute */
if ($route instanceof IGroupRoute) { if ($route instanceof IGroupRoute) {
$group = $route; $group = $route;
@@ -159,9 +169,9 @@ class Router
if ($route->matchRoute($this->request)) { if ($route->matchRoute($this->request)) {
/* Add exceptionhandlers */ /* Add exception handlers */
if (count($route->getExceptionHandlers()) > 0) { if (count($route->getExceptionHandlers()) > 0) {
$this->exceptionHandlers = array_merge($route->getExceptionHandlers(), $this->exceptionHandlers); $exceptionHandlers += $route->getExceptionHandlers();
} }
} }
@@ -172,7 +182,6 @@ class Router
/* Add the parent group */ /* Add the parent group */
$route->setGroup($group); $route->setGroup($group);
} }
if ($parent !== null) { if ($parent !== null) {
@@ -201,6 +210,8 @@ class Router
$this->processRoutes($stack, $route, $group); $this->processRoutes($stack, $route, $group);
} }
} }
$this->exceptionHandlers = array_unique(array_merge($exceptionHandlers, $this->exceptionHandlers));
} }
public function routeRequest($rewrite = false) public function routeRequest($rewrite = false)
@@ -253,7 +264,7 @@ class Router
if ($route->matchRoute($this->request)) { if ($route->matchRoute($this->request)) {
/* Check if request method matches */ /* Check if request method matches */
if (count($route->getRequestMethods()) > 0 && !in_array($this->request->getMethod(), $route->getRequestMethods())) { if (count($route->getRequestMethods()) > 0 && in_array($this->request->getMethod(), $route->getRequestMethods()) === false) {
$routeNotAllowed = true; $routeNotAllowed = true;
continue; continue;
} }
@@ -262,7 +273,7 @@ class Router
$this->loadedRoute->loadMiddleware($this->request, $this->loadedRoute); $this->loadedRoute->loadMiddleware($this->request, $this->loadedRoute);
/* If the request has changed, we reinitialize the router */ /* If the request has changed, we reinitialize the router */
if ($this->request->getUri() !== $this->originalUrl && !in_array($this->request->getUri(), $this->routeRewrites)) { if ($this->request->getUri() !== $this->originalUrl && in_array($this->request->getUri(), $this->routeRewrites) === false) {
$this->routeRewrites[] = $this->request->getUri(); $this->routeRewrites[] = $this->request->getUri();
$this->routeRequest(true); $this->routeRequest(true);
@@ -309,7 +320,7 @@ class Router
$request = $handler->handleError($this->request, $this->loadedRoute, $e); $request = $handler->handleError($this->request, $this->loadedRoute, $e);
/* If the request has changed */ /* If the request has changed */
if ($request !== null && $this->request->getUri() !== $this->originalUrl && !in_array($request->getUri(), $this->routeRewrites)) { if ($request !== null && $this->request->getUri() !== $this->originalUrl && in_array($request->getUri(), $this->routeRewrites) === false) {
$this->request = $request; $this->request = $request;
$this->routeRewrites[] = $request->getUri(); $this->routeRewrites[] = $request->getUri();
$this->routeRequest(true); $this->routeRequest(true);
@@ -375,7 +386,7 @@ class Router
if (strpos($name, '@') !== false && strpos($route->getCallback(), '@') !== false && !is_callable($route->getCallback())) { if (strpos($name, '@') !== false && strpos($route->getCallback(), '@') !== false && !is_callable($route->getCallback())) {
/* Check if the entire callback is matching */ /* Check if the entire callback is matching */
if (strtolower($route->getCallback()) === strtolower($name) || strpos($route->getCallback(), $name) === 0) { if (strpos($route->getCallback(), $name) === 0 || strtolower($route->getCallback()) === strtolower($name)) {
return $route; return $route;
} }
@@ -404,6 +415,7 @@ class Router
* @param string|null $name * @param string|null $name
* @param string|array|null $parameters * @param string|array|null $parameters
* @param array|null $getParams * @param array|null $getParams
* @throws \InvalidArgumentException
* @return string * @return string
*/ */
public function getUrl($name = null, $parameters = null, $getParams = null) public function getUrl($name = null, $parameters = null, $getParams = null)
@@ -439,7 +451,7 @@ class Router
} }
/* Using @ is most definitely a controller@method or alias@method */ /* Using @ is most definitely a controller@method or alias@method */
if (stripos($name, '@') !== false) { if (strpos($name, '@') !== false) {
list($controller, $method) = explode('@', $name); list($controller, $method) = explode('@', $name);
/* Loop through all the routes to see if we can find a match */ /* Loop through all the routes to see if we can find a match */
+1
View File
@@ -309,6 +309,7 @@ class SimpleRouter
* @param string|null $name * @param string|null $name
* @param string|array|null $parameters * @param string|array|null $parameters
* @param array|null $getParams * @param array|null $getParams
* @throws \Exception
* @return string * @return string
*/ */
public static function getUrl($name = null, $parameters = null, $getParams = null) public static function getUrl($name = null, $parameters = null, $getParams = null)
@@ -0,0 +1,4 @@
<?php
class ExceptionHandlerException extends \Exception
{
}
+1 -1
View File
@@ -4,7 +4,7 @@ class ExceptionHandler implements \Pecee\Handlers\IExceptionHandler
{ {
public function handleError(\Pecee\Http\Request $request, \Pecee\SimpleRouter\Route\ILoadableRoute &$route = null, \Exception $error) public function handleError(\Pecee\Http\Request $request, \Pecee\SimpleRouter\Route\ILoadableRoute &$route = null, \Exception $error)
{ {
throw $error; echo $error->getMessage();
} }
} }
@@ -0,0 +1,13 @@
<?php
class TestExceptionHandlerFirst implements \Pecee\Handlers\IExceptionHandler
{
public function handleError(\Pecee\Http\Request $request, \Pecee\SimpleRouter\Route\ILoadableRoute &$route = null, \Exception $error)
{
echo 'ExceptionHandler 1 loaded' . chr(10);
$request->setUri('/');
return $request;
}
}
@@ -0,0 +1,13 @@
<?php
class TestExceptionHandlerSecond implements \Pecee\Handlers\IExceptionHandler
{
public function handleError(\Pecee\Http\Request $request, \Pecee\SimpleRouter\Route\ILoadableRoute &$route = null, \Exception $error)
{
echo 'ExceptionHandler 2 loaded' . chr(10);
$request->setUri('/');
return $request;
}
}
@@ -0,0 +1,12 @@
<?php
class TestExceptionHandlerThird implements \Pecee\Handlers\IExceptionHandler
{
public function handleError(\Pecee\Http\Request $request, \Pecee\SimpleRouter\Route\ILoadableRoute &$route = null, \Exception $error)
{
echo 'ExceptionHandler 3 loaded' . chr(10);
throw new ExceptionHandlerException('All good!', 666);
}
}
+57 -57
View File
@@ -7,89 +7,89 @@ use Pecee\SimpleRouter\SimpleRouter as SimpleRouter;
class GroupTest extends PHPUnit_Framework_TestCase class GroupTest extends PHPUnit_Framework_TestCase
{ {
protected $result; protected $result;
public function testGroupLoad() public function testGroupLoad()
{ {
$this->result = false; $this->result = false;
SimpleRouter::group(['prefix' => '/group'], function () { SimpleRouter::group(['prefix' => '/group'], function () {
$this->result = true; $this->result = true;
}); });
try { try {
SimpleRouter::start(); SimpleRouter::start();
} catch (Exception $e) { } catch (Exception $e) {
// ignore RouteNotFound exception // ignore RouteNotFound exception
} }
$this->assertTrue($this->result); $this->assertTrue($this->result);
} }
public function testNestedGroup() public function testNestedGroup()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setUri('/api/v1/test'); SimpleRouter::request()->setUri('/api/v1/test');
SimpleRouter::request()->setMethod('get'); SimpleRouter::request()->setMethod('get');
SimpleRouter::group(['prefix' => '/api'], function () { SimpleRouter::group(['prefix' => '/api'], function () {
SimpleRouter::group(['prefix' => '/v1'], function () { SimpleRouter::group(['prefix' => '/v1'], function () {
SimpleRouter::get('/test', 'DummyController@start'); SimpleRouter::get('/test', 'DummyController@start');
}); });
}); });
SimpleRouter::start(); SimpleRouter::start();
} }
public function testManyRoutes() public function testManyRoutes()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setUri('/my/match'); SimpleRouter::request()->setUri('/my/match');
SimpleRouter::request()->setMethod('get'); SimpleRouter::request()->setMethod('get');
SimpleRouter::group(['prefix' => '/api'], function () { SimpleRouter::group(['prefix' => '/api'], function () {
SimpleRouter::group(['prefix' => '/v1'], function () { SimpleRouter::group(['prefix' => '/v1'], function () {
SimpleRouter::get('/test', 'DummyController@start'); SimpleRouter::get('/test', 'DummyController@start');
}); });
}); });
SimpleRouter::get('/my/match', 'DummyController@start'); SimpleRouter::get('/my/match', 'DummyController@start');
SimpleRouter::group(['prefix' => '/service'], function () { SimpleRouter::group(['prefix' => '/service'], function () {
SimpleRouter::group(['prefix' => '/v1'], function () { SimpleRouter::group(['prefix' => '/v1'], function () {
SimpleRouter::get('/no-match', 'DummyController@start'); SimpleRouter::get('/no-match', 'DummyController@start');
}); });
}); });
SimpleRouter::start(); SimpleRouter::start();
} }
public function testUrls() public function testUrls()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setUri('/my/fancy/url/1'); SimpleRouter::request()->setUri('/my/fancy/url/1');
SimpleRouter::request()->setMethod('get'); SimpleRouter::request()->setMethod('get');
// Test array name // Test array name
SimpleRouter::get('/my/fancy/url/1', 'DummyController@start', ['as' => 'fancy1']); SimpleRouter::get('/my/fancy/url/1', 'DummyController@start', ['as' => 'fancy1']);
// Test method name // Test method name
SimpleRouter::get('/my/fancy/url/2', 'DummyController@start')->setName('fancy2'); SimpleRouter::get('/my/fancy/url/2', 'DummyController@start')->setName('fancy2');
SimpleRouter::start(); SimpleRouter::start();
$this->assertEquals('/my/fancy/url/1/', SimpleRouter::getUrl('fancy1')); $this->assertEquals('/my/fancy/url/1/', SimpleRouter::getUrl('fancy1'));
$this->assertEquals('/my/fancy/url/2/', SimpleRouter::getUrl('fancy2')); $this->assertEquals('/my/fancy/url/2/', SimpleRouter::getUrl('fancy2'));
} }
} }
+25 -16
View File
@@ -8,25 +8,34 @@ use Pecee\SimpleRouter\SimpleRouter as SimpleRouter;
class MiddlewareTest extends PHPUnit_Framework_TestCase class MiddlewareTest extends PHPUnit_Framework_TestCase
{ {
public function testMiddlewareFound() public function testMiddlewareFound()
{ {
SimpleRouter::router()->reset(); $this->setExpectedException('MiddlewareLoadedException');
SimpleRouter::request()->setMethod('get');
SimpleRouter::request()->setUri('/my/test/url');
SimpleRouter::group(['exceptionHandler' => 'ExceptionHandler'], function () { SimpleRouter::router()->reset();
SimpleRouter::get('/my/test/url', 'DummyController@start', ['middleware' => 'DummyMiddleware']); SimpleRouter::request()->setMethod('get');
}); SimpleRouter::request()->setUri('/my/test/url');
$found = false; SimpleRouter::group(['exceptionHandler' => 'ExceptionHandler'], function () {
SimpleRouter::get('/my/test/url', 'DummyController@start', ['middleware' => 'DummyMiddleware']);
});
try { SimpleRouter::start();
SimpleRouter::start(); }
} catch (\Exception $e) {
$found = ($e instanceof MiddlewareLoadedException);
}
$this->assertTrue($found); public function testNestedMiddlewareLoad()
} {
$this->setExpectedException('MiddlewareLoadedException');
SimpleRouter::router()->reset();
SimpleRouter::request()->setMethod('get');
SimpleRouter::request()->setUri('/my/test/url');
SimpleRouter::group(['exceptionHandler' => 'ExceptionHandler', 'middleware' => 'DummyMiddleware'], function () {
SimpleRouter::get('/my/test/url', 'DummyController@start');
});
SimpleRouter::start();
}
} }
+123 -102
View File
@@ -2,140 +2,161 @@
require_once 'Dummy/DummyMiddleware.php'; require_once 'Dummy/DummyMiddleware.php';
require_once 'Dummy/DummyController.php'; require_once 'Dummy/DummyController.php';
require_once 'Dummy/Handler/ExceptionHandler.php'; require_once 'Dummy/Exceptions/ExceptionHandlerException.php';
require_once 'Dummy/Handler/TestExceptionHandlerFirst.php';
require_once 'Dummy/Handler/TestExceptionHandlerSecond.php';
require_once 'Dummy/Handler/TestExceptionHandlerThird.php';
use Pecee\SimpleRouter\SimpleRouter as SimpleRouter;
use Pecee\SimpleRouter\Exceptions\NotFoundHttpException as NotFoundHttpException; use Pecee\SimpleRouter\Exceptions\NotFoundHttpException as NotFoundHttpException;
use Pecee\SimpleRouter\SimpleRouter as SimpleRouter;
class RouterRouteTest extends PHPUnit_Framework_TestCase class RouterRouteTest extends PHPUnit_Framework_TestCase
{ {
protected $result = false; protected $result = false;
public function testNotFound() /**
{ * Redirects to another route through 3 exception handlers.
SimpleRouter::router()->reset(); *
SimpleRouter::request()->setMethod('get'); * You will see "ExceptionHandler 1 loaded" 2 times. This happen because
SimpleRouter::request()->setUri('/test-param1-param2'); * the exceptionhandler is asking the router to reload.
*
* That means that the exceptionhandler is loaded again, but this time
* the router ignores the same rewrite-route to avoid loop - loads
* the second which have same behavior and is also ignored before
* throwing the final Exception in ExceptionHandler 3.
*
* So this tests:
* 1. If ExceptionHandlers loads
* 2. If ExceptionHandlers load in the correct order
* 3. If ExceptionHandlers can rewrite the page on error
* 4. If the router can avoid redirect-loop due to developer has started loop.
* 5. And finally if we reaches the last exception-handler and that the correct
* exception-type is being thrown.
*/
public function testNotFound()
{
$this->setExpectedException('ExceptionHandlerException');
SimpleRouter::group(['exceptionHandler' => 'ExceptionHandler'], function () { SimpleRouter::router()->reset();
SimpleRouter::get('/non-existing-path', 'DummyController@start'); SimpleRouter::request()->setMethod('get');
}); SimpleRouter::request()->setUri('/test-param1-param2');
$found = false; SimpleRouter::group(['exceptionHandler' => ['TestExceptionHandlerFirst', 'TestExceptionHandlerSecond']], function () {
try { SimpleRouter::group(['exceptionHandler' => 'TestExceptionHandlerThird'], function () {
SimpleRouter::start();
} catch (\Exception $e) {
$found = ($e instanceof NotFoundHttpException && $e->getCode() == 404);
}
$this->assertTrue($found); SimpleRouter::get('/non-existing-path', 'DummyController@start');
}
public function testGet() });
{ });
SimpleRouter::router()->reset();
SimpleRouter::request()->setUri('/my/test/url');
SimpleRouter::request()->setMethod('get');
SimpleRouter::get('/my/test/url', 'DummyController@start'); SimpleRouter::start();
SimpleRouter::start(); }
}
public function testPost() public function testGet()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setUri('/my/test/url'); SimpleRouter::request()->setUri('/my/test/url');
SimpleRouter::request()->setMethod('post'); SimpleRouter::request()->setMethod('get');
SimpleRouter::post('/my/test/url', 'DummyController@start'); SimpleRouter::get('/my/test/url', 'DummyController@start');
SimpleRouter::start(); SimpleRouter::start();
} }
public function testPut() public function testPost()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setUri('/my/test/url'); SimpleRouter::request()->setUri('/my/test/url');
SimpleRouter::request()->setMethod('put'); SimpleRouter::request()->setMethod('post');
SimpleRouter::put('/my/test/url', 'DummyController@start'); SimpleRouter::post('/my/test/url', 'DummyController@start');
SimpleRouter::start(); SimpleRouter::start();
} }
public function testDelete() public function testPut()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setUri('/my/test/url'); SimpleRouter::request()->setUri('/my/test/url');
SimpleRouter::request()->setMethod('delete'); SimpleRouter::request()->setMethod('put');
SimpleRouter::delete('/my/test/url', 'DummyController@start'); SimpleRouter::put('/my/test/url', 'DummyController@start');
SimpleRouter::start(); SimpleRouter::start();
} }
public function testMethodNotAllowed() public function testDelete()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setUri('/my/test/url'); SimpleRouter::request()->setUri('/my/test/url');
SimpleRouter::request()->setMethod('post'); SimpleRouter::request()->setMethod('delete');
SimpleRouter::get('/my/test/url', 'DummyController@start'); SimpleRouter::delete('/my/test/url', 'DummyController@start');
SimpleRouter::start();
}
try { public function testMethodNotAllowed()
SimpleRouter::start(); {
} catch (\Exception $e) { SimpleRouter::router()->reset();
$this->assertEquals(403, $e->getCode()); SimpleRouter::request()->setUri('/my/test/url');
} SimpleRouter::request()->setMethod('post');
}
public function testSimpleParam() SimpleRouter::get('/my/test/url', 'DummyController@start');
{
SimpleRouter::router()->reset();
SimpleRouter::request()->setMethod('get');
SimpleRouter::request()->setUri('/test-param1');
SimpleRouter::get('/test-{param1}', 'DummyController@param'); try {
SimpleRouter::start(); SimpleRouter::start();
} } catch (\Exception $e) {
$this->assertEquals(403, $e->getCode());
}
}
public function testMultiParam() public function testSimpleParam()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setMethod('get'); SimpleRouter::request()->setMethod('get');
SimpleRouter::request()->setUri('/test-param1-param2'); SimpleRouter::request()->setUri('/test-param1');
SimpleRouter::get('/test-{param1}-{param2}', 'DummyController@param'); SimpleRouter::get('/test-{param1}', 'DummyController@param');
SimpleRouter::start(); SimpleRouter::start();
} }
public function testPathParamRegex() public function testMultiParam()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setMethod('get'); SimpleRouter::request()->setMethod('get');
SimpleRouter::request()->setUri('/test/path/123123'); SimpleRouter::request()->setUri('/test-param1-param2');
SimpleRouter::get('/test/path/{myParam}', 'DummyController@param', ['where' => ['myParam' => '([0-9]+)']]); SimpleRouter::get('/test-{param1}-{param2}', 'DummyController@param');
SimpleRouter::start(); SimpleRouter::start();
} }
public function testDomainRoute() public function testPathParamRegex()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setMethod('get'); SimpleRouter::request()->setMethod('get');
SimpleRouter::request()->setUri('/test'); SimpleRouter::request()->setUri('/test/path/123123');
SimpleRouter::request()->setHost('hello.world.com');
$this->result = false; SimpleRouter::get('/test/path/{myParam}', 'DummyController@param', ['where' => ['myParam' => '([0-9]+)']]);
SimpleRouter::start();
}
SimpleRouter::group(['domain' => '{subdomain}.world.com'], function () { public function testDomainRoute()
SimpleRouter::get('/test', function ($subdomain = null) { {
$this->result = ($subdomain === 'hello'); SimpleRouter::router()->reset();
}); SimpleRouter::request()->setMethod('get');
}); SimpleRouter::request()->setUri('/test');
SimpleRouter::request()->setHost('hello.world.com');
SimpleRouter::start(); $this->result = false;
$this->assertTrue($this->result); SimpleRouter::group(['domain' => '{subdomain}.world.com'], function () {
SimpleRouter::get('/test', function ($subdomain = null) {
$this->result = ($subdomain === 'hello');
});
});
} SimpleRouter::start();
$this->assertTrue($this->result);
}
} }
+59 -58
View File
@@ -8,94 +8,95 @@ use Pecee\SimpleRouter\SimpleRouter as SimpleRouter;
class RouterUrlTest extends PHPUnit_Framework_TestCase class RouterUrlTest extends PHPUnit_Framework_TestCase
{ {
protected $result = false; protected $result = false;
protected function getUrl($name = null, $parameters = null, array $getParams = []) { protected function getUrl($name = null, $parameters = null, array $getParams = [])
return SimpleRouter::getUrl($name, $parameters, $getParams); {
} return SimpleRouter::getUrl($name, $parameters, $getParams);
}
public function testUrls() public function testUrls()
{ {
SimpleRouter::router()->reset(); SimpleRouter::router()->reset();
SimpleRouter::request()->setMethod('get'); SimpleRouter::request()->setMethod('get');
SimpleRouter::request()->setUri('/'); SimpleRouter::request()->setUri('/');
// Match normal route on alias // Match normal route on alias
SimpleRouter::get('/', 'DummyController@silent', ['as' => 'home']); SimpleRouter::get('/', 'DummyController@silent', ['as' => 'home']);
SimpleRouter::get('/about', 'DummyController@about'); SimpleRouter::get('/about', 'DummyController@about');
SimpleRouter::group(['prefix' => '/admin', 'as' => 'admin'], function() { SimpleRouter::group(['prefix' => '/admin', 'as' => 'admin'], function () {
// Match route with prefix on alias // Match route with prefix on alias
SimpleRouter::get('/{id?}', 'DummyController@start', ['as' => 'home']); SimpleRouter::get('/{id?}', 'DummyController@start', ['as' => 'home']);
// Match controller with prefix and alias // Match controller with prefix and alias
SimpleRouter::controller('/users', 'DummyController', ['as' => 'users']); SimpleRouter::controller('/users', 'DummyController', ['as' => 'users']);
// Match controller with prefix and NO alias // Match controller with prefix and NO alias
SimpleRouter::controller('/pages', 'DummyController'); SimpleRouter::controller('/pages', 'DummyController');
}); });
SimpleRouter::group(['prefix' => 'api', 'as' => 'api'], function() { SimpleRouter::group(['prefix' => 'api', 'as' => 'api'], function () {
// Match resource controller // Match resource controller
SimpleRouter::resource('phones', 'DummyController'); SimpleRouter::resource('phones', 'DummyController');
}); });
SimpleRouter::controller('gadgets', 'DummyController', ['names' => ['getIphoneInfo' => 'iphone']]); SimpleRouter::controller('gadgets', 'DummyController', ['names' => ['getIphoneInfo' => 'iphone']]);
// Match controller with no prefix and no alias // Match controller with no prefix and no alias
SimpleRouter::controller('/cats', 'CatsController'); SimpleRouter::controller('/cats', 'CatsController');
// Pretend to load page // Pretend to load page
SimpleRouter::start(); SimpleRouter::start();
$this->assertEquals('/gadgets/iphoneinfo/', $this->getUrl('gadgets.iphone')); $this->assertEquals('/gadgets/iphoneinfo/', $this->getUrl('gadgets.iphone'));
$this->assertEquals('/api/phones/create/', $this->getUrl('api.phones.create')); $this->assertEquals('/api/phones/create/', $this->getUrl('api.phones.create'));
// Should match / // Should match /
$this->assertEquals('/', $this->getUrl('home')); $this->assertEquals('/', $this->getUrl('home'));
// Should match /about/ // Should match /about/
$this->assertEquals('/about/', $this->getUrl('DummyController@about')); $this->assertEquals('/about/', $this->getUrl('DummyController@about'));
// Should match /admin/ // Should match /admin/
$this->assertEquals('/admin/', $this->getUrl('DummyController@start')); $this->assertEquals('/admin/', $this->getUrl('DummyController@start'));
// Should match /admin/ // Should match /admin/
$this->assertEquals('/admin/', $this->getUrl('admin.home')); $this->assertEquals('/admin/', $this->getUrl('admin.home'));
// Should match /admin/2/ // Should match /admin/2/
$this->assertEquals('/admin/2/', $this->getUrl('admin.home', ['id' => 2])); $this->assertEquals('/admin/2/', $this->getUrl('admin.home', ['id' => 2]));
// Should match /admin/users/ // Should match /admin/users/
$this->assertEquals('/admin/users/', $this->getUrl('admin.users')); $this->assertEquals('/admin/users/', $this->getUrl('admin.users'));
// Should match /admin/users/home/ // Should match /admin/users/home/
$this->assertEquals('/admin/users/home/', $this->getUrl('admin.users@home')); $this->assertEquals('/admin/users/home/', $this->getUrl('admin.users@home'));
// Should match /cats/ // Should match /cats/
$this->assertEquals('/cats/', $this->getUrl('CatsController')); $this->assertEquals('/cats/', $this->getUrl('CatsController'));
// Should match /cats/view/ // Should match /cats/view/
$this->assertEquals('/cats/view/', $this->getUrl('CatsController', 'view')); $this->assertEquals('/cats/view/', $this->getUrl('CatsController', 'view'));
// Should match /cats/view/ // Should match /cats/view/
//$this->assertEquals('/cats/view/', $this->getUrl('CatsController', ['view'])); //$this->assertEquals('/cats/view/', $this->getUrl('CatsController', ['view']));
// Should match /cats/view/666 // Should match /cats/view/666
$this->assertEquals('/cats/view/666/', $this->getUrl('CatsController@getView', ['666'])); $this->assertEquals('/cats/view/666/', $this->getUrl('CatsController@getView', ['666']));
// Should match /funny/man/ // Should match /funny/man/
$this->assertEquals('/funny/man/', $this->getUrl('/funny/man')); $this->assertEquals('/funny/man/', $this->getUrl('/funny/man'));
// Should match /?jackdaniels=true&cola=yeah // Should match /?jackdaniels=true&cola=yeah
$this->assertEquals('/?jackdaniels=true&cola=yeah', $this->getUrl('home', null, ['jackdaniels' => 'true', 'cola' => 'yeah'])); $this->assertEquals('/?jackdaniels=true&cola=yeah', $this->getUrl('home', null, ['jackdaniels' => 'true', 'cola' => 'yeah']));
} }
} }