Compare commits
14
Commits
33f5b7462b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2188d58fed | ||
|
|
84ed545c69 | ||
|
|
5b6d9553ac | ||
|
|
795062bb6d | ||
|
|
03e9f93e00 | ||
|
|
ee481dbe80 | ||
|
|
63f3820a2b | ||
|
|
05a330d65e | ||
|
|
5ac437d7c1 | ||
|
|
bfe57bc9b6 | ||
|
|
20161dcc5d | ||
|
|
5bdd6a3ebb | ||
|
|
2d4f222269 | ||
|
|
0d4a959a9e |
@@ -1,3 +1,465 @@
|
||||
# Routes
|
||||
# InforRoutes
|
||||
|
||||
A simple and dependency free routing system providing:
|
||||
|
||||
- Non blocking dispatch of system `WEB` and `CLI` functionalities
|
||||
- Parameters detection on the URL segments
|
||||
- Route grouping based on namespaces
|
||||
- Error handling and 404 detection
|
||||
- Attachable and global middlewares
|
||||
|
||||
## Usage
|
||||
|
||||
### Installation
|
||||
First install the package with `composer require inforsistemas/routes`. You might need to add a custom repository on the composer.json
|
||||
|
||||
```json
|
||||
"repositories": [{
|
||||
"type": "composer",
|
||||
"url": "https://satis.domain.com"
|
||||
}],
|
||||
```
|
||||
|
||||
|
||||
#### Hello World
|
||||
|
||||
With the dependencies and the server with the correct configuration, create a index.php with the content
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
include_once 'vendor/autoload.php';
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
// Add a route to the collection
|
||||
RouteCollection::get ("/", function(){
|
||||
return "Hello World";
|
||||
});
|
||||
|
||||
// Dispatch the router
|
||||
RouteCollection::getInstance()->submit();
|
||||
```
|
||||
|
||||
### Registering routes
|
||||
|
||||
#### The simple API to register routes
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::get("/", function(){ });
|
||||
RouteCollection::get("/form", function(){ });
|
||||
RouteCollection::post("/", function(){ });
|
||||
RouteCollection::get("/[i:id]", function($id){ });
|
||||
RouteCollection::put("/[i:id]", function($id){ });
|
||||
RouteCollection::patch("/[i:id]", function($id){ });
|
||||
RouteCollection::delete("/[i:id]", function($id){ });
|
||||
```
|
||||
|
||||
#### Passing a ClassPath string as argument.
|
||||
|
||||
Based on the defined autoloader, the library will instanciate the controller and execute the method.
|
||||
|
||||
The library will also try to infer the controller method signature and parse the URL parameters to the required type
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::get("/", "\App\SubPlugin\Plugin\PluginController@index");
|
||||
RouteCollection::get("/form", "\App\SubPlugin\Plugin\PluginController@create");
|
||||
RouteCollection::post("/", "\App\SubPlugin\Plugin\PluginController@store");
|
||||
RouteCollection::get("/[i:id]", "\App\SubPlugin\Plugin\PluginController@show");
|
||||
RouteCollection::put("/[i:id]", "\App\SubPlugin\Plugin\PluginController@update");
|
||||
RouteCollection::patch("/[i:id]", "\App\SubPlugin\Plugin\PluginController@update");
|
||||
RouteCollection::delete("/[i:id]", "\App\SubPlugin\Plugin\PluginController@destroy");
|
||||
```
|
||||
|
||||
#### Laravel Compatibility
|
||||
|
||||
Routes can be added with the Laravel way
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::get("/", [PluginController:class, "index"]);
|
||||
RouteCollection::get("/form", [PluginController:class, "create"]);
|
||||
RouteCollection::post("/", [PluginController:class, "store"]);
|
||||
RouteCollection::get("/[i:id]", [PluginController:class, "show"]);
|
||||
RouteCollection::put("/[i:id]", [PluginController:class, "update"]);
|
||||
RouteCollection::patch("/[i:id]", [PluginController:class, "update"]);
|
||||
RouteCollection::delete("/[i:id]", [PluginController:class, "destroy"]);
|
||||
```
|
||||
|
||||
#### RouteGroup
|
||||
|
||||
The library allows to nest routes on a `namespace`, applying the prefix on each route defined
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::group("/subplugin/plugin", function(){
|
||||
RouteCollection::get("/", "\App\SubPlugin\Plugin\PluginController@index");
|
||||
RouteCollection::get("/form", "\App\SubPlugin\Plugin\PluginController@create");
|
||||
RouteCollection::post("/", "\App\SubPlugin\Plugin\PluginController@store");
|
||||
RouteCollection::get("/[i:id]", "\App\SubPlugin\Plugin\PluginController@show");
|
||||
RouteCollection::put("/[i:id]", "\App\SubPlugin\Plugin\PluginController@update");
|
||||
RouteCollection::patch("/[i:id]", "\App\SubPlugin\Plugin\PluginController@update");
|
||||
RouteCollection::delete("/[i:id]", "\App\SubPlugin\Plugin\PluginController@destroy");
|
||||
});
|
||||
```
|
||||
|
||||
#### Setup/Service Routes
|
||||
|
||||
This library allows you to create sintetic routes with housekeeping features, for example:
|
||||
|
||||
* Setup plugins configurations
|
||||
* Building menus
|
||||
* Manipulate data before executing routes
|
||||
|
||||
**This snippet merges the content from `php://input` and `$_POST` on weight -10**
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::add("WEB", "*", function () {
|
||||
|
||||
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
return;
|
||||
}
|
||||
|
||||
$_POST = array_merge($_POST, (array) json_decode(file_get_contents('php://input')));
|
||||
|
||||
}, -10)->notBlock()->doIgnore();
|
||||
```
|
||||
|
||||
**This snippet create menus and submenus**
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::get('*', function() {
|
||||
Output::addSubmenu('menuname', 'Item name', "<i class='fa fa-globe'></i>", ['class' => 'nav-link'] );
|
||||
}, -11)->doIgnore();
|
||||
|
||||
RouteCollection::get('*', function () {
|
||||
Output::addOnSubmenu('menuname', '/url', 'SubItem name', "", ['class' => 'nav-link']);
|
||||
}, -10)->doIgnore();
|
||||
```
|
||||
|
||||
## Routes Properties
|
||||
|
||||
The routes can have some properties configured on them. This section will Describe them
|
||||
|
||||
### Blocking
|
||||
|
||||
The routing system will iterate over all the registered routes, when a Route is matched and it's not configured to block the execution, more routes on the chain might match and be executed.
|
||||
|
||||
The default behavior of a Route is **TO BLOCK** the executions when it is executed, but this behavior can be changed with the `notBlock()` method
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
// If executed, this route will not stop the matchin chain
|
||||
RouteCollection::get('*', function() { })->notBlock();
|
||||
```
|
||||
|
||||
### Ignore
|
||||
|
||||
If during the Routing process, the library didn't match any Route, a fallback `404` route will be executed. If you want a specific Route not to count on this process, you can ignore it with the function `doIgnore()`. The default behavior of routese is to **NOT IGNORE** the route.
|
||||
|
||||
Routes with this property assigned, will not prevent a `404` code. It is usefull for Setup/Service Routes.
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
// This route will execute, but will not count. Make some setup or preparation with this functionality
|
||||
RouteCollection::get('*', function() { })->doIgnore();
|
||||
```
|
||||
|
||||
### Weight
|
||||
|
||||
When adding a Route, you can define it's weight. Before dispatching the routing process, the route set will be sorted and the routes will be checked on the specified order. The library will execute all routes until it get blocked, so the Route order might matter on the execution.
|
||||
|
||||
The weight is the third argument on `get|post|put|patch|delete` functions and the fouth on the `add` method. You can also mannually define the weight with the `setWeight(int $weight)` function.
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
// This route has the wight 0, but it's redefined to -1
|
||||
RouteCollection::get('*', function() { }, 0)->setWeight(-1);
|
||||
```
|
||||
|
||||
### Name (#ToDo)
|
||||
|
||||
You can name your routes with the `name(string $name)` function
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::get("*", function(){ })->name('routeName');
|
||||
```
|
||||
|
||||
### Tag (#ToDo)
|
||||
|
||||
You can tag your routes with the `setTag(string|array $key, string $value)` function
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::get("*", function(){ })->setTag('group', 'value');
|
||||
|
||||
// Not implemented yet
|
||||
RouteCollection::get("*", function () { })->setTag(
|
||||
[
|
||||
['group', "value1"],
|
||||
["group2", "value2"]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
## Middlewares
|
||||
|
||||
The library provides a simple Middleware functionality.
|
||||
|
||||
You can register
|
||||
* Named Middlewares
|
||||
* AdHock Middlewares
|
||||
* Global Middlewares
|
||||
|
||||
This middlewares can be attached or removed from the Routes
|
||||
|
||||
### General Middlewares
|
||||
|
||||
A general Middlewares can be created with the API `RouteCollection::registerMiddleware(string $name, callable $function)` and will be stored as available on the `RouteCollection` Singleton.
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::registerMiddleware("myMiddleware", function($param){
|
||||
// Do some validation or stuff
|
||||
});
|
||||
```
|
||||
|
||||
This Middleware can be latter attached to Routes or RouteGroups with the function `middlewareAdd(string $name)`
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::get('*', function() { })->middlewareAdd("myMiddleware", Array("someValue"));
|
||||
|
||||
// #ToDo - Group Middlewares are not receaving parameters
|
||||
RouteCollection::group("/group", function(){ })->middlewareAdd("myMiddleware", Array("someValue"));
|
||||
```
|
||||
|
||||
### AdHock Middlewares
|
||||
|
||||
You can simply attach a function to be executed before the Route/Group execute with the `middlewareAppend(string $name, callable $callback)` function
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
// #ToDo Routes do not have this functionality yet
|
||||
RouteCollection::get('*', function() { })->middlewareAppend("myMiddleware", Array("someValue"));
|
||||
|
||||
// #ToDo Refactor the middleware API for the RouteGroup
|
||||
RouteCollection::group("/group", function(){ })->middlewareAppend("myMiddleware", Array("someValue"));
|
||||
```
|
||||
|
||||
### Default Middleware
|
||||
|
||||
Default middlewares can be registered on the `RouteCollection` with the function `addDefaultMiddleware(string $name, callable $function)` Singleton and will be executed before all Routes
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::addDefaultMiddleware("auth", function(Route $route){
|
||||
// Do some auth validation here
|
||||
});
|
||||
```
|
||||
|
||||
A Route/RouteGroup can also ignore a Default Middleware with the function `middlewareIgnore(string $name)`
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
// #ToDo Routes do not have this functionality yet
|
||||
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
|
||||
|
||||
#### Requirements
|
||||
|
||||
The following packages need to be installed for the project to run
|
||||
|
||||
* Apache
|
||||
- apache2 phpX.X phpX.X-fpm libapache2-mod-phpX.X
|
||||
* Nginx
|
||||
- nginx phpX.X phpX.X-fpm
|
||||
|
||||
The ports `80` and `443` must be open: `ufw allow 80 && ufw allow 443`
|
||||
|
||||
|
||||
|
||||
#### Apache
|
||||
|
||||
For apache, the basic required configuration
|
||||
|
||||
```
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin webmaster@localhost
|
||||
DocumentRoot /var/www/html/public
|
||||
ServerName example.com
|
||||
|
||||
<Directory /var/www >
|
||||
Options Indexes FollowSymLinks MultiViews
|
||||
AllowOverride All
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
For a server with HTTPs, the configuration with redirection
|
||||
|
||||
```
|
||||
<VirtualHost *:80>
|
||||
ServerName example.com
|
||||
Redirect / https://example.com
|
||||
</VirtualHost>
|
||||
|
||||
<IfModule mod_ssl.c>
|
||||
<VirtualHost *:443>
|
||||
|
||||
ServerAdmin webmaster@localhost
|
||||
DocumentRoot /var/www/html/public
|
||||
ServerName urfat.com.br
|
||||
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
|
||||
SSLCertificateFile /etc/letsencrypt/live/example.com.br/fullchain.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/example.com.br/privkey.pem
|
||||
Include /etc/letsencrypt/options-ssl-apache.conf
|
||||
</VirtualHost>
|
||||
</IfModule>
|
||||
```
|
||||
|
||||
#### Nginx
|
||||
|
||||
*For Nginx,this is the basic required configuration with PHP-FPM*
|
||||
|
||||
```
|
||||
server {
|
||||
listen 82 default_server;
|
||||
listen [::]:82 default_server;
|
||||
|
||||
server_name example.com;
|
||||
|
||||
root /var/www/html/public;
|
||||
index index.php index.html index.htm index.nginx-debian.html;
|
||||
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
include snippets/fastcgi-php.conf;
|
||||
#Check fpm-version
|
||||
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For a server with HTTPs, the configuration with redirection
|
||||
|
||||
```
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
listen 443 default_server ssl;
|
||||
|
||||
server_name example.com;
|
||||
|
||||
ssl_certificate /path/to/my/cert;
|
||||
ssl_certificate_key /path/to/my/key;
|
||||
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS:!AES256";
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_dhparam /path/to/my/dhp-4096.pem #sudo openssl dhparam -out /path/to/my/dhp-4096.pem 4096
|
||||
|
||||
if ($scheme = http) {
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Inner workings
|
||||
|
||||
The package consist in 3 main files, with `RouteCollection.php` providing the main API
|
||||
|
||||
- `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
|
||||
- `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 chained
|
||||
|
||||
## Other resources
|
||||
https://stackoverflow.com/questions/8054165/using-put-method-in-html-form
|
||||
Executable → Regular
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name" : "urfat/routes",
|
||||
"name" : "inforsistemas/routes",
|
||||
"description" : "Different Routes",
|
||||
"type" : "library",
|
||||
"authors" : [
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd sandbox/public
|
||||
sudo php -S 0.0.0.0:8081
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
use \App\Routes\RoutesController;
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::group("/routes", function(){
|
||||
RouteCollection::get("/", "\App\Routes\RoutesController@index");
|
||||
RouteCollection::get("/tag/[d:tag]", "\App\Routes\RoutesController@withTag");
|
||||
RouteCollection::get("/group/[d:group]", "\App\Routes\RoutesController@fromGroup");
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Routes;
|
||||
|
||||
use Routes\Route;
|
||||
use Routes\RouteCollection;
|
||||
|
||||
class RoutesController
|
||||
{
|
||||
|
||||
function index(): array
|
||||
{
|
||||
return array_map(function (Route $route) {
|
||||
return implode(" | ", $route->_verb) . " === $route->_uri";
|
||||
}, RouteCollection::getInstance()->_routes);
|
||||
}
|
||||
|
||||
function withTag(string $tag): array
|
||||
{
|
||||
return Array();
|
||||
}
|
||||
|
||||
function fromGroup(string $group): array
|
||||
{
|
||||
return Array();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Users\Clients;
|
||||
|
||||
class Client
|
||||
{
|
||||
|
||||
public private(set) int $id;
|
||||
public private(set) string $name;
|
||||
|
||||
private static Array $listOfFirstNames = [
|
||||
'ROBERTO', 'CIBELE', 'GILSA', 'TADEU', 'ELENICE', 'FRANCISCO', 'MARIA', 'JANAINA', 'RUBIA', 'MIRIAN', 'MARIA', 'EZIELMA', 'DEBORA', 'SILVANA', 'SELMA', 'RENICE', 'ALINE', 'ROSIMARA', 'ANDREA', 'JOSE', 'KATIUSCIA', 'GERALDO', 'WANDA', 'JUCIANE', 'ANTONIA', 'LUCIANA', 'CRISTIANE', 'ANA', 'MARIA', 'SANDRA', 'CONCEICAO', 'CRISTINA', 'VERA', 'ROMINA', 'MAX', 'EDMAR', 'NEIDE', 'TÂNIA', 'NARELAINE', 'SANDRA', 'ANGELA', 'ADRIANA', 'ANA', 'SIMONE', 'CRISTIANA', 'REDUZINA', 'RIVANIA', 'LUCIANA', 'ANANDA', 'CLAUDIA', 'LUCIANA', 'DANIELLE', 'CLAUDIA', 'FERNANDA', 'LUCIANE', 'RENATA', 'ROBERTO', 'PAULO', 'REGINA', 'JOSE', 'EVERALDO', 'SHEILA', 'CARMEM', 'CATIA', 'JOSE', 'ANGELITA', 'EDGARD', 'CLEBER', 'WILSON', 'EDNA', 'RITA', 'JOSELMA', 'MAURO', 'ANA', 'AUGUSTO', 'HAMILTON', 'JOANESLEY', 'JORGE', 'SUZAN', 'JOVANDIR', 'JOAO', 'RENATA', 'LETICIA', 'JAQUELINE', 'ILNA', 'AMELIA', 'PEDRO', 'JULIO', 'REUS', 'LEDA', 'VIRGINIA', 'FRANCEROSE', 'MAURO'
|
||||
];
|
||||
|
||||
private static Array $listOfMiddleNames = [
|
||||
'TERNES', 'AMOROSO', 'GISELE', 'AMOROSO', 'DIVINA', 'VIANA', 'LUIZA', 'MONICI', 'CARLA', 'CONCEICAO', 'VALREZ', 'ALVES', 'FRAGOSO', 'GOULART', 'BARROS', 'SUMAN', 'MENS', 'MORESCHI', 'NARA', 'ANTONIO', 'LUCAS', 'ALMEIDA', 'LOPES', 'MELO', 'BERTULLI', 'KARINA', 'DAS', 'NIEL', 'FIGUEREDO', 'TIBURCIO', 'LUCIA', 'DIAS', 'JUCA', 'TEIXEIRA', 'LUCIA', 'MARIA', 'GOMES', 'CRISTINA', 'MARIA', 'PAULA', 'ALMEIDA', 'PROCOPIO', 'LIMA', 'TABOSA', 'MENEZES', 'JORGE', 'GONCALVES', 'MARIA', 'NEVES', 'BASTOS', 'TAU', 'CÉSAR', 'D\'ARC', 'REINALDO', 'CRISTINA', 'LUCIA', 'JOSÉ', 'EDUARDO', 'AMARANTE', 'FELIX', 'VILLA', 'PEREIRA', 'MARIA', 'RAMOS', 'ROMAO', 'LUCIA', 'PAZ', 'BATUIRA', 'ARY', 'PAULA', 'BOTELHO', 'BATISTA', 'FURTADO', 'HARDMANN', 'CRISTINA', 'LUIZ', 'CÉSAR', 'ANTUNES', 'MARCIA', 'SOFIA', 'CLARA', 'ORLANDO', 'CHARLES', 'PAULA', 'FERREIRA', 'CRISTINA', 'UBALDINO'
|
||||
];
|
||||
|
||||
private static Array $listOfLastNames = [
|
||||
'ASSIS', 'ROCHA', 'JUNIOR', 'LIMA', 'MAGALHAES', 'MOURA', 'REIS', 'SILVA', 'SILVANO', 'ARRIAL', 'MAIA', 'SANTANA', 'GONCALVES', 'FILHO', 'SOUZA', 'LOPES', 'TEIXEIRA', 'SOUSA', 'DANTAS', 'PERES', 'MARQUES', 'MELO', 'CARVALHO', 'CUNHA', 'BARBOSA', 'LEMOS', 'GUIMARAES', 'CIPRIANO', 'MESQUITA', 'ALMEIDA', 'MONTEIRO', 'OLIVEIRA', 'PONCE', 'RIBEIRO', 'VIEIRA', 'KOKAY', 'MIZIARA', 'GONÇALVES', 'NEVES', 'CRUZ', 'MAGELA', 'TRINDADE', 'FALCAO', 'CUSTODIO', 'LEITE', 'INACIO', 'RODRIGUES', 'RAMOS', 'VALENÇA', 'NOBRE', 'MOREIRA', 'MORAES', 'GARCIA', 'FLOR', 'PINTO', 'MOUTA', 'TARACHUK', 'LEAL', 'TELES', 'VALENCA', 'ARARIPE', 'BEVILACQUA', 'MATOS', 'DUMONT', 'ALBUQUERQUE', 'NOGUEIRA'
|
||||
];
|
||||
|
||||
/**
|
||||
* Client Constructor
|
||||
*
|
||||
* @param int $id
|
||||
*/
|
||||
function __construct(int $id = 0)
|
||||
{
|
||||
if($id == 0){
|
||||
return;
|
||||
}
|
||||
$this->id = $id;
|
||||
$this->name = self::generateRandomName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random Client Name
|
||||
*
|
||||
* @param int $id Id of the Client
|
||||
* @return string
|
||||
*/
|
||||
public static function generateClient(int $id): Client
|
||||
{
|
||||
|
||||
return new Client($id);
|
||||
}
|
||||
|
||||
public static function generateRandomName(): string
|
||||
{
|
||||
$firstname = self::$listOfFirstNames[rand(0, sizeof(self::$listOfFirstNames) - 1)];
|
||||
$middleName = self::$listOfMiddleNames[rand(0, sizeof(self::$listOfMiddleNames) - 1)];
|
||||
$lastName = self::$listOfLastNames[rand(0, sizeof(self::$listOfLastNames) - 1)];
|
||||
|
||||
return "$firstname $middleName $lastName";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Users\Clients;
|
||||
|
||||
use App\Users\Clients\Client as Client;
|
||||
|
||||
class ClientsController
|
||||
{
|
||||
|
||||
/**
|
||||
* Return a random Client list
|
||||
* @param array $users
|
||||
* @return array
|
||||
*/
|
||||
function index(Array $users = Array()): Array
|
||||
{
|
||||
for ($i=0; $i < rand(20, 100); $i++) {
|
||||
$users[$i] = Client::generateClient($i);
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
function raw(){
|
||||
|
||||
}
|
||||
|
||||
function show(Client $client): Client
|
||||
{
|
||||
return $client;
|
||||
}
|
||||
|
||||
function print(Client $client): string
|
||||
{
|
||||
return "{$client->id} - " . $client->name;
|
||||
}
|
||||
|
||||
function fullBuild(Client $client, Permission $permission, Config $config, bool $ignoreCache = true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
function crazyTest(Client $client, Permission $permission, Config $config, bool $ignoreCache = true): Array
|
||||
{
|
||||
return [$client, $permission, $config, $ignoreCache];
|
||||
}
|
||||
|
||||
function dump(Client $client, Permission $permission, Config $config, bool $ignoreCache = true): Array
|
||||
{
|
||||
return [$client, $permission, $config, $ignoreCache];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Users\Clients;
|
||||
|
||||
class Config
|
||||
{
|
||||
function __construct(){}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Users\Clients;
|
||||
|
||||
class Permission {
|
||||
|
||||
public private(set) int $id;
|
||||
public private(set) string $name;
|
||||
public private(set) string $displayName;
|
||||
|
||||
private static array $permissions = [
|
||||
"user-edit" => [
|
||||
"id" => 1,
|
||||
"name" => "user-edit",
|
||||
"displayName" => "Editar Usuário"
|
||||
],
|
||||
"user-delete" => [
|
||||
"id" => 2,
|
||||
"name" => "user-delete",
|
||||
"displayName" => "Apagar Usuário"
|
||||
]
|
||||
];
|
||||
|
||||
function __construct(string $permission = ''){
|
||||
if(isset(self::$permissions[$permission])){
|
||||
$permission = (object) self::$permissions[$permission];
|
||||
|
||||
$this->id = $permission->id;
|
||||
$this->name = $permission->name;
|
||||
$this->displayName = $permission->displayName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use \App\Users\Clients\ClientsController;
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
use App\Users\Clients\Config;
|
||||
use App\Users\Clients\Client;
|
||||
use App\Users\Clients\Permission;
|
||||
|
||||
|
||||
RouteCollection::group("/users/clients", function(){
|
||||
RouteCollection::get("/", "\App\Users\Clients\ClientsController@index");
|
||||
RouteCollection::get("/raw", "\App\Users\Clients\ClientsController@raw");
|
||||
RouteCollection::get("/[i:id]", "\App\Users\Clients\ClientsController@show");
|
||||
RouteCollection::get("/print/[i:id]", "\App\Users\Clients\ClientsController@print");
|
||||
//RouteCollection::get("/print/[i:id]", [ClientsController::class, "print"]);
|
||||
});
|
||||
|
||||
RouteCollection::get("/user/simple/[i:id]/coisa/[s:slug]/[s:version]/list", function (Client $client, Permission $permission, Config $config, bool $ignoreCache = true): array{
|
||||
return [$client, $permission, $config, $ignoreCache];
|
||||
});
|
||||
|
||||
RouteCollection::get("/teste/[i:id]/coisa/[s:slug]/[s:version]/list", "\App\Users\Clients\ClientsController@crazyTest");
|
||||
RouteCollection::get("/user/simple/[i:id]/coisa/[s:slug]/[s:version]/dump", [ClientsController::class, "dump"]);
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
include_once 'includes.php';
|
||||
|
||||
use Routes\RouteCollection as RouteCollection;
|
||||
|
||||
RouteCollection::error("404", function () {
|
||||
http_response_code(404);
|
||||
echo "Woops - Not Found";
|
||||
});
|
||||
|
||||
RouteCollection::getInstance()->crawl(__DIR__ . "/app")->loadRoutes();
|
||||
RouteCollection::getInstance()->submit();
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
include_once(__DIR__ . "/../src/Routes/Route.php");
|
||||
include_once(__DIR__ . "/../src/Routes/RouteGroup.php");
|
||||
include_once(__DIR__ . "/../src/Routes/HTTPCodes.php");
|
||||
include_once(__DIR__ . "/../src/Routes/ObjectSpawners.php");
|
||||
include_once(__DIR__ . "/../src/Routes/RouteCollection.php");
|
||||
|
||||
spl_autoload_register(function ($className) {
|
||||
$path = explode('\\', $className);
|
||||
$fileName = $path[sizeof($path) - 1];
|
||||
|
||||
$path[sizeof($path) - 1] = '';
|
||||
|
||||
$path = __DIR__ ."/". strtolower(implode(DIRECTORY_SEPARATOR, $path));
|
||||
|
||||
if (is_file($path . $fileName . '.php')) {
|
||||
return include $path . $fileName . '.php';
|
||||
}
|
||||
|
||||
if (is_file(strtolower($path . $fileName . '.php'))) {
|
||||
return include strtolower($path . $fileName . '.php');
|
||||
}
|
||||
|
||||
@include $path . $fileName . '.php';
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
include '../bootstrap.php';
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace Routes;
|
||||
|
||||
/**
|
||||
* HTTP Status Codes Enum
|
||||
*
|
||||
* Represents standard HTTP response status codes with descriptive messages.
|
||||
* Supports querying code categories and retrieving status information.
|
||||
*/
|
||||
enum HTTPCodes: int
|
||||
{
|
||||
// Informational 1xx
|
||||
case CONTINUE = 100;
|
||||
case SWITCHING_PROTOCOLS = 101;
|
||||
|
||||
// Successful 2xx
|
||||
case OK = 200;
|
||||
case CREATED = 201;
|
||||
case ACCEPTED = 202;
|
||||
case NON_AUTHORITATIVE_INFORMATION = 203;
|
||||
case NO_CONTENT = 204;
|
||||
case RESET_CONTENT = 205;
|
||||
case PARTIAL_CONTENT = 206;
|
||||
|
||||
// Redirection 3xx
|
||||
case MULTIPLE_CHOICES = 300;
|
||||
case MOVED_PERMANENTLY = 301;
|
||||
case FOUND = 302;
|
||||
case SEE_OTHER = 303;
|
||||
case NOT_MODIFIED = 304;
|
||||
case USE_PROXY = 305;
|
||||
case TEMPORARY_REDIRECT = 307;
|
||||
|
||||
// Client Error 4xx
|
||||
case BAD_REQUEST = 400;
|
||||
case UNAUTHORIZED = 401;
|
||||
case PAYMENT_REQUIRED = 402;
|
||||
case FORBIDDEN = 403;
|
||||
case NOT_FOUND = 404;
|
||||
case METHOD_NOT_ALLOWED = 405;
|
||||
case NOT_ACCEPTABLE = 406;
|
||||
case PROXY_AUTHENTICATION_REQUIRED = 407;
|
||||
case REQUEST_TIMEOUT = 408;
|
||||
case CONFLICT = 409;
|
||||
case GONE = 410;
|
||||
case LENGTH_REQUIRED = 411;
|
||||
case PRECONDITION_FAILED = 412;
|
||||
case REQUEST_ENTITY_TOO_LARGE = 413;
|
||||
case REQUEST_URI_TOO_LONG = 414;
|
||||
case UNSUPPORTED_MEDIA_TYPE = 415;
|
||||
case REQUESTED_RANGE_NOT_SATISFIABLE = 416;
|
||||
case EXPECTATION_FAILED = 417;
|
||||
|
||||
// Server Error 5xx
|
||||
case INTERNAL_SERVER_ERROR = 500;
|
||||
case NOT_IMPLEMENTED = 501;
|
||||
case BAD_GATEWAY = 502;
|
||||
case SERVICE_UNAVAILABLE = 503;
|
||||
case GATEWAY_TIMEOUT = 504;
|
||||
case HTTP_VERSION_NOT_SUPPORTED = 505;
|
||||
|
||||
/**
|
||||
* Get the human-readable message for this status code
|
||||
*/
|
||||
public function message(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::CONTINUE => 'Continue',
|
||||
self::SWITCHING_PROTOCOLS => 'Switching Protocols',
|
||||
self::OK => 'OK',
|
||||
self::CREATED => 'Created',
|
||||
self::ACCEPTED => 'Accepted',
|
||||
self::NON_AUTHORITATIVE_INFORMATION => 'Non-Authoritative Information',
|
||||
self::NO_CONTENT => 'No Content',
|
||||
self::RESET_CONTENT => 'Reset Content',
|
||||
self::PARTIAL_CONTENT => 'Partial Content',
|
||||
self::MULTIPLE_CHOICES => 'Multiple Choices',
|
||||
self::MOVED_PERMANENTLY => 'Moved Permanently',
|
||||
self::FOUND => 'Found',
|
||||
self::SEE_OTHER => 'See Other',
|
||||
self::NOT_MODIFIED => 'Not Modified',
|
||||
self::USE_PROXY => 'Use Proxy',
|
||||
self::TEMPORARY_REDIRECT => 'Temporary Redirect',
|
||||
self::BAD_REQUEST => 'Bad Request',
|
||||
self::UNAUTHORIZED => 'Unauthorized',
|
||||
self::PAYMENT_REQUIRED => 'Payment Required',
|
||||
self::FORBIDDEN => 'Forbidden',
|
||||
self::NOT_FOUND => 'Not Found',
|
||||
self::METHOD_NOT_ALLOWED => 'Method Not Allowed',
|
||||
self::NOT_ACCEPTABLE => 'Not Acceptable',
|
||||
self::PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required',
|
||||
self::REQUEST_TIMEOUT => 'Request Timeout',
|
||||
self::CONFLICT => 'Conflict',
|
||||
self::GONE => 'Gone',
|
||||
self::LENGTH_REQUIRED => 'Length Required',
|
||||
self::PRECONDITION_FAILED => 'Precondition Failed',
|
||||
self::REQUEST_ENTITY_TOO_LARGE => 'Request Entity Too Large',
|
||||
self::REQUEST_URI_TOO_LONG => 'Request-URI Too Long',
|
||||
self::UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type',
|
||||
self::REQUESTED_RANGE_NOT_SATISFIABLE => 'Requested Range Not Satisfiable',
|
||||
self::EXPECTATION_FAILED => 'Expectation Failed',
|
||||
self::INTERNAL_SERVER_ERROR => 'Internal Server Error',
|
||||
self::NOT_IMPLEMENTED => 'Not Implemented',
|
||||
self::BAD_GATEWAY => 'Bad Gateway',
|
||||
self::SERVICE_UNAVAILABLE => 'Service Unavailable',
|
||||
self::GATEWAY_TIMEOUT => 'Gateway Timeout',
|
||||
self::HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version Not Supported',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this is a successful response (2xx)
|
||||
*/
|
||||
public function isSuccess(): bool
|
||||
{
|
||||
return $this->value >= 200 && $this->value < 300;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this is a client error (4xx)
|
||||
*/
|
||||
public function isClientError(): bool
|
||||
{
|
||||
return $this->value >= 400 && $this->value < 500;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this is a server error (5xx)
|
||||
*/
|
||||
public function isServerError(): bool
|
||||
{
|
||||
return $this->value >= 500 && $this->value < 600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this is a redirect (3xx)
|
||||
*/
|
||||
public function isRedirect(): bool
|
||||
{
|
||||
return $this->value >= 300 && $this->value < 400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this is informational (1xx)
|
||||
*/
|
||||
public function isInformational(): bool
|
||||
{
|
||||
return $this->value >= 100 && $this->value < 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the category name for this status code
|
||||
*/
|
||||
public function category(): string
|
||||
{
|
||||
return match (true) {
|
||||
$this->isInformational() => 'Informational',
|
||||
$this->isSuccess() => 'Success',
|
||||
$this->isRedirect() => 'Redirection',
|
||||
$this->isClientError() => 'Client Error',
|
||||
$this->isServerError() => 'Server Error',
|
||||
default => 'Unknown',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an HTTPCodes enum from an integer code
|
||||
* Returns null if code doesn't exist
|
||||
*/
|
||||
public static function tryFromCode(int $code): ?self
|
||||
{
|
||||
return self::tryFrom($code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<?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];
|
||||
continue;
|
||||
}
|
||||
|
||||
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];
|
||||
continue;
|
||||
}
|
||||
|
||||
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];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($routeParameters[$key])) {
|
||||
$class = $signatureItem->getType()->__tostring();
|
||||
$returnParameters[] = new $class($routeParameters[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $returnParameters;
|
||||
};
|
||||
}
|
||||
}
|
||||
+313
-243
@@ -2,203 +2,259 @@
|
||||
|
||||
namespace Routes;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
use Clousure;
|
||||
|
||||
class Route {
|
||||
/*
|
||||
* HTTP VERB
|
||||
/**
|
||||
* Summary of Route
|
||||
*/
|
||||
class Route
|
||||
{
|
||||
public private(set) Array $_verb = Array(); // Route Verbs to match
|
||||
public private(set) string $_source; // Execution Source (HTTP | Cli | SOAP)
|
||||
public private(set) string $_name; // Route Name
|
||||
public private(set) string $_uri; // Route URI
|
||||
public private(set) int $_weight = 0; // Wight of the route, for sorting
|
||||
public private(set) Array $_uriSegments = Array(); // Route Full URI Segments
|
||||
public private(set) Array $_segments = Array(); // Route parsed URI Segments
|
||||
public private(set) Array $_params = Array(); // Prepared Routes parameters
|
||||
public private(set) Array $_before = Array(); // Functions to execute Before the Route
|
||||
public private(set) mixed $_callback; // Route Callback
|
||||
public private(set) Array $_after = Array(); // Functions to execute After the Route
|
||||
public private(set) string $_regex = ''; // The URI regex to match
|
||||
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 private(set) Array $_middlewaresToIgnore = Array(); // Middlewares this Route will ignore
|
||||
public private(set) Array $_tags = Array(); // Tags of the Route
|
||||
public private(set) Array $_variableSegments = Array(); // Segments of the route that are variables
|
||||
|
||||
public $_verb = Array();
|
||||
/*
|
||||
* Execution Source
|
||||
* HTTP | Cli | SOAP |
|
||||
*/
|
||||
public $_source;
|
||||
|
||||
/*
|
||||
* URI String
|
||||
*/
|
||||
public $_uri;
|
||||
|
||||
/*
|
||||
* Routes dispatch priority
|
||||
*/
|
||||
public $_weight = 0;
|
||||
|
||||
/*
|
||||
* URI Segments
|
||||
*/
|
||||
public $_uriSegments = Array();
|
||||
|
||||
/*
|
||||
* Extracted params
|
||||
*/
|
||||
public $_segments = Array();
|
||||
|
||||
/*
|
||||
* Prepared params
|
||||
*/
|
||||
public $_params = Array();
|
||||
|
||||
/*
|
||||
* Execute before dispatch route
|
||||
*/
|
||||
public $_before = Array();
|
||||
|
||||
/*
|
||||
* Route callback
|
||||
*/
|
||||
public $_callback = Array();
|
||||
|
||||
/*
|
||||
* Execute after route dispatched
|
||||
*/
|
||||
public $_after = Array();
|
||||
|
||||
/*
|
||||
* Prepared RegEx
|
||||
*/
|
||||
public $_regex = '';
|
||||
|
||||
/*
|
||||
* Can execute other route after this one?
|
||||
*/
|
||||
public $_block = false;
|
||||
|
||||
/*
|
||||
* Is there a problem witch one?
|
||||
*/
|
||||
public $_httpError = false;
|
||||
|
||||
/*
|
||||
* This rout should be counted?
|
||||
*/
|
||||
public $_ignore = false;
|
||||
|
||||
/*
|
||||
* Middlewares to remove from the list
|
||||
*/
|
||||
public $_middlewaresToIgnore = Array();
|
||||
/*
|
||||
* From Klein
|
||||
* HTTP status List
|
||||
*/
|
||||
protected static $httpMessages = array(
|
||||
// Informational 1xx
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
// Successful 2xx
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
// Redirection 3xx
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found',
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
306 => '(Unused)',
|
||||
307 => 'Temporary Redirect',
|
||||
// Client Error 4xx
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
402 => 'Payment Required',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
// Server Error 5xx
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported',
|
||||
);
|
||||
|
||||
//=======================================================
|
||||
function execute() {
|
||||
//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);
|
||||
// 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
|
||||
*
|
||||
* @param string $name
|
||||
* @return Route
|
||||
*/
|
||||
function setName(string $name): Route
|
||||
{
|
||||
$this->_name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the route URI
|
||||
*
|
||||
* @param mixed $uri
|
||||
*
|
||||
* @return Route
|
||||
*/
|
||||
function setUri($uri): Route
|
||||
{
|
||||
$this->_uri = $uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of segments of the route
|
||||
* @return array
|
||||
*/
|
||||
function getSegments(): array
|
||||
{
|
||||
return $this->_segments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define that this route will not block the execution
|
||||
*
|
||||
* @return Route
|
||||
*/
|
||||
function notBlock(): Route
|
||||
{
|
||||
$this->_block = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define that this route will be ignored on the counting
|
||||
* if no routes match, we will throw a Excepton
|
||||
*
|
||||
* @return Route
|
||||
*/
|
||||
function doIgnore(): Route
|
||||
{
|
||||
$this->_ignore = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a tag for this Route
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return Route
|
||||
*/
|
||||
function setTag(string $key, string $value): Route
|
||||
{
|
||||
$this->_tags[$key][] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this Route has a specific tag
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
function hasTag(string $key): bool
|
||||
{
|
||||
return array_key_exists($key, $this->_tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Route weight
|
||||
*
|
||||
* @param int $weigth
|
||||
* @return Route
|
||||
*/
|
||||
function setWeight(int $weigth = 0): Route
|
||||
{
|
||||
$this->_weight = $weigth;
|
||||
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
|
||||
//
|
||||
|
||||
/**
|
||||
* Set Variables Segments to pass as function args
|
||||
*
|
||||
* @param string $segment
|
||||
* @return void
|
||||
*/
|
||||
function registerVariableSegment(string $segment): void
|
||||
{
|
||||
if($segment == ""){
|
||||
return;
|
||||
}
|
||||
|
||||
$segment = str_replace("]", "", str_replace("[", "", $segment));
|
||||
$segments = explode(":", $segment);
|
||||
|
||||
if(sizeof($segments) == 1){
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($segments[0]) {
|
||||
case 'i':
|
||||
$this->_variableSegments[] = ["name" => $segments[1], "type" => "int"];
|
||||
break;
|
||||
default:
|
||||
$this->_variableSegments[] = ["name" => $segments[1], "type" => "string"];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->_callback as $callback) {
|
||||
if (is_string($callback)) {
|
||||
$segments = explode('@', $callback);
|
||||
$class = new $segments[0]();
|
||||
|
||||
$r = new \ReflectionMethod($segments[0], $segments[1]);
|
||||
|
||||
if (sizeof($r->getParameters()) > 0 && $r->getParameters()[0]->getClass() != NULL) {
|
||||
$element;
|
||||
$element = $r->getParameters()[0]->getClass()->name;
|
||||
$element = new $element;
|
||||
if(isset($this->_params['id'])){
|
||||
$element->load($this->_params['id']);
|
||||
}
|
||||
$this->_params['id'] = $element;
|
||||
}
|
||||
$class->{$segments[1]}(...array_values($this->_params));
|
||||
} else {
|
||||
$r = new \ReflectionFunction($callback);
|
||||
if(sizeof($r->getParameters()) > 0 && $r->getParameters()[0]->getClass() != NULL){
|
||||
$element;
|
||||
$element = $r->getParameters()[0]->getClass()->name;
|
||||
$element = new $element;
|
||||
if(isset($this->_params['id'])){
|
||||
$element->load($this->_params['id']);
|
||||
}
|
||||
$this->_params['id'] = $element;
|
||||
}
|
||||
call_user_func_array($callback, $this->_params);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->_after as $after) {
|
||||
call_user_func($after);
|
||||
}
|
||||
}
|
||||
|
||||
function prepare() {
|
||||
/**
|
||||
* Prepare the route placeholders
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function prepare()
|
||||
{
|
||||
$this->_segments = explode('/', $this->_uri);
|
||||
|
||||
foreach ($this->_segments as $segment) {
|
||||
$this->registerVariableSegment($segment);
|
||||
|
||||
if (strpos($segment, 'i:') > -1) {
|
||||
$this->_regex .= "\/[0-9]+";
|
||||
} else if (strpos($segment, 'h:') > -1) {
|
||||
$this->_regex .= "\/[A-z]+";
|
||||
} else if (strpos($segment, 'd:') > -1) {
|
||||
$this->_regex .= "\/[A-z0-9]+";
|
||||
} else if (strpos($segment, 's:') > -1) {
|
||||
$this->_regex .= "\/[A-z0-9\-_]+";
|
||||
} else if (strpos($segment, 'r:') > -1) {
|
||||
$this->_regex .= "\/[ -~]+";
|
||||
} else {
|
||||
@@ -209,7 +265,13 @@ class Route {
|
||||
$this->_regex = "/^\/" . $this->_regex . "$/";
|
||||
}
|
||||
|
||||
function createIndexes() {
|
||||
/**
|
||||
* Split the route segments into indexes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function createIndexes()
|
||||
{
|
||||
foreach ($this->_segments as $key => $segment) {
|
||||
if (preg_match('/\[.*?\]$/', $segment)) {
|
||||
$segment = trim(trim($segment, '['), ']');
|
||||
@@ -219,68 +281,14 @@ class Route {
|
||||
}
|
||||
}
|
||||
|
||||
function setUri($uri) {
|
||||
$this->_uri = $uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function getSegments() {
|
||||
return $this->_segments;
|
||||
}
|
||||
|
||||
function doBlock() {
|
||||
$this->_block = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function notBlock() {
|
||||
$this->_block = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function doIgnore() {
|
||||
$this->_ignore = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function notIgnore() {
|
||||
$this->_ignore = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function middlewareIgnore($name = '') {
|
||||
$this->_middlewaresToIgnore[] = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function middlewareAdd($name = '', $params) {
|
||||
$this->_before[$name] = $params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function middlewareAppend($name = '', $function) {
|
||||
$this->_before[$name] = $function;
|
||||
}
|
||||
|
||||
function setWeight($weigth = 0) {
|
||||
$this->_weight = $weigth;
|
||||
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;
|
||||
}
|
||||
|
||||
function match($uri) {
|
||||
/**
|
||||
* Check if the URI match the Route Signature
|
||||
*
|
||||
* @param string $uri
|
||||
* @return bool
|
||||
*/
|
||||
function match(string $uri): bool
|
||||
{
|
||||
//Wildcards allways match
|
||||
if (in_array('*', $this->_verb) || $this->_uri == '*') {
|
||||
return true;
|
||||
@@ -295,5 +303,67 @@ class Route {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
function compress($group, $tag)
|
||||
{
|
||||
//$pattern = '/\[a:(\w+)\]/';
|
||||
//$replacement = '/{{$1}}/';
|
||||
//$route = preg_replace($pattern, $replacement, $this->_uri) );
|
||||
|
||||
$route = str_replace(['[i:', '[d:'], '{{', $this->_uri);
|
||||
$route = str_replace([']', ']'], '}}', $route);
|
||||
|
||||
return [
|
||||
'name' => $this->_name,
|
||||
'group' => $group,
|
||||
'tag' => $tag,
|
||||
'verbs' => $this->_verb,
|
||||
//'route' => preg_replace($pattern, $replacement, $this->_uri)
|
||||
'route' => $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;
|
||||
}
|
||||
}
|
||||
|
||||
+499
-209
@@ -2,32 +2,52 @@
|
||||
|
||||
namespace Routes;
|
||||
|
||||
class RouteCollection {
|
||||
use stdClass;
|
||||
use Exception;
|
||||
|
||||
private static $_routeCollection;
|
||||
class RouteCollection
|
||||
{
|
||||
|
||||
public $_uri = '/';
|
||||
public $_routes = Array();
|
||||
private $_verb = '';
|
||||
private $_loadedFiles = Array();
|
||||
private $_errors = Array();
|
||||
private $_defaultMiddlewares = Array();
|
||||
private $_middlewareSet = Array();
|
||||
private static $_verbsWhitelist = Array('*', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'CLI');
|
||||
private static $_verbsWeb = Array('GET', 'POST', 'PUT', 'PATCH', 'DELETE');
|
||||
private static RouteCollection $_routeCollection;
|
||||
|
||||
public $_groupIn = false;
|
||||
public $_groupBase = '';
|
||||
public $_groupList = [];
|
||||
public private(set) string $_uri = '/';
|
||||
public private(set) Array $_routes = Array();
|
||||
public private(set) string $_verb = '';
|
||||
public private(set) Array $_loadedFiles = Array();
|
||||
public private(set) Array $_errors = Array();
|
||||
public private(set) Array $_defaultMiddlewares = Array();
|
||||
public private(set) Array $_middlewareSet = Array();
|
||||
public private(set) bool $_groupIn = false;
|
||||
public private(set) string $_groupBase = '';
|
||||
public private(set) Array $_groupList = Array();
|
||||
public private(set) Array $_groups = Array();
|
||||
public private(set) Array $_contentParsers = Array(); // Configure parsers for possible Route Returns
|
||||
public private(set) Route $_currentRoute; // The Route Being Dispatched
|
||||
public private(set) bool $_trace = false; // For debuggin
|
||||
public private(set) int $_traceVerbosity = 1; // How Verbose to trace
|
||||
public private(set) Array $_objectSpawners = Array();
|
||||
|
||||
private static Array $_verbsWhitelist = Array('*', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'CLI');
|
||||
private static Array $_verbsWeb = Array('GET', 'POST', 'PUT', 'PATCH', 'DELETE');
|
||||
|
||||
//SINGLETON==============================================
|
||||
|
||||
private function __construct() {
|
||||
//=======================================================
|
||||
// SINGLETON
|
||||
//
|
||||
|
||||
/**
|
||||
* Empty constructor for Singleton
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
private static function newObj() {
|
||||
/**
|
||||
* Instanciate the Singleton Object
|
||||
*
|
||||
* @return RouteCollection
|
||||
*/
|
||||
private static function newObj(): RouteCollection
|
||||
{
|
||||
if (!isset(self::$_routeCollection)) {
|
||||
self::$_routeCollection = new RouteCollection();
|
||||
if (php_sapi_name() == "cli") {
|
||||
@@ -35,38 +55,49 @@ class RouteCollection {
|
||||
} else {
|
||||
self::$_routeCollection->_uri = isset($_SERVER['REQUEST_URI']) ? explode('?', $_SERVER['REQUEST_URI'])[0] : '/';
|
||||
}
|
||||
|
||||
self::$_routeCollection->defineVerb();
|
||||
self::$_routeCollection->setDefaultParsers();
|
||||
self::$_routeCollection->setDefaultObjectSpawners();
|
||||
}
|
||||
self::$_routeCollection->_uri = str_replace("//", "/", self::$_routeCollection->_uri);
|
||||
return self::$_routeCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Singleton instance
|
||||
*
|
||||
* @return RouteCollection
|
||||
*/
|
||||
public static function getInstance() {
|
||||
public static function getInstance(): RouteCollection
|
||||
{
|
||||
if (!isset(self::$_routeCollection)) {
|
||||
return self::newObj();
|
||||
}
|
||||
return self::$_routeCollection;
|
||||
}
|
||||
|
||||
//HELPERS================================================
|
||||
//=======================================================
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
/*
|
||||
* Find route files with names under pathname
|
||||
/**
|
||||
* Crawl the filesystem to find the System Routes
|
||||
*
|
||||
* @ctag\t RouteCollection->crawl()
|
||||
* @param string $basePath Path to crawl
|
||||
* @param array $filenames Filenames to Match
|
||||
* @return RouteCollection
|
||||
*/
|
||||
public function crawl($basepath = __DIR__, $filenames = Array('Routes.php', 'routes.php')) {
|
||||
public function crawl(string $basePath = __DIR__, array $filenames = array('Routes.php', 'routes.php')): RouteCollection
|
||||
{
|
||||
$instance = self::getInstance();
|
||||
|
||||
$rdi = new \RecursiveDirectoryIterator($basepath);
|
||||
$rdi = new \RecursiveDirectoryIterator($basePath);
|
||||
|
||||
foreach (new \RecursiveIteratorIterator($rdi) as $file) {
|
||||
foreach ($filenames as $filename) {
|
||||
// if (strpos($file, $filename) && $file[0] != '.') {
|
||||
if (strpos($file, $filename) && !strpos($file, '.swp') ) {
|
||||
if (strpos($file, $filename) && !strpos($file, '.swp')) {
|
||||
$instance->_loadedFiles[] = $file;
|
||||
}
|
||||
}
|
||||
@@ -75,11 +106,12 @@ class RouteCollection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the files
|
||||
*
|
||||
* Load the files with the routes
|
||||
* @ctag\t RouteCollection->loadRoutes()
|
||||
* @return RouteCollection
|
||||
*/
|
||||
function loadRoutes() {
|
||||
function loadRoutes(): RouteCollection
|
||||
{
|
||||
$instance = self::getInstance();
|
||||
|
||||
foreach ($instance->_loadedFiles as $loadedFile) {
|
||||
@@ -89,14 +121,14 @@ class RouteCollection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Infer the Request Verb
|
||||
*
|
||||
* GET | POST | PUT | PATCH | DELETE | CLI
|
||||
*
|
||||
* @param string $verb DO NOT USE
|
||||
* @throws Exception
|
||||
* @return void
|
||||
*/
|
||||
private function defineVerb() {
|
||||
|
||||
$verb = '';
|
||||
|
||||
private function defineVerb(string $verb = ""): void
|
||||
{
|
||||
if (isset($_POST['_method'])) {
|
||||
$verb = strtoupper($_POST['_method']);
|
||||
} else if (php_sapi_name() == "cli") {
|
||||
@@ -108,15 +140,18 @@ class RouteCollection {
|
||||
if (in_array($verb, self::$_verbsWhitelist)) {
|
||||
$this->_verb = $verb;
|
||||
} else {
|
||||
echo 'Invalid Verb';
|
||||
throw new Exception("Verb not Allowed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the route order
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function sort_routes() {
|
||||
usort($this->_routes, function($a, $b) {
|
||||
private function sortRoutes(): void
|
||||
{
|
||||
usort($this->_routes, function ($a, $b) {
|
||||
if ($a->_weight == $b->_weight) {
|
||||
return 0;
|
||||
}
|
||||
@@ -124,13 +159,418 @@ class RouteCollection {
|
||||
});
|
||||
}
|
||||
|
||||
public static function getGroupRoutesWithTags($group, $tag = '*')
|
||||
{
|
||||
$instance = self::getInstance();
|
||||
|
||||
if (!isset($instance->_groups[$group])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!isset($tag)) {
|
||||
return $instance->_groups[$group];
|
||||
}
|
||||
|
||||
return $instance->_groups[$group]->getRoutesWithTag($group, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trace logs
|
||||
*
|
||||
* @param bool $trace Should we trace
|
||||
* @param int $verbosity How verbose 1 - EXECUTION | 2 - CONTENT
|
||||
* @return RouteCollection
|
||||
*/
|
||||
public static function shouldTrace(bool $trace = true, int $verbosity = 1): RouteCollection
|
||||
{
|
||||
self::getInstance()->_trace = $trace;
|
||||
self::getInstance()->_traceVerbosity = $verbosity;
|
||||
return self::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a trace to the log
|
||||
*
|
||||
* @param mixed $trace Content to Trace
|
||||
* @param int $verbosity How verbose 1 - EXECUTION | 2 - CONTENT
|
||||
* @return void
|
||||
*/
|
||||
private static function trace(mixed $trace, int $verbosity = 1): void
|
||||
{
|
||||
if (!self::getInstance()->_trace) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($verbosity <= self::getInstance()->_traceVerbosity) {
|
||||
error_log(print_r($trace, true));
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================
|
||||
// Content Parsing
|
||||
//
|
||||
|
||||
/**
|
||||
* Register some common return types
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function setDefaultParsers(): void
|
||||
{
|
||||
$this->_contentParsers["string"] = function (string $content):void {
|
||||
echo $content;
|
||||
};
|
||||
|
||||
$this->_contentParsers["array"] = function (array $content):void {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode($content);
|
||||
};
|
||||
|
||||
$this->_contentParsers["stdClass"] = function (object $content):void {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode($content);
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* Register Content Parsers
|
||||
*
|
||||
* @param string $type Classname of the parser
|
||||
* @param callable $parser How to parse the content
|
||||
* @return RouteCollection
|
||||
*/
|
||||
public static function addParser(string $type, callable $parser): RouteCollection
|
||||
{
|
||||
self::getInstance()->_contentParsers[$type] = $parser;
|
||||
return self::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the content parsing
|
||||
*
|
||||
* @param mixed $content Content to be parsed
|
||||
* @return void
|
||||
*/
|
||||
public function parseContent(mixed $content): void
|
||||
{
|
||||
$contentType = gettype($content);
|
||||
|
||||
if ($contentType == "NULL") { // Route didn't return anything
|
||||
return;
|
||||
}
|
||||
|
||||
if ($contentType == "object") {
|
||||
$contentType = get_class($content);
|
||||
}
|
||||
|
||||
foreach (self::getInstance()->_contentParsers as $type => $parser) {
|
||||
if ($contentType == $type) {
|
||||
call_user_func($parser, $content);
|
||||
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);
|
||||
}
|
||||
|
||||
//=======================================================
|
||||
// API
|
||||
//
|
||||
|
||||
/**
|
||||
* Create a Route Group with the prefix
|
||||
*
|
||||
* @param string $prefix The name prefix
|
||||
* @param callable $callback The closure that will nest the routes
|
||||
* @param string $name The name of the group
|
||||
* @return RouteGroup
|
||||
*/
|
||||
public static function group(string $prefix, callable $callback, string $name = ""): RouteGroup
|
||||
{
|
||||
$collection = self::getInstance();
|
||||
$collection->_groupList = [];
|
||||
$collection->_groupIn = true;
|
||||
$collection->_groupBase = $prefix;
|
||||
call_user_func($callback);
|
||||
$collection->_groupBase = '';
|
||||
$collection->_groupIn = false;
|
||||
$group = new RouteGroup($collection->_groupList);
|
||||
$collection->_groups[$name] = $group;
|
||||
|
||||
$collection::trace("RouteGroup $prefix Added", 2);
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a GET route
|
||||
*
|
||||
* @param string $uri URI to Match
|
||||
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||
* @param int $weight Weight of the Route
|
||||
* @return Route
|
||||
*/
|
||||
static function get(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||
{
|
||||
return self::add('GET', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CLI route
|
||||
*
|
||||
* @param string $uri URI to Match
|
||||
* @param string|callable|array $callback Callback to Execute. Might be a class or a callable
|
||||
* @param int $weight Weight of the Route
|
||||
* @return Route
|
||||
*/
|
||||
static function cli(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||
{
|
||||
return self::add('CLI', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CLI route
|
||||
*
|
||||
* @param string $uri URI to Match
|
||||
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||
* @param int $weight Weight of the Route
|
||||
* @return Route
|
||||
*/
|
||||
static function post(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||
{
|
||||
return self::add('POST', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CLI route
|
||||
*
|
||||
* @param string $uri URI to Match
|
||||
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||
* @param int $weight Weight of the Route
|
||||
* @return Route
|
||||
*/
|
||||
static function put(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||
{
|
||||
return self::add('PUT', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CLI route
|
||||
*
|
||||
* @param string $uri URI to Match
|
||||
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||
* @param int $weight Weight of the Route
|
||||
* @return Route
|
||||
*/
|
||||
static function patch(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||
{
|
||||
return self::add('PATCH', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CLI route
|
||||
*
|
||||
* @param string $uri URI to Match
|
||||
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||
* @param int $weight Weight of the Route
|
||||
* @return Route
|
||||
*/
|
||||
static function delete(string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||
{
|
||||
return self::add('DELETE', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a full resource group for the prefix
|
||||
*
|
||||
* @param string $prefix Prefix to add the resource
|
||||
* @param string $resourceNameSpace NameSpace of the class to map
|
||||
* @return RouteGroup
|
||||
*/
|
||||
static function resource(string $prefix, string $resourceNameSpace): RouteGroup
|
||||
{
|
||||
throw new Exception('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Route to the Collection
|
||||
*
|
||||
* @param Array|string $verb Verbs to match the Route
|
||||
* @param string $uri URI to Match
|
||||
* @param string|callable|Array $callback Callback to Execute. Might be a class or a callable
|
||||
* @param int $weight Weight of the Route
|
||||
* @return Route
|
||||
*/
|
||||
static function add(array|string $verb, string $uri, string|callable|array $callback, int $weight = 0): Route
|
||||
{
|
||||
$route = new Route();
|
||||
|
||||
if (self::getInstance()->_groupIn) {
|
||||
$uri = self::getInstance()->_groupBase . $uri;
|
||||
self::getInstance()->_groupList[] = &$route;
|
||||
}
|
||||
|
||||
$uri = rtrim($uri, '/');
|
||||
|
||||
if (is_array($verb)) {
|
||||
$route->setVerb(array_map('strtoupper', $verb));
|
||||
} else if (strtoupper($verb) == 'WEB') {
|
||||
$route->setVerb(array_merge($route->_verb, self::$_verbsWeb));
|
||||
} else {
|
||||
$route->appendVerb(strtoupper($verb));
|
||||
}
|
||||
|
||||
$route->setUri($uri)->setCallback($callback)->setWeight($weight)->prepare();
|
||||
|
||||
self::getInstance()->_routes[] = $route;
|
||||
|
||||
self::trace("Route:: " . implode("|", $route->_verb) . " - $uri - ADDED");
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Pre Build Route
|
||||
*
|
||||
* @param Route $route The route object
|
||||
* @return RouteCollection
|
||||
*/
|
||||
function addRoute(Route $route): RouteCollection
|
||||
{
|
||||
$this->_routes[] = $route;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register error Pages
|
||||
*
|
||||
* @param int $code URI to Match
|
||||
* @param string|callable $callback Callback to Execute. Might be a class or a callable
|
||||
* @return RouteCollection
|
||||
*/
|
||||
static function error(int $code, string|callable $callback): RouteCollection
|
||||
{
|
||||
self::getInstance()->_errors[$code] = $callback;
|
||||
return self::getInstance();
|
||||
}
|
||||
|
||||
//=======================================================
|
||||
// Middlewares
|
||||
//
|
||||
|
||||
/**
|
||||
* Register a Middleware
|
||||
*
|
||||
* @param string $name Middleware Name
|
||||
* @param callable $function Middleware colsure
|
||||
* @return RouteCollection
|
||||
*/
|
||||
static function registerMiddleware(string $name, callable $function): RouteCollection
|
||||
{
|
||||
self::getInstance()->_middlewareSet[$name] = $function;
|
||||
return self::getInstance();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a middleware to match all Routes
|
||||
*
|
||||
* @param string $name Middleware Name
|
||||
* @param callable $function Middleware colsure
|
||||
* @return RouteCollection
|
||||
*/
|
||||
static function addDefaultMiddleware(string $name, callable $function): RouteCollection
|
||||
{
|
||||
self::getInstance()->_defaultMiddlewares[$name] = $function;
|
||||
return self::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::onHttpError(function(){})
|
||||
*/
|
||||
function submit() {
|
||||
global $ROUTE;
|
||||
static function onHttpError($code, $function)
|
||||
{
|
||||
$instance = self::getInstance();
|
||||
}
|
||||
|
||||
self::$_routeCollection->sort_routes();
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::httpError($class)
|
||||
*/
|
||||
private function httpError(stdClass $info)
|
||||
{
|
||||
$info = (array) $info;
|
||||
foreach ($this->_errors as $error) {
|
||||
call_user_func_array($error, $info);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================
|
||||
// RUN
|
||||
//
|
||||
|
||||
/**
|
||||
* Submit the request and execute the matching and Routing
|
||||
*
|
||||
* @return RouteCollection
|
||||
*/
|
||||
public function submit(): RouteCollection
|
||||
{
|
||||
self::$_routeCollection->sortRoutes();
|
||||
|
||||
$one_hit = false;
|
||||
|
||||
@@ -141,194 +581,44 @@ class RouteCollection {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Request match a route
|
||||
// Check if the request match a Route
|
||||
$match = $route->match(self::$_routeCollection->_uri);
|
||||
|
||||
if ($match) {
|
||||
//Yup. Execute the route
|
||||
if ($match) { // This Route Matches the pattern
|
||||
$this->_currentRoute = $route;
|
||||
|
||||
$ROUTE = $route;
|
||||
|
||||
foreach ($route->_before as $key => $requestedMiddleware){
|
||||
$route->_before[$key] = Array(
|
||||
foreach ($route->_before as $key => $requestedMiddleware) {
|
||||
$route->_before[$key] = array(
|
||||
'callback' => $this->_middlewareSet[$key],
|
||||
'params' => $requestedMiddleware);
|
||||
'params' => $requestedMiddleware
|
||||
);
|
||||
}
|
||||
|
||||
$route->_before = array_merge($this->_defaultMiddlewares, $route->_before);
|
||||
$route->setMiddlewares(array_merge($this->_defaultMiddlewares, $route->_before));
|
||||
|
||||
$route->execute();
|
||||
$routeResult = $route->execute();
|
||||
|
||||
if (!$route->_ignore) {
|
||||
$one_hit = true;
|
||||
}
|
||||
|
||||
if ($route->_httpError) {
|
||||
$this->httpError($route->_httpError);
|
||||
return;
|
||||
}
|
||||
$this->parseContent($routeResult);
|
||||
|
||||
//If Executed, interrupt route chain?
|
||||
if ($route->_block) {
|
||||
return;
|
||||
if ($route->_block) { //If Executed, interrupt route chain?
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$one_hit) {
|
||||
$info = new \stdClass();
|
||||
$info->code = 404;
|
||||
$info->message = 'Not Found';
|
||||
self::$_routeCollection->httpError($info);
|
||||
if (!$one_hit) { // Check if at least on counted Route matched
|
||||
if (isset($this->_errors['404'])) { // Return a defined 404
|
||||
call_user_func($this->_errors['404']);
|
||||
} else { // Return a regular 404
|
||||
http_response_code(404);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::group('base',function(){})
|
||||
*/
|
||||
static function group($base = '', $callback){
|
||||
$collection = self::getInstance();
|
||||
$collection->_groupList = [];
|
||||
$collection->_groupIn = true;
|
||||
$collection->_groupBase = $base;
|
||||
call_user_func($callback);
|
||||
$collection->_groupBase = '';
|
||||
$collection->_groupIn = false;
|
||||
return new RouteGroup($collection->_groupList);
|
||||
}
|
||||
|
||||
//DEFINITORS=============================================
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::get('/url',function(){})
|
||||
*/
|
||||
static function get($uri, $callback, $weight = 0) {
|
||||
return self::add('GET', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::cli('/url',function(){})
|
||||
*/
|
||||
static function cli($uri, $callback, $weight = 0) {
|
||||
return self::add('CLI', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::post('/url',function(){})
|
||||
*/
|
||||
static function post($uri, $callback, $weight = 0) {
|
||||
return self::add('POST', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::put('/url',function(){})
|
||||
*/
|
||||
static function put($uri, $callback, $weight = 0) {
|
||||
return self::add('PUT', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::patch('/url',function(){})
|
||||
*/
|
||||
static function patch($uri, $callback, $weight = 0) {
|
||||
return self::add('PATCH', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::delete('/url',Controller@Method)
|
||||
* @ctag RouteCollection::delete('/url',function(){})
|
||||
*/
|
||||
static function delete($uri, $callback, $weight = 0) {
|
||||
return self::add('DELETE', $uri, $callback, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::resource('/url',function(){})
|
||||
*/
|
||||
static function resource($uri) {
|
||||
throw new Exception('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::add('VERB','/url',function(){})
|
||||
* @ctag RouteCollection::add('VERB','/url',Controller@Method)
|
||||
*/
|
||||
static function add($verb, $uri, $callback, $weight = 0) {
|
||||
$route = new Route();
|
||||
|
||||
if(self::getInstance()->_groupIn){
|
||||
$uri = self::getInstance()->_groupBase . $uri;
|
||||
self::getInstance()->_groupList[] = &$route;
|
||||
}
|
||||
$uri = rtrim($uri, '/');
|
||||
if (is_array($verb)) {
|
||||
$route->_verb = array_map('strtoupper', $verb);
|
||||
} else if (strtoupper($verb) == 'WEB') {
|
||||
$route->_verb[] = self::_verbsWeb;
|
||||
} else {
|
||||
$route->_verb[] = strtoupper($verb);
|
||||
}
|
||||
|
||||
$route->_uri = $uri;
|
||||
$route->_callback[] = $callback;
|
||||
$route->_weight = $weight;
|
||||
$route->prepare();
|
||||
|
||||
self::getInstance()->_routes[] = $route;
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function addRoute(Route $route) {
|
||||
$this->_routes[] = $route;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::addDefaultMiddleware('name',function(){})
|
||||
*/
|
||||
static function addDefaultMiddleware($name = '', $function) {
|
||||
self::getInstance()->_defaultMiddlewares[$name] = $function;
|
||||
return self::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::addDefaultMiddleware('name',function(){})
|
||||
*/
|
||||
static function registerMiddleware($name = '', $function) {
|
||||
return self::getInstance()->_middlewareSet[$name] = $function;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::onHttpError(function(){})
|
||||
*/
|
||||
static function onHttpError($code, $function) {
|
||||
$instance = self::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ctag RouteCollection::httpError($class)
|
||||
*/
|
||||
private function httpError(\stdClass $info) {
|
||||
$info = (array) $info;
|
||||
foreach ($this->_errors as $error) {
|
||||
call_user_func_array($error, $info);
|
||||
}
|
||||
return $this; // Do you really want to chain more Stuff?
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+46
-38
@@ -2,88 +2,96 @@
|
||||
|
||||
namespace Routes;
|
||||
|
||||
class RouteGroup{
|
||||
class RouteGroup
|
||||
{
|
||||
|
||||
private $_routeGroup = [];
|
||||
|
||||
function __construct($group){
|
||||
function __construct($group)
|
||||
{
|
||||
$this->setGroup($group);
|
||||
|
||||
}
|
||||
|
||||
function setGroup($group){
|
||||
function setGroup($group)
|
||||
{
|
||||
$this->_routeGroup = $group;
|
||||
}
|
||||
|
||||
function doBlock() {
|
||||
foreach($this->_routeGroup as $route){
|
||||
function doBlock()
|
||||
{
|
||||
foreach ($this->_routeGroup as $route) {
|
||||
$route->_block = true;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
function notBlock() {
|
||||
foreach($this->_routeGroup as $route){
|
||||
function notBlock()
|
||||
{
|
||||
foreach ($this->_routeGroup as $route) {
|
||||
$route->_block = false;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
function doIgnore() {
|
||||
foreach($this->_routeGroup as $route){
|
||||
function doIgnore()
|
||||
{
|
||||
foreach ($this->_routeGroup as $route) {
|
||||
$route->_ignore = true;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
function notIgnore() {
|
||||
foreach($this->_routeGroup as $route){
|
||||
function notIgnore()
|
||||
{
|
||||
foreach ($this->_routeGroup as $route) {
|
||||
$route->_ignore = false;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
function middlewareIgnore($name = '') {
|
||||
foreach($this->_routeGroup as $route){
|
||||
$route->_middlewaresToIgnore[] = $name;
|
||||
function middlewareIgnore($name)
|
||||
{
|
||||
foreach ($this->_routeGroup as $route) {
|
||||
$route->middlewareIgnore($name);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
function middlewareAdd($name = '') {
|
||||
foreach($this->_routeGroup as $route){
|
||||
$route->_before[$name] = $function;
|
||||
function middlewareAdd($name)
|
||||
{
|
||||
foreach ($this->_routeGroup as $route) {
|
||||
$route->middlewareAdd($name);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
function middlewareAppend($name = '', $function) {
|
||||
foreach($this->_routeGroup as $route){
|
||||
$route->_before[$name] = $function;
|
||||
//function middlewareAppend($name, $function)
|
||||
//{
|
||||
// foreach ($this->_routeGroup as $route) {
|
||||
// $route->_before[$name] = $function;
|
||||
// }
|
||||
// return $this;
|
||||
//}
|
||||
|
||||
function setWeight($weigth = 0)
|
||||
{
|
||||
foreach ($this->_routeGroup as $route) {
|
||||
$route->setWeight($weigth);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
function setWeight($weigth = 0) {
|
||||
foreach($this->_routeGroup as $route){
|
||||
$route->_weight = $weigth;
|
||||
}
|
||||
return $this;
|
||||
function getRoutesWithTag($group, $tag): Array
|
||||
{
|
||||
return array_filter(array_map(function($route) use($group, $tag){
|
||||
return $route->hasTag($tag) ? $route->compress($group, $tag) : null;
|
||||
}, $this->_routeGroup));
|
||||
}
|
||||
|
||||
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;
|
||||
function getRoutes()
|
||||
{
|
||||
return $this->_routeGroup;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user