Addin a lot of changes
This commit is contained in:
@@ -76,9 +76,9 @@ RouteCollection::patch("/[i:id]", "\App\SubPlugin\Plugin\PluginController@updat
|
|||||||
RouteCollection::delete("/[i:id]", "\App\SubPlugin\Plugin\PluginController@destroy");
|
RouteCollection::delete("/[i:id]", "\App\SubPlugin\Plugin\PluginController@destroy");
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Laravel Compatibility (#ToDo)
|
#### Laravel Compatibility
|
||||||
|
|
||||||
It would be nice to add routes similar to how Laravel Does, avoiding the usage of the whole ClassPath
|
Routes can be added with the Laravel way
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
@@ -299,6 +299,37 @@ use Routes\RouteCollection as RouteCollection;
|
|||||||
RouteCollection::get('*', function() { })->middlewareIgnore("auth");
|
RouteCollection::get('*', function() { })->middlewareIgnore("auth");
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Extending functionality
|
||||||
|
|
||||||
|
This library allows you to change and customize some behaviors
|
||||||
|
|
||||||
|
### Content Parser
|
||||||
|
|
||||||
|
This librar has as default the return types for the Routes
|
||||||
|
|
||||||
|
* `string` (Raw print the content)
|
||||||
|
* `Array` (JSON Encode The Return)
|
||||||
|
* `stdClass|object|mixed` (JSON Encode The Return)
|
||||||
|
|
||||||
|
But you can extend this functionality to process a return type in a customizible way with the API `RouteCollection::addParser(string $type, callable $function)`
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
use Routes\RouteCollection;
|
||||||
|
|
||||||
|
// When the returned object is the type Collection. This parser will be used
|
||||||
|
RouteCollection::addParser("Collection", function(Collection $collection): void{
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
echo json_encode($collection->get());
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Object Spawners
|
||||||
|
|
||||||
|
The functions called by the Routing system might have a Data Type defined as a parameter. With the spawners, you can configure how this Objects will be created and passed prepared to the target function.
|
||||||
|
|
||||||
|
With the default Behavior, in order, we grab the function parameters, match with the variable segments of the URL and instanciate a object from the defined type passing the URI parameter as the __construct main parameter
|
||||||
|
|
||||||
## Server configuration
|
## Server configuration
|
||||||
|
|
||||||
#### Requirements
|
#### Requirements
|
||||||
@@ -424,33 +455,11 @@ server {
|
|||||||
|
|
||||||
The package consist in 3 main files, with `RouteCollection.php` providing the main API
|
The package consist in 3 main files, with `RouteCollection.php` providing the main API
|
||||||
|
|
||||||
- `Route.php` => Stores each route information
|
|
||||||
- `RouteCollection.php` => Aggregate all routes and provide a interface to interact with the routes dataset
|
- `RouteCollection.php` => Aggregate all routes and provide a interface to interact with the routes dataset
|
||||||
- `RouteGroup.php` => Aggregate a group of routes based on their namespaces
|
- `RouteGroup.php` => Aggregate a group of routes based on their namespaces
|
||||||
|
- `Route.php` => Stores each route information
|
||||||
|
|
||||||
The class `RouteCollection` is treated as a Singleton that return it's own global instance when loaded. The main interface would be something like: `RouteCollection::add($verb, $uri, $callback, $weight = 0)`, this method will return the instance of the `Route` object, so that the Route properties can be configured
|
The class `RouteCollection` is treated as a Singleton that return it's own global instance when loaded. The main interface would be something like: `RouteCollection::add($verb, $uri, $callback, $weight = 0)`, this method will return the instance of the `Route` object, so that the Route properties can be chained
|
||||||
|
|
||||||
*Route settings:*
|
|
||||||
- `RouteCollection::add($verb, $uri, $callback, $weight = 0)->doBlock()`
|
|
||||||
- After this route execute, no more routes would be executed
|
|
||||||
- `RouteCollection::add($verb, $uri, $callback, $weight = 0)->notBlock()`
|
|
||||||
- The execution of this route will not block the execution of the next routes
|
|
||||||
- `RouteCollection::add($verb, $uri, $callback, $weight = 0)->doIgnore()`
|
|
||||||
- This route will not count as a executed route, so a 404 can be detected
|
|
||||||
- `RouteCollection::add($verb, $uri, $callback, $weight = 0)->middlewareIgnore($name = '')`
|
|
||||||
- This route will not execute a registered global middleware
|
|
||||||
- `RouteCollection::add($verb, $uri, $callback, $weight = 0)->middlewareAdd($name = '', $params = [])`
|
|
||||||
- Register that this route must pass by a registered middleware
|
|
||||||
- `RouteCollection::add($verb, $uri, $callback, $weight = 0)->middlewareAppend($name = '', $function)`
|
|
||||||
- Append a ad-hock middleware to this specific route
|
|
||||||
- `RouteCollection::add($verb, $uri, $callback, $weight = 0)->setWeight($weigth = 0)`
|
|
||||||
- Define the priority of this route on the execution chain
|
|
||||||
- `RouteCollection::add($verb, $uri, $callback, $weight = 0)->setName($name)`
|
|
||||||
- Add a property name for the route object
|
|
||||||
- `RouteCollection::add($verb, $uri, $callback, $weight = 0)->setTag($key = '', $value = '')`
|
|
||||||
- Add a custom arbitrary tag on the route object
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Other resources
|
## Other resources
|
||||||
https://stackoverflow.com/questions/8054165/using-put-method-in-html-form
|
https://stackoverflow.com/questions/8054165/using-put-method-in-html-form
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Routes;
|
||||||
|
|
||||||
|
use ReflectionMethod;
|
||||||
|
use ReflectionFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object Parameter Spawner
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ObjectSpawners
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return the list of available Spawners
|
||||||
|
*
|
||||||
|
* @return array{array: callable, callable: callable, string: callable}
|
||||||
|
*/
|
||||||
|
public static function getDefaultSpawners(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
"string" => self::classPathSpawner(),
|
||||||
|
"callable" => self::clousureSpawner(),
|
||||||
|
"array" => self::arraySpawner()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Spawner for classPath
|
||||||
|
*
|
||||||
|
* /App/Module/ModuleController:method
|
||||||
|
*
|
||||||
|
* @return (callable(array ,Route ,array ):array)
|
||||||
|
*/
|
||||||
|
private static function classPathSpawner(): callable
|
||||||
|
{
|
||||||
|
return function (array $classPath, Route $route, array $returnParameters = array ()): array {
|
||||||
|
$controller = new $classPath[0]();
|
||||||
|
$routeParameters = array_values($route->_params);
|
||||||
|
|
||||||
|
$reflectionFunction = new ReflectionMethod($controller::class, $classPath[1]);
|
||||||
|
$reflectionParameters = $reflectionFunction->getParameters();
|
||||||
|
|
||||||
|
foreach ($reflectionParameters as $key => $signatureItem) {
|
||||||
|
|
||||||
|
if (!isset($routeParameters[$key])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($signatureItem->getType()->isBuiltin()) {
|
||||||
|
$returnParameters[] = $routeParameters[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($routeParameters[$key])) {
|
||||||
|
$class = $signatureItem->getType()->__tostring();
|
||||||
|
$returnParameters[] = new $class($routeParameters[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnParameters;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Spawner for a closuer
|
||||||
|
*
|
||||||
|
* RouteCollection::get("*", function(int $id ....) {});
|
||||||
|
*
|
||||||
|
* @return (callable(callable ,Route ,array ):array)
|
||||||
|
*/
|
||||||
|
private static function clousureSpawner(): callable
|
||||||
|
{
|
||||||
|
return function (callable $callback, Route $route, array $returnParameters = array ()): mixed {
|
||||||
|
$routeParameters = array_values($route->_params);
|
||||||
|
|
||||||
|
$reflectionFunction = new ReflectionFunction($callback);
|
||||||
|
$reflectionParameters = $reflectionFunction->getParameters();
|
||||||
|
|
||||||
|
foreach ($reflectionParameters as $key => $signatureItem) {
|
||||||
|
if (!isset($routeParameters[$key])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($signatureItem->getType()->isBuiltin()) {
|
||||||
|
$returnParameters[] = $routeParameters[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($routeParameters[$key])) {
|
||||||
|
$class = $signatureItem->getType()->__tostring();
|
||||||
|
$returnParameters[] = new $class($routeParameters[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnParameters;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Spawner for array definition Laravel Style
|
||||||
|
*
|
||||||
|
* RouteCollection::get("*", [ModuleController:class, "method"]);
|
||||||
|
*
|
||||||
|
* @return (callable(array ,Route ,array ):array)
|
||||||
|
*/
|
||||||
|
private static function arraySpawner(): callable
|
||||||
|
{
|
||||||
|
return function (array $array, Route $route, Array $returnParameters = Array()): mixed {
|
||||||
|
$routeParameters = array_values($route->_params);
|
||||||
|
|
||||||
|
$reflectionFunction = new ReflectionMethod($array[0], $array[1]);
|
||||||
|
$reflectionParameters = $reflectionFunction->getParameters();
|
||||||
|
|
||||||
|
foreach ($reflectionParameters as $key => $signatureItem) {
|
||||||
|
if (!isset($routeParameters[$key])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($signatureItem->getType()->isBuiltin()) {
|
||||||
|
$returnParameters[] = $routeParameters[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($routeParameters[$key])) {
|
||||||
|
$class = $signatureItem->getType()->__tostring();
|
||||||
|
$returnParameters[] = new $class($routeParameters[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnParameters;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
+159
-130
@@ -2,55 +2,72 @@
|
|||||||
|
|
||||||
namespace Routes;
|
namespace Routes;
|
||||||
|
|
||||||
use stdClass;
|
use Clousure;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Summary of Route
|
* Summary of Route
|
||||||
*/
|
*/
|
||||||
class Route
|
class Route
|
||||||
{
|
{
|
||||||
public Array $_verb = Array(); // Route Verbs to match
|
public private(set) Array $_verb = Array(); // Route Verbs to match
|
||||||
|
public private(set) string $_source; // Execution Source (HTTP | Cli | SOAP)
|
||||||
public string $_source; // Execution Source (HTTP | Cli | SOAP)
|
public private(set) string $_name; // Route Name
|
||||||
|
public private(set) string $_uri; // Route URI
|
||||||
public string $_name; // Route Name
|
public private(set) int $_weight = 0; // Wight of the route, for sorting
|
||||||
|
public private(set) Array $_uriSegments = Array(); // Route Full URI Segments
|
||||||
public string $_uri; // Route URI
|
public private(set) Array $_segments = Array(); // Route parsed URI Segments
|
||||||
|
public private(set) Array $_params = Array(); // Prepared Routes parameters
|
||||||
public int $_weight = 0; // Wight of the route, for sorting
|
public private(set) Array $_before = Array(); // Functions to execute Before the Route
|
||||||
|
public private(set) mixed $_callback; // Route Callback
|
||||||
public Array $_uriSegments = Array(); // Route Full URI Segments
|
public private(set) Array $_after = Array(); // Functions to execute After the Route
|
||||||
|
public private(set) string $_regex = ''; // The URI regex to match
|
||||||
public Array $_segments = Array(); // Route parsed URI Segments
|
public private(set) bool $_block = true; // Will this route block the remaining execution?
|
||||||
|
public private(set) bool $_ignore = false; // Wil the execution of this route be counted. To know 404
|
||||||
public Array $_params = Array(); // Prepared Routes parameters
|
public private(set) Array $_middlewaresToIgnore = Array(); // Middlewares this Route will ignore
|
||||||
|
public private(set) Array $_tags = Array(); // Tags of the Route
|
||||||
public Array $_before = Array(); // Functions to execute Before the Route
|
public private(set) Array $_variableSegments = Array(); // Segments of the route that are variables
|
||||||
|
|
||||||
public Array|string $_callback = Array(); // Route Callback
|
|
||||||
|
|
||||||
public Array $_after = Array(); // Functions to execute After the Route
|
|
||||||
|
|
||||||
public string $_regex = ''; // The URI regex to match
|
|
||||||
|
|
||||||
public bool $_block = true; // Will this route block the remaining execution?
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Is there a problem witch one?
|
|
||||||
*/
|
|
||||||
public bool $_httpError = false;
|
|
||||||
|
|
||||||
public bool $_ignore = false; // Wil the execution of this route be counted. To know 404
|
|
||||||
|
|
||||||
public array $_middlewaresToIgnore = array(); // Middlewares this Route will ignore
|
|
||||||
|
|
||||||
public array $_tags = array(); // Tags of the Route
|
|
||||||
|
|
||||||
|
|
||||||
// ========
|
//=======================================================
|
||||||
// Getters and Setters
|
// Getters and Setters
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set The Route Verb
|
||||||
|
*
|
||||||
|
* @param array $verb
|
||||||
|
* @return Route
|
||||||
|
*/
|
||||||
|
function setVerb(Array $verb): Route
|
||||||
|
{
|
||||||
|
$this->_verb = $verb;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a verb to the Route
|
||||||
|
*
|
||||||
|
* @param string $verb
|
||||||
|
* @return Route
|
||||||
|
*/
|
||||||
|
function appendVerb(string $verb): Route
|
||||||
|
{
|
||||||
|
$this->_verb = array_merge($this->_verb, [$verb]);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Route Callback
|
||||||
|
*
|
||||||
|
* @param mixed $callback
|
||||||
|
* @return Route
|
||||||
|
*/
|
||||||
|
function setCallback(mixed $callback): Route
|
||||||
|
{
|
||||||
|
$this->_callback = $callback;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the name of this Route
|
* Set the name of this Route
|
||||||
*
|
*
|
||||||
@@ -144,72 +161,78 @@ class Route
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================
|
||||||
|
// Middlewares
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a middleware for this route
|
||||||
|
*
|
||||||
|
* @param string $name Name of the Middleware
|
||||||
|
* @param Array $params Array of parametrs to pass on the function
|
||||||
|
*
|
||||||
|
* @return Route
|
||||||
|
*/
|
||||||
|
function middlewareAdd(string $name, array $params = []): Route
|
||||||
|
{
|
||||||
|
$this->_before[$name] = $params;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Middlewares this Route will ignore
|
||||||
|
*
|
||||||
|
* @param mixed $name
|
||||||
|
* @return Route
|
||||||
|
*/
|
||||||
|
function middlewareIgnore(string $name): Route
|
||||||
|
{
|
||||||
|
$this->_middlewaresToIgnore[] = $name;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrite Middlewares
|
||||||
|
*
|
||||||
|
* @param array $middlewares
|
||||||
|
* @return Route
|
||||||
|
*/
|
||||||
|
function setMiddlewares(Array $middlewares): Route
|
||||||
|
{
|
||||||
|
$this->_before = $middlewares;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================
|
//=======================================================
|
||||||
// Route Functionality
|
// Route Functionality
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the route
|
* Set Variables Segments to pass as function args
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @param string $segment
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
function execute(): mixed
|
function registerVariableSegment(string $segment): void
|
||||||
{
|
{
|
||||||
|
if($segment == ""){
|
||||||
$routeReturn = "";
|
return;
|
||||||
|
|
||||||
//Middlewares with function or class method
|
|
||||||
foreach ($this->_before as $key => $before) {
|
|
||||||
if (!in_array($key, $this->_middlewaresToIgnore) && !$this->_ignore) {
|
|
||||||
if (is_string($before)) {
|
|
||||||
$before = explode('@', $before);
|
|
||||||
$class = new $before[0]();
|
|
||||||
$class->{$before[1]}();
|
|
||||||
} else if (is_array($before)) {
|
|
||||||
call_user_func($before['callback'], $before['params']);
|
|
||||||
} else {
|
|
||||||
call_user_func($before);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->_callback as $callback) {
|
$segment = str_replace("]", "", str_replace("[", "", $segment));
|
||||||
if (is_string($callback)) {
|
$segments = explode(":", $segment);
|
||||||
$segments = explode('@', $callback);
|
|
||||||
$class = new $segments[0]();
|
|
||||||
|
|
||||||
$r = new \ReflectionMethod($segments[0], $segments[1]);
|
if(sizeof($segments) == 1){
|
||||||
|
return;
|
||||||
$firstType = count($r->getParameters()) > 0 ? $r->getParameters()[0]->getType() : null;
|
|
||||||
if ($firstType instanceof \ReflectionNamedType && !$firstType->isBuiltin()) {
|
|
||||||
$element = $firstType->getName();
|
|
||||||
$element = new $element;
|
|
||||||
if (isset($this->_params['id'])) {
|
|
||||||
$element->load($this->_params['id']);
|
|
||||||
}
|
|
||||||
$this->_params['id'] = $element;
|
|
||||||
}
|
|
||||||
$routeReturn = $class->{$segments[1]}(...array_values($this->_params));
|
|
||||||
} else {
|
|
||||||
$r = new \ReflectionFunction($callback);
|
|
||||||
$firstType = count($r->getParameters()) > 0 ? $r->getParameters()[0]->getType() : null;
|
|
||||||
if ($firstType instanceof \ReflectionNamedType && !$firstType->isBuiltin()) {
|
|
||||||
$element = $firstType->getName();
|
|
||||||
$element = new $element;
|
|
||||||
if (isset($this->_params['id'])) {
|
|
||||||
$element->load($this->_params['id']);
|
|
||||||
}
|
|
||||||
$this->_params['id'] = $element;
|
|
||||||
}
|
|
||||||
$routeReturn = call_user_func_array($callback, $this->_params);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->_after as $after) {
|
switch ($segments[0]) {
|
||||||
call_user_func($after);
|
case 'i':
|
||||||
|
$this->_variableSegments[] = ["name" => $segments[1], "type" => "int"];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->_variableSegments[] = ["name" => $segments[1], "type" => "string"];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $routeReturn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -222,6 +245,8 @@ class Route
|
|||||||
$this->_segments = explode('/', $this->_uri);
|
$this->_segments = explode('/', $this->_uri);
|
||||||
|
|
||||||
foreach ($this->_segments as $segment) {
|
foreach ($this->_segments as $segment) {
|
||||||
|
$this->registerVariableSegment($segment);
|
||||||
|
|
||||||
if (strpos($segment, 'i:') > -1) {
|
if (strpos($segment, 'i:') > -1) {
|
||||||
$this->_regex .= "\/[0-9]+";
|
$this->_regex .= "\/[0-9]+";
|
||||||
} else if (strpos($segment, 'h:') > -1) {
|
} else if (strpos($segment, 'h:') > -1) {
|
||||||
@@ -256,46 +281,6 @@ class Route
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a middleware for this route
|
|
||||||
*
|
|
||||||
* @param string $name Name of the Middleware
|
|
||||||
* @param Array $params Array of parametrs to pass on the function
|
|
||||||
*
|
|
||||||
* @return Route
|
|
||||||
*/
|
|
||||||
function middlewareAdd(string $name, array $params): Route
|
|
||||||
{
|
|
||||||
$this->_before[$name] = $params;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Middlewares this Route will ignore
|
|
||||||
*
|
|
||||||
* @param mixed $name
|
|
||||||
* @return Route
|
|
||||||
*/
|
|
||||||
function middlewareIgnore(string $name): Route
|
|
||||||
{
|
|
||||||
$this->_middlewaresToIgnore[] = $name;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setHttpError($code = 400, $message = null)
|
|
||||||
{
|
|
||||||
if ($message == null) {
|
|
||||||
$message = self::$httpMessages[$code];
|
|
||||||
}
|
|
||||||
|
|
||||||
$info = new stdClass();
|
|
||||||
$info->code = $code;
|
|
||||||
$info->message = $message;
|
|
||||||
|
|
||||||
$this->_httpError = $info;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the URI match the Route Signature
|
* Check if the URI match the Route Signature
|
||||||
*
|
*
|
||||||
@@ -337,4 +322,48 @@ class Route
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the route
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function execute(mixed $routeReturn = ""): mixed
|
||||||
|
{
|
||||||
|
|
||||||
|
//Middlewares with function or class method
|
||||||
|
foreach ($this->_before as $key => $before) {
|
||||||
|
if (!in_array($key, $this->_middlewaresToIgnore) && !$this->_ignore) {
|
||||||
|
if (is_string($before)) {
|
||||||
|
$before = explode('@', $before);
|
||||||
|
$class = new $before[0]();
|
||||||
|
$class->{$before[1]}();
|
||||||
|
} else if (is_array($before)) {
|
||||||
|
call_user_func($before['callback'], $before['params']);
|
||||||
|
} else {
|
||||||
|
call_user_func($before);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($this->_callback)) {
|
||||||
|
$segments = explode('@', $this->_callback);
|
||||||
|
$class = new $segments[0]();
|
||||||
|
$parameters = RouteCollection::getObjectSpawner('string')($segments, $this);
|
||||||
|
$routeReturn = $class->{$segments[1]}(...$parameters);
|
||||||
|
} else if (is_array($this->_callback)) {
|
||||||
|
[$class, $method] = $this->_callback;
|
||||||
|
$parameters = RouteCollection::getObjectSpawner('array')($this->_callback, $this);
|
||||||
|
$classInstance = new $class;
|
||||||
|
$routeReturn = $classInstance->$method(...$parameters);
|
||||||
|
} else {
|
||||||
|
$parameters = RouteCollection::getObjectSpawner('callable')($this->_callback, $this);
|
||||||
|
$routeReturn = call_user_func_array($this->_callback, $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->_after as $after) {
|
||||||
|
call_user_func($after);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $routeReturn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+101
-49
@@ -10,26 +10,29 @@ class RouteCollection
|
|||||||
|
|
||||||
private static RouteCollection $_routeCollection;
|
private static RouteCollection $_routeCollection;
|
||||||
|
|
||||||
public string $_uri = '/';
|
public private(set) string $_uri = '/';
|
||||||
public array $_routes = array();
|
public private(set) Array $_routes = Array();
|
||||||
private string $_verb = '';
|
public private(set) string $_verb = '';
|
||||||
private array $_loadedFiles = array();
|
public private(set) Array $_loadedFiles = Array();
|
||||||
private array $_errors = array();
|
public private(set) Array $_errors = Array();
|
||||||
private array $_defaultMiddlewares = array();
|
public private(set) Array $_defaultMiddlewares = Array();
|
||||||
private array $_middlewareSet = array();
|
public private(set) Array $_middlewareSet = Array();
|
||||||
private static array $_verbsWhitelist = array('*', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'CLI');
|
public private(set) bool $_groupIn = false;
|
||||||
private static array $_verbsWeb = array('GET', 'POST', 'PUT', 'PATCH', 'DELETE');
|
public private(set) string $_groupBase = '';
|
||||||
public bool $_groupIn = false;
|
public private(set) Array $_groupList = Array();
|
||||||
public string $_groupBase = '';
|
public private(set) Array $_groups = Array();
|
||||||
public array $_groupList = array();
|
public private(set) Array $_contentParsers = Array(); // Configure parsers for possible Route Returns
|
||||||
public array $_groups = array();
|
public private(set) Route $_currentRoute; // The Route Being Dispatched
|
||||||
public array $_contentParsers = array(); // Configure parsers for possible Route Returns
|
public private(set) bool $_trace = false; // For debuggin
|
||||||
public Route $_currentRoute; // The Route Being Dispatched
|
public private(set) int $_traceVerbosity = 1; // How Verbose to trace
|
||||||
public bool $_trace = false; // For debuggin
|
public private(set) Array $_objectSpawners = Array();
|
||||||
public int $_traceVerbosity = 1; // How Verbose to trace
|
|
||||||
|
|
||||||
|
private static Array $_verbsWhitelist = Array('*', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'CLI');
|
||||||
|
private static Array $_verbsWeb = Array('GET', 'POST', 'PUT', 'PATCH', 'DELETE');
|
||||||
|
|
||||||
//SINGLETON==============================================
|
//=======================================================
|
||||||
|
// SINGLETON
|
||||||
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty constructor for Singleton
|
* Empty constructor for Singleton
|
||||||
@@ -52,8 +55,10 @@ class RouteCollection
|
|||||||
} else {
|
} else {
|
||||||
self::$_routeCollection->_uri = isset($_SERVER['REQUEST_URI']) ? explode('?', $_SERVER['REQUEST_URI'])[0] : '/';
|
self::$_routeCollection->_uri = isset($_SERVER['REQUEST_URI']) ? explode('?', $_SERVER['REQUEST_URI'])[0] : '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$_routeCollection->defineVerb();
|
self::$_routeCollection->defineVerb();
|
||||||
self::$_routeCollection->setDefaultParsers();
|
self::$_routeCollection->setDefaultParsers();
|
||||||
|
self::$_routeCollection->setDefaultObjectSpawners();
|
||||||
}
|
}
|
||||||
self::$_routeCollection->_uri = str_replace("//", "/", self::$_routeCollection->_uri);
|
self::$_routeCollection->_uri = str_replace("//", "/", self::$_routeCollection->_uri);
|
||||||
return self::$_routeCollection;
|
return self::$_routeCollection;
|
||||||
@@ -212,16 +217,16 @@ class RouteCollection
|
|||||||
*/
|
*/
|
||||||
private function setDefaultParsers(): void
|
private function setDefaultParsers(): void
|
||||||
{
|
{
|
||||||
$this->_contentParsers["string"] = function (string $content) {
|
$this->_contentParsers["string"] = function (string $content):void {
|
||||||
echo $content;
|
echo $content;
|
||||||
};
|
};
|
||||||
|
|
||||||
$this->_contentParsers["array"] = function (array $content) {
|
$this->_contentParsers["array"] = function (array $content):void {
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
echo json_encode($content);
|
echo json_encode($content);
|
||||||
};
|
};
|
||||||
|
|
||||||
$this->_contentParsers["stdClass"] = function (object $content) {
|
$this->_contentParsers["stdClass"] = function (object $content):void {
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
echo json_encode($content);
|
echo json_encode($content);
|
||||||
};
|
};
|
||||||
@@ -250,7 +255,7 @@ class RouteCollection
|
|||||||
{
|
{
|
||||||
$contentType = gettype($content);
|
$contentType = gettype($content);
|
||||||
|
|
||||||
if ($contentType == "null") { // Route didn't return anything
|
if ($contentType == "NULL") { // Route didn't return anything
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,6 +269,61 @@ class RouteCollection
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
call_user_func(self::getInstance()->_contentParsers['stdClass'], $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================
|
||||||
|
// Object Spawner
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a Spawner type
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function getObjectSpawner(string $type): mixed
|
||||||
|
{
|
||||||
|
return self::getInstance()->_objectSpawners[$type];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register some Object Spawner Types
|
||||||
|
*
|
||||||
|
* This will serve to be overwritten for each case so this
|
||||||
|
* library can have a default spawner and allow custom spawners
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function setDefaultObjectSpawners(): void
|
||||||
|
{
|
||||||
|
$this->_objectSpawners = ObjectSpawners::getDefaultSpawners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to append a Spawner type on the list
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param callable $callback
|
||||||
|
* @return RouteCollection
|
||||||
|
*/
|
||||||
|
protected function addSpawner(string $name, callable $callback): RouteCollection
|
||||||
|
{
|
||||||
|
$this->_objectSpawners[$name] = $callback;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API to append a Spawner type on the list
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param callable $callback
|
||||||
|
* @return RouteCollection
|
||||||
|
*/
|
||||||
|
public static function appendObjectSpawner(string $name, callable $callback): RouteCollection
|
||||||
|
{
|
||||||
|
return self::getInstance()->addSpawner($name, $callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================
|
//=======================================================
|
||||||
@@ -299,11 +359,11 @@ class RouteCollection
|
|||||||
* Add a GET route
|
* Add a GET route
|
||||||
*
|
*
|
||||||
* @param string $uri URI to Match
|
* @param string $uri URI to Match
|
||||||
* @param string|callable $callback Callback to Execute. Might be a class or a callable
|
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||||
* @param int $weight Weight of the Route
|
* @param int $weight Weight of the Route
|
||||||
* @return Route
|
* @return Route
|
||||||
*/
|
*/
|
||||||
static function get(string $uri, string|callable $callback, int $weight = 0): Route
|
static function get(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||||
{
|
{
|
||||||
return self::add('GET', $uri, $callback, $weight);
|
return self::add('GET', $uri, $callback, $weight);
|
||||||
}
|
}
|
||||||
@@ -312,11 +372,11 @@ class RouteCollection
|
|||||||
* Add a CLI route
|
* Add a CLI route
|
||||||
*
|
*
|
||||||
* @param string $uri URI to Match
|
* @param string $uri URI to Match
|
||||||
* @param string|callable $callback Callback to Execute. Might be a class or a callable
|
* @param string|callable|array $callback Callback to Execute. Might be a class or a callable
|
||||||
* @param int $weight Weight of the Route
|
* @param int $weight Weight of the Route
|
||||||
* @return Route
|
* @return Route
|
||||||
*/
|
*/
|
||||||
static function cli(string $uri, string|callable $callback, int $weight = 0): Route
|
static function cli(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||||
{
|
{
|
||||||
return self::add('CLI', $uri, $callback, $weight);
|
return self::add('CLI', $uri, $callback, $weight);
|
||||||
}
|
}
|
||||||
@@ -325,11 +385,11 @@ class RouteCollection
|
|||||||
* Add a CLI route
|
* Add a CLI route
|
||||||
*
|
*
|
||||||
* @param string $uri URI to Match
|
* @param string $uri URI to Match
|
||||||
* @param string|callable $callback Callback to Execute. Might be a class or a callable
|
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||||
* @param int $weight Weight of the Route
|
* @param int $weight Weight of the Route
|
||||||
* @return Route
|
* @return Route
|
||||||
*/
|
*/
|
||||||
static function post(string $uri, string|callable $callback, int $weight = 0): Route
|
static function post(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||||
{
|
{
|
||||||
return self::add('POST', $uri, $callback, $weight);
|
return self::add('POST', $uri, $callback, $weight);
|
||||||
}
|
}
|
||||||
@@ -338,11 +398,11 @@ class RouteCollection
|
|||||||
* Add a CLI route
|
* Add a CLI route
|
||||||
*
|
*
|
||||||
* @param string $uri URI to Match
|
* @param string $uri URI to Match
|
||||||
* @param string|callable $callback Callback to Execute. Might be a class or a callable
|
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||||
* @param int $weight Weight of the Route
|
* @param int $weight Weight of the Route
|
||||||
* @return Route
|
* @return Route
|
||||||
*/
|
*/
|
||||||
static function put(string $uri, string|callable $callback, int $weight = 0): Route
|
static function put(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||||
{
|
{
|
||||||
return self::add('PUT', $uri, $callback, $weight);
|
return self::add('PUT', $uri, $callback, $weight);
|
||||||
}
|
}
|
||||||
@@ -351,11 +411,11 @@ class RouteCollection
|
|||||||
* Add a CLI route
|
* Add a CLI route
|
||||||
*
|
*
|
||||||
* @param string $uri URI to Match
|
* @param string $uri URI to Match
|
||||||
* @param string|callable $callback Callback to Execute. Might be a class or a callable
|
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||||
* @param int $weight Weight of the Route
|
* @param int $weight Weight of the Route
|
||||||
* @return Route
|
* @return Route
|
||||||
*/
|
*/
|
||||||
static function patch(string $uri, string|callable $callback, int $weight = 0): Route
|
static function patch(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||||
{
|
{
|
||||||
return self::add('PATCH', $uri, $callback, $weight);
|
return self::add('PATCH', $uri, $callback, $weight);
|
||||||
}
|
}
|
||||||
@@ -364,11 +424,11 @@ class RouteCollection
|
|||||||
* Add a CLI route
|
* Add a CLI route
|
||||||
*
|
*
|
||||||
* @param string $uri URI to Match
|
* @param string $uri URI to Match
|
||||||
* @param string|callable $callback Callback to Execute. Might be a class or a callable
|
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||||
* @param int $weight Weight of the Route
|
* @param int $weight Weight of the Route
|
||||||
* @return Route
|
* @return Route
|
||||||
*/
|
*/
|
||||||
static function delete(string $uri, string|callable $callback, int $weight = 0): Route
|
static function delete(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||||
{
|
{
|
||||||
return self::add('DELETE', $uri, $callback, $weight);
|
return self::add('DELETE', $uri, $callback, $weight);
|
||||||
}
|
}
|
||||||
@@ -390,11 +450,11 @@ class RouteCollection
|
|||||||
*
|
*
|
||||||
* @param Array|string $verb Verbs to match the Route
|
* @param Array|string $verb Verbs to match the Route
|
||||||
* @param string $uri URI to Match
|
* @param string $uri URI to Match
|
||||||
* @param string|callable $callback Callback to Execute. Might be a class or a callable
|
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||||
* @param int $weight Weight of the Route
|
* @param int $weight Weight of the Route
|
||||||
* @return Route
|
* @return Route
|
||||||
*/
|
*/
|
||||||
static function add(array|string $verb, string $uri, string|callable $callback, int $weight = 0): Route
|
static function add(array|string $verb, string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||||
{
|
{
|
||||||
$route = new Route();
|
$route = new Route();
|
||||||
|
|
||||||
@@ -406,17 +466,14 @@ class RouteCollection
|
|||||||
$uri = rtrim($uri, '/');
|
$uri = rtrim($uri, '/');
|
||||||
|
|
||||||
if (is_array($verb)) {
|
if (is_array($verb)) {
|
||||||
$route->_verb = array_map('strtoupper', $verb);
|
$route->setVerb(array_map('strtoupper', $verb));
|
||||||
} else if (strtoupper($verb) == 'WEB') {
|
} else if (strtoupper($verb) == 'WEB') {
|
||||||
$route->_verb = array_merge($route->_verb, self::$_verbsWeb);
|
$route->setVerb(array_merge($route->_verb, self::$_verbsWeb));
|
||||||
} else {
|
} else {
|
||||||
$route->_verb[] = strtoupper($verb);
|
$route->appendVerb(strtoupper($verb));
|
||||||
}
|
}
|
||||||
|
|
||||||
$route->_uri = $uri;
|
$route->setUri($uri)->setCallback($callback)->setWeight($weight)->prepare();
|
||||||
$route->_callback[] = $callback;
|
|
||||||
$route->_weight = $weight;
|
|
||||||
$route->prepare();
|
|
||||||
|
|
||||||
self::getInstance()->_routes[] = $route;
|
self::getInstance()->_routes[] = $route;
|
||||||
|
|
||||||
@@ -537,7 +594,7 @@ class RouteCollection
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$route->_before = array_merge($this->_defaultMiddlewares, $route->_before);
|
$route->setMiddlewares(array_merge($this->_defaultMiddlewares, $route->_before));
|
||||||
|
|
||||||
$routeResult = $route->execute();
|
$routeResult = $route->execute();
|
||||||
|
|
||||||
@@ -545,11 +602,6 @@ class RouteCollection
|
|||||||
$one_hit = true;
|
$one_hit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($route->_httpError) {
|
|
||||||
$this->httpError($route->_httpError);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->parseContent($routeResult);
|
$this->parseContent($routeResult);
|
||||||
|
|
||||||
if ($route->_block) { //If Executed, interrupt route chain?
|
if ($route->_block) { //If Executed, interrupt route chain?
|
||||||
|
|||||||
+10
-26
@@ -53,7 +53,7 @@ class RouteGroup
|
|||||||
function middlewareIgnore($name)
|
function middlewareIgnore($name)
|
||||||
{
|
{
|
||||||
foreach ($this->_routeGroup as $route) {
|
foreach ($this->_routeGroup as $route) {
|
||||||
$route->_middlewaresToIgnore[] = $name;
|
$route->middlewareIgnore($name);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -61,39 +61,23 @@ class RouteGroup
|
|||||||
function middlewareAdd($name)
|
function middlewareAdd($name)
|
||||||
{
|
{
|
||||||
foreach ($this->_routeGroup as $route) {
|
foreach ($this->_routeGroup as $route) {
|
||||||
$route->_before[] = $name;
|
$route->middlewareAdd($name);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
function middlewareAppend($name, $function)
|
//function middlewareAppend($name, $function)
|
||||||
{
|
//{
|
||||||
foreach ($this->_routeGroup as $route) {
|
// foreach ($this->_routeGroup as $route) {
|
||||||
$route->_before[$name] = $function;
|
// $route->_before[$name] = $function;
|
||||||
}
|
// }
|
||||||
return $this;
|
// return $this;
|
||||||
}
|
//}
|
||||||
|
|
||||||
function setWeight($weigth = 0)
|
function setWeight($weigth = 0)
|
||||||
{
|
{
|
||||||
foreach ($this->_routeGroup as $route) {
|
foreach ($this->_routeGroup as $route) {
|
||||||
$route->_weight = $weigth;
|
$route->setWeight($weigth);
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setHttpError($code = 400, $message = null)
|
|
||||||
{
|
|
||||||
foreach ($this->_routeGroup as $route) {
|
|
||||||
if ($message == null) {
|
|
||||||
$message = self::$httpMessages[$code];
|
|
||||||
}
|
|
||||||
|
|
||||||
$info = new \stdClass();
|
|
||||||
$info->code = $code;
|
|
||||||
$info->message = $message;
|
|
||||||
|
|
||||||
$route->_httpError = $info;
|
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user