Skip to content

Commit

Permalink
Milstone of changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Ahmard authored and Ahmard committed Oct 28, 2020
1 parent f4eb5d7 commit 187eeec
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 168 deletions.
61 changes: 35 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# QuickRoute
An elegant http router built on top of [FastRoute](https://github.com/nikic/FastRoute) to provide more easy of use.

## Information
Due to object-sharing between routes introduced in version 1, some errors cannot be fixed.
<br/>
Here is version 2, which is object-sharing free.

## Installation
```bash
Expand All @@ -13,16 +17,38 @@ Simple example
```php
use QuickRoute\Route;
use QuickRoute\Route\Collector;
use QuickRoute\Route\Dispatcher;

Route::get('/', function (){
require('vendor/autoload.php');

Route::get('/', function () {
echo 'Hello world';
});

$collector = Collector::create()
->collect()
->register();

$routes = $collector->getCollectedRoutes();
$method = $_SERVER['REQUEST_METHOD'];
$path = $_SERVER['REQUEST_URI'];
if (false !== $pos = strpos($path, '?')) {
$uri = substr($path, 0, $pos);
}
$path = rawurldecode($path);


$collector = Collector::create()->collect()->register();

$dispatcher = Dispatcher::create($collector)->dispatch($method, $path);

switch (true) {
case $dispatcher->isFound():
$routeData = $dispatcher->getRoute();
$routeData['controller']($dispatcher->getUrlParameters());
break;
case $dispatcher->isNotFound():
echo "Page not found";
break;
case $dispatcher->isMethodNotAllowed():
echo "Request method not allowed";
break;
}
```

Controller-like example
Expand All @@ -35,31 +61,14 @@ Route::get('/home', 'MainController@home');
Advance usage
```php
use QuickRoute\Route;
use QuickRoute\RouteInterface;

Route::prefix('user')->name('user.')
->namespace('User')
->middleware('UserMiddleware')
->group(function (RouteInterface $route){
$route->get('profile', 'UserController@profile');
$route->put('update', 'UserController@update');
});
```

More advance usage
```php
use QuickRoute\Route;
use QuickRoute\RouteInterface;

Route::prefix('notes')->name('notes.')
->prepend('api')
->append('{token}')
->namespace('User')
->group(function (RouteInterface $route){
$route->post('add', 'NotesController@add')->name('add');
$route->put('{noteId}', 'NotesController@update')->name('update');
->group(function (){
Route::get('profile', 'UserController@profile');
Route::put('update', 'UserController@update');
});

```

Routes as configuration
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
}
],
"require": {
"nikic/fast-route": "^1.3"
"nikic/fast-route": "^1.3",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^9"
Expand Down
23 changes: 6 additions & 17 deletions src/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
* @method static TheRoute name(string $name)
* @method static TheRoute namespace(string $namespace)
* @method static TheRoute middleware(string $middleware)
* @method static TheRoute prepend(string $prefixToPrepend)
* @method static TheRoute append(string $prefixToAppend)
* @method static TheRoute group(callable $closure)
* @method static TheRoute with(array $withDat)
* @method static TheRoute get(string $route, $controller)
Expand All @@ -28,25 +26,21 @@ class Route
*/
protected static array $called = [];

protected static TheRoute $theRouter;

protected static array $defaultRouteConfig = [];

/**
* @param string $name
* @param array $args
* @return TheRoute
*/
public static function __callStatic($name, $args)
public static function __callStatic(string $name, array $args)
{
self::$theRouter = new TheRoute(self::$defaultRouteConfig);

return self::$theRouter->$name(...$args);
$router = new TheRoute();
self::$called[] = $router;
return $router->$name(...$args);
}

public static function use(array $theRoute)
public static function restart()
{
self::$defaultRouteConfig = $theRoute;
self::$called = [];
}

/**
Expand All @@ -57,9 +51,4 @@ public static function getRoutes(): array
{
return self::$called;
}

public static function addRoute(TheRoute $route)
{
self::$called[] = $route;
}
}
96 changes: 86 additions & 10 deletions src/Route/Collector.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,34 @@ class Collector

protected array $collectedRoutes = [];

private array $routes = [];


public static function create()
{
return new self();
}

public function collectFile(string $filePath, array $routesInfo = [])
{
Route::use($routesInfo);
require $filePath;
$this->collectedRoutes += Route::getRoutes();
$routes = Route::getRoutes();
$this->collectedRoutes += $this->get($routes);
return $this;
}

public function collect(array $routesInfo = [])
{
Route::use($routesInfo);
$this->collectedRoutes += Route::getRoutes();
$routes = Route::getRoutes();
$this->collectedRoutes += $this->get($routes);
return $this;
}

public function register()
{
foreach ($this->collectedRoutes as $route) {
//Notify that we are about to register this route
$route->onRegister();
$routeData = $route->getRouteData();

foreach ($this->collectedRoutes as $routeData) {
//Register route to Nikita's fast route.
$this->getFastRouteCollector()->addRoute(strtoupper($routeData['method']), $routeData['prefix'], $route);
$this->getFastRouteCollector()->addRoute(strtoupper($routeData['method']), $routeData['prefix'], $routeData);
}

return $this;
Expand All @@ -70,4 +69,81 @@ public function getCollectedRoutes(): array
{
return $this->collectedRoutes;
}

private function get(array $routes)
{
$routes = $this->loop($routes);

$this->build($routes);

return $this->routes;
}

/**
* @param TheRoute[] $routes
* @return array
*/
private function loop(array $routes)
{
$results = [];

for ($i = 0; $i < count($routes); $i++) {
$route = $routes[$i]->getRouteData();
$results[$i]['route'] = $route;
if (!empty($route['group'])) {
$results[$i]['children'] = $this->loop($this->getGroup($route['group']));
}
}

$this->routes = [];

return $results;
}

private function build(array $routes, array $parent = [])
{
foreach ($routes as $route) {
$routeData = $route['route'];
if (isset($route['route'])) {

if (isset($parent['prefix'])) {
$parentPrefix = $parent['prefix'];
if (! empty($routeData['prefix'])) {
$parentPrefix = $parentPrefix . $routeData['prefix'];
}
}

if (isset($parent['middleware'])) {
$parentMiddleware = $parent['middleware'];
if ($routeData['middleware']) {
$parentMiddleware = $parentMiddleware . '|' . $routeData['middleware'];
}
}

$data = [
'prefix' => ($parentPrefix ?? $routeData['prefix']),
'namespace' => ($parent['namespace'] ?? '') . $routeData['namespace'],
'name' => ($parent['name'] ?? '') . $route['route']['name'],
'controller' => $routeData['controller'],
'method' => $routeData['method'],
'middleware' => ($parentMiddleware ?? $routeData['middleware']),
];

if (!empty($routeData['method'])) {
$this->routes[] = $data;
}

if (isset($route['children'])) {
$this->build($route['children'], $data);
}
}
}
}

private function getGroup(callable $callback)
{
Route::restart();
$callback();
return Route::getRoutes();
}
}
63 changes: 63 additions & 0 deletions src/Route/DispatchResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php


namespace QuickRoute\Route;


use FastRoute\Dispatcher as FastDispatcher;

class DispatchResult
{
private array $dispatchResult;

public function __construct(array $dispatchResult)
{
$this->dispatchResult = $dispatchResult;
}


/**
* If url is found
* @return bool
*/
public function isFound()
{
return $this->dispatchResult[0] === FastDispatcher::FOUND;
}

/**
* If url is not found
* @return bool
*/
public function isNotFound()
{
return $this->dispatchResult[0] === FastDispatcher::NOT_FOUND;
}

/**
* If url method is not allowed
* @return bool
*/
public function isMethodNotAllowed()
{
return $this->dispatchResult[0] === FastDispatcher::METHOD_NOT_ALLOWED;
}

/**
* Get dispatched url parameters
* @return mixed|null
*/
public function getUrlParameters()
{
return $this->dispatchResult[2] ?? null;
}

/**
* Get found url class
* @return array
*/
public function getRoute(): array
{
return $this->dispatchResult[1] ?? [];
}
}
Loading

0 comments on commit 187eeec

Please sign in to comment.