Added router
This commit is contained in:
parent
b7de8ae0bf
commit
1e3e3f94d8
3 changed files with 194 additions and 0 deletions
48
src/Route.php
Normal file
48
src/Route.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
namespace Szurubooru;
|
||||||
|
|
||||||
|
final class Route
|
||||||
|
{
|
||||||
|
public $query;
|
||||||
|
public $route;
|
||||||
|
|
||||||
|
public function __construct($query, $route)
|
||||||
|
{
|
||||||
|
$this->query = $query;
|
||||||
|
$this->route = $route;
|
||||||
|
$this->regex = $this->getRegex();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle($query)
|
||||||
|
{
|
||||||
|
$query = trim($query, '/');
|
||||||
|
if (!preg_match($this->regex, $query, $matches))
|
||||||
|
return false;
|
||||||
|
$routeArguments = $this->getRouteArguments($matches);
|
||||||
|
call_user_func_array($this->route, $routeArguments);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRegex()
|
||||||
|
{
|
||||||
|
$quotedQuery = preg_quote(trim($this->query, '/'), '/');
|
||||||
|
return '/^' . preg_replace('/\\\?\:([a-zA-Z_-]*)/', '(?P<\1>[^\/]+)', $quotedQuery) . '$/i';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRouteArguments($matches)
|
||||||
|
{
|
||||||
|
$reflectionFunction = new \ReflectionFunction($this->route);
|
||||||
|
$arguments = [];
|
||||||
|
foreach ($reflectionFunction->getParameters() as $reflectionParameter)
|
||||||
|
{
|
||||||
|
$key = $reflectionParameter->name;
|
||||||
|
if (isset($matches[$key]))
|
||||||
|
$arguments[$key] = $matches[$key];
|
||||||
|
elseif ($reflectionParameter->isDefaultValueAvailable())
|
||||||
|
$arguments[$key] = $reflectionParameter->getDefaultValue();
|
||||||
|
else
|
||||||
|
$arguments[$key] = null;
|
||||||
|
}
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
}
|
46
src/Router.php
Normal file
46
src/Router.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
namespace Szurubooru;
|
||||||
|
|
||||||
|
final class Router
|
||||||
|
{
|
||||||
|
private $routes;
|
||||||
|
|
||||||
|
public function get($query, $route)
|
||||||
|
{
|
||||||
|
$this->route('GET', $query, $route);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function put($query, $route)
|
||||||
|
{
|
||||||
|
$this->route('PUT', $query, $route);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($query, $route)
|
||||||
|
{
|
||||||
|
$this->route('DELETE', $query, $route);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function post($query, $route)
|
||||||
|
{
|
||||||
|
$this->route('POST', $query, $route);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function route($method, $query, $route)
|
||||||
|
{
|
||||||
|
$this->routes[$method] []= new Route($query, $route);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle($method, $request)
|
||||||
|
{
|
||||||
|
if (!isset($this->routes[$method]))
|
||||||
|
throw new \DomainException('Unhandled request method: ' . $method);
|
||||||
|
|
||||||
|
foreach ($this->routes[$method] as $route)
|
||||||
|
{
|
||||||
|
if ($route->handle($request))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \DomainException('Unhandled request address: ' . $request);
|
||||||
|
}
|
||||||
|
}
|
100
tests/RouterTest.php
Normal file
100
tests/RouterTest.php
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
namespace Szurubooru\Tests;
|
||||||
|
|
||||||
|
final class PostDaoTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testParameterlessHandling()
|
||||||
|
{
|
||||||
|
$router = new \Szurubooru\Router;
|
||||||
|
$testOk = false;
|
||||||
|
$router->get('/test', function() use (&$testOk) { $testOk = true; });
|
||||||
|
$router->handle('GET', '/test');
|
||||||
|
$this->assertTrue($testOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTrailingSlashes()
|
||||||
|
{
|
||||||
|
$router = new \Szurubooru\Router;
|
||||||
|
$testOk = false;
|
||||||
|
$router->get('/test', function() use (&$testOk) { $testOk = true; });
|
||||||
|
$router->handle('GET', '/test/');
|
||||||
|
$this->assertTrue($testOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUnhandledMethod()
|
||||||
|
{
|
||||||
|
$router = new \Szurubooru\Router;
|
||||||
|
$router->get('/test', function() { $this->fail('Route shouldn\'t be executed'); });
|
||||||
|
$this->setExpectedException('\DomainException');
|
||||||
|
$router->handle('POST', '/test');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUnhandledQuery()
|
||||||
|
{
|
||||||
|
$router = new \Szurubooru\Router;
|
||||||
|
$router->get('/test', function() { $this->fail('Route shouldn\'t be executed'); });
|
||||||
|
$this->setExpectedException('\DomainException');
|
||||||
|
$router->handle('GET', '/test2');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTwoMethodsHandling()
|
||||||
|
{
|
||||||
|
$router = new \Szurubooru\Router;
|
||||||
|
$testOk = false;
|
||||||
|
$router->get('/test', function() { $this->fail('Route shouldn\'t be executed'); });
|
||||||
|
$router->post('/test', function() use (&$testOk) { $testOk = true; });
|
||||||
|
$router->handle('POST', '/test');
|
||||||
|
$this->assertTrue($testOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testParameterHandling()
|
||||||
|
{
|
||||||
|
$router = new \Szurubooru\Router;
|
||||||
|
$testOk = false;
|
||||||
|
$router->get('/tests/:id', function($id) use (&$testOk) {
|
||||||
|
$this->assertEquals($id, 'test_id');
|
||||||
|
$testOk = true; });
|
||||||
|
|
||||||
|
$router->handle('GET', '/tests/test_id');
|
||||||
|
$this->assertTrue($testOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTwoParameterHandling()
|
||||||
|
{
|
||||||
|
$router = new \Szurubooru\Router;
|
||||||
|
$testOk = false;
|
||||||
|
$router->get('/tests/:id/:page', function($id, $page) use (&$testOk) {
|
||||||
|
$this->assertEquals($id, 'test_id');
|
||||||
|
$this->assertEquals($page, 'test_page');
|
||||||
|
$testOk = true; });
|
||||||
|
|
||||||
|
$router->handle('GET', '/tests/test_id/test_page');
|
||||||
|
$this->assertTrue($testOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMissingParameterHandling()
|
||||||
|
{
|
||||||
|
$router = new \Szurubooru\Router;
|
||||||
|
$testOk = false;
|
||||||
|
$router->get('/tests/:id', function($id, $page) use (&$testOk) {
|
||||||
|
$this->assertEquals($id, 'test_id');
|
||||||
|
$this->assertNull($page);
|
||||||
|
$testOk = true; });
|
||||||
|
|
||||||
|
$router->handle('GET', '/tests/test_id');
|
||||||
|
$this->assertTrue($testOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMissingDefaultParameterHandling()
|
||||||
|
{
|
||||||
|
$router = new \Szurubooru\Router;
|
||||||
|
$testOk = false;
|
||||||
|
$router->get('/tests/:id', function($id, $page = 1) use (&$testOk) {
|
||||||
|
$this->assertEquals($id, 'test_id');
|
||||||
|
$this->assertEquals(1, $page);
|
||||||
|
$testOk = true; });
|
||||||
|
|
||||||
|
$router->handle('GET', '/tests/test_id');
|
||||||
|
$this->assertTrue($testOk);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue