Skip to content

Commit

Permalink
[ENH] refactoring routing system to be more flexiblea and manageable …
Browse files Browse the repository at this point in the history
…via application
  • Loading branch information
bim-g committed Sep 22, 2024
1 parent 9a2f35a commit 2ed0ea9
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 63 deletions.
14 changes: 14 additions & 0 deletions src/Core/Routing/Providers/Contracts/RouteContract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
/*
* Copyright (c) 2024. Wepesi Dev Framework
*/

namespace Wepesi\Core\Routing\Providers\Contracts;

/**
* @template T
*/
interface RouteContract
{
public function call();
}
48 changes: 48 additions & 0 deletions src/Core/Routing/Providers/Contracts/RouterContract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
/*
* Copyright (c) 2024. Wepesi Dev Framework
*/

namespace Wepesi\Core\Routing\Providers\Contracts;

/**
* @template T
*/
interface RouterContract
{
/**
* @param string $path
* @param $callable
* @param $name
* @return RouteContract
*/
public function get(string $path, $callable, $name = null): RouteContract;
/**
* @param string $path
* @param $callable
* @param $name
* @return RouteContract
*/
public function post(string $path, $callable, $name = null): RouteContract;

/**
* @param string $path
* @param $callable
* @param $name
* @return RouteContract
*/
public function put(string $path, $callable, $name = null): RouteContract;

/**
* @param string $path
* @param $callable
* @param $name
* @return RouteContract
*/
public function delete(string $path, $callable, $name = null): RouteContract;

/**
*
*/
public function run();
}
18 changes: 18 additions & 0 deletions src/Core/Routing/Providers/Contracts/RouterProviders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/*
* Copyright (c) 2024. Wepesi Dev Framework
*/

namespace Wepesi\Core\Routing\Providers\Contracts;

/**
* @template T
*/
interface RouterProviders
{
/**
* @param string $routes
* @return void
*/
public function register(string $routes): void;
}
23 changes: 13 additions & 10 deletions src/Core/Routing/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@

namespace Wepesi\Core\Routing;

use Wepesi\Core\Routing\Providers\Contracts\RouteContract;
use Wepesi\Core\Routing\Traits\routeBuilder;

/**
*
* @template T
* @template-implements RouteContract<T>
*/
class Route
class Route implements RouteContract
{
/**
* @var string
Expand Down Expand Up @@ -42,10 +44,11 @@ class Route
use routeBuilder;

/**
* @param $path
* @param class-string<T> $path
* @param $callable
* @param array $middleware
*/
function __construct($path, $callable, array $middleware = [])
function __construct(string $path, $callable, array $middleware = [])
{
$this->pattern = trim($path, '/');
$this->callable = $callable;
Expand All @@ -56,10 +59,10 @@ function __construct($path, $callable, array $middleware = [])
}

/**
* @param $url
* @param class-string<T> $url
* @return bool
*/
function match($url): bool
function match(string $url): bool
{
$url = trim($url, '/');
$path = preg_replace_callback('#:([\w]+)#', [$this, 'paramMatch'], $this->pattern);
Expand All @@ -80,16 +83,16 @@ function match($url): bool
/**
*
*/
public function call()
public function call(): void
{
try {
if (count($this->middleware_tab) > 0) {
foreach ($this->middleware_tab as $middleware) {
$this->routeFunctionCall($middleware, true, $this->_matches);
$this->executeMiddleware($middleware, $this->_matches);
}
$this->middleware_tab = [];
}
$this->routeFunctionCall($this->callable, false, $this->_matches);
$this->executeController($this->callable, $this->_matches);
} catch (\Exception $ex) {
echo $ex->getMessage();
}
Expand Down Expand Up @@ -126,7 +129,7 @@ public function getPattern(): string
* @param $params
* @return array|string|string[]
*/
public function getUrl($params)
public function getUrl($params): array|string
{
$path = $this->pattern;
foreach ($params as $k => $v) {
Expand Down
46 changes: 46 additions & 0 deletions src/Core/Routing/RouteFileRegistrar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/*
* Copyright (c) 2024. Wepesi Dev Framework
*/

namespace Wepesi\Core\Routing;


use Wepesi\Core\Routing\Providers\Contracts\RouterContract;
use Wepesi\Core\Routing\Providers\Contracts\RouterProviders;

/**
* @template T
* @template-implements RouterProviders<T>
*/
final class RouteFileRegistrar implements RouterProviders
{
/**
* @var RouterContract
*/
protected RouterContract $router;

/**
* Create a new route file registrar instance.
*
* @param Router $router
*/
public function __construct(RouterContract $router)
{
$this->router = $router;
}

/**
* Require the given routes file.
*
* @param class-string<T> $routes
* @return void
*/
public function register(string $routes): void
{
$router = $this->router;
if (is_file($routes)) {
require $routes;
}
}
}
69 changes: 34 additions & 35 deletions src/Core/Routing/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@

namespace Wepesi\Core\Routing;

use Closure;
use Wepesi\Core\Application;
use Wepesi\Core\Escape;
use Wepesi\Core\Exceptions\RoutingException;
use Wepesi\Core\Http\Response;
use Wepesi\Core\Routing\Providers\Contracts\RouteContract;
use Wepesi\Core\Routing\Providers\Contracts\RouterContract;
use Wepesi\Core\Routing\Traits\routeBuilder;

/**
* Wepesi API Router provider
* @template T
* @template-implements RouterContract<T>
*/
class Router
class Router implements RouterContract
{
/**
* @var array|null
* @var array
*/
protected array $baseMiddleware;
/**
Expand Down Expand Up @@ -56,7 +61,7 @@ public function __construct()
}

/**
* @param $path
* @param string $path
* @param $callable
* @param null $name
* @return Route
Expand All @@ -73,9 +78,9 @@ public function get(string $path, $callable, $name = null): Route
* @param string $methode
* @return Route
*/
private function add(string $pattern, $callable, ?string $name, string $methode): Route
private function add(string $pattern, $callable, ?string $name, string $methode): RouteContract
{
$pattern = $this->baseRoute . '/' . trim($pattern, '/');
$pattern = $this->baseRoute . Escape::addSlashes(trim($pattern, '/'));
$pattern = $this->baseRoute ? rtrim($pattern, '/') : $pattern;
$route = new Route($pattern, $callable, $this->baseMiddleware);
$this->routes[$methode][] = $route;
Expand All @@ -91,7 +96,7 @@ private function add(string $pattern, $callable, ?string $name, string $methode)
}

/**
* @param $path
* @param string $path
* @param $callable
* @param null $name
* @return Route
Expand All @@ -117,32 +122,14 @@ public function delete(string $path, $callable, $name = null): Route
return $this->add($path, $callable, $name, 'DELETE');
}

/**
* API base group routing
* @param string|array $base_route it can be defined as we did for group routing, but you don't need to specify api, it will be added automatically
* @param callable $callable
* @return null
*/
public function api($base_route, callable $callable)
{
$api_pattern = '/api';
if (is_array($base_route)) {
$base_route['pattern'] = $api_pattern . (isset($base_route['pattern']) ? $this->trimPath($base_route['pattern']) : '');
} else {

$base_route = $api_pattern . $this->trimPath($base_route);
}
return $this->group($base_route, $callable);
}

/**
* @param string $path
* @return string
*/
private function trimPath(string $path): string
{
$trim_path = trim($path, '/');
return strlen($trim_path) > 0 ? '/' . $trim_path : '';
return strlen($trim_path) > 0 ? Escape::addSlashes($trim_path) : '';
}

/**
Expand All @@ -151,7 +138,7 @@ private function trimPath(string $path): string
* @param array|string $base_route can be a string or an array to defined middleware for the group routing
* @param callable $callable a callable method can be a controller method or an anonymous callable method
*/
public function group($base_route, callable $callable)
public function group(array|string $base_route, $callable): void
{
$pattern = $base_route;
if (is_array($base_route)) {
Expand All @@ -162,7 +149,12 @@ public function group($base_route, callable $callable)
}
$cur_base_route = $this->baseRoute;
$this->baseRoute .= $pattern;
call_user_func($callable);

if ($callable instanceof Closure) {
call_user_func($callable, $this);
} else {
(new RouteFileRegistrar($this))->register($callable);
}
$this->baseRoute = $cur_base_route;
}

Expand Down Expand Up @@ -206,12 +198,12 @@ protected function getUrl()
}

/**
* Set the 404 handling function.
* Set the 404 handling functions.
*
* @param object|callable|string $match_fn The function to be executed
* @param callable|object|string $match_fn The function to be executed
* @param $callable
*/
public function set404($match_fn, $callable = null)
public function set404(callable|object|string $match_fn, $callable = null): void
{
if (!$callable) {
$this->notFoundCallback = $match_fn;
Expand All @@ -221,7 +213,15 @@ public function set404($match_fn, $callable = null)
}

/**
* @return void
* list all routes elements
* @return array
*/
public function getRoutes(): array
{
return $this->routes;
}
/**
* Execute the route request
*/
public function run()
{
Expand All @@ -240,7 +240,6 @@ public function run()
}
if (count($routesRequestMethod) === $i) {
$this->trigger404($this->notFoundCallback);
Response::setStatusCode(404);
}
} catch (RoutingException $ex) {
Application::dumper($ex);
Expand All @@ -250,9 +249,9 @@ public function run()
}

/**
* @return void
* trigger 404 error while no route match
*/
protected function trigger404($match = null)
protected function trigger404($match = null): void
{
if ($match) {
$this->routeFunctionCall($match);
Expand Down
Loading

0 comments on commit 2ed0ea9

Please sign in to comment.