158 lines
4.3 KiB
PHP
158 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http;
|
|
|
|
use App\Domain\Controller;
|
|
use App\Exceptions\InvalidRouteException;
|
|
use App\Helpers\AutoLoader;
|
|
use FilesystemIterator;
|
|
|
|
final class Router {
|
|
|
|
/**
|
|
* Route voulue par le client.
|
|
* @var string
|
|
*/
|
|
public private(set) static string $clientRouteString;
|
|
|
|
/**
|
|
* Informations de la route du client.
|
|
* @var Route
|
|
*/
|
|
public private(set) static Route $clientRoute;
|
|
|
|
/**
|
|
* Liste des controllers sorti du cache ou récupéré via fetchControllers.
|
|
* @var array
|
|
*/
|
|
private static array $controllers;
|
|
|
|
/**
|
|
* Liste des routes tirées des controllers. Rempli par la méthode fetchRoutes.
|
|
* @var Route[]
|
|
*/
|
|
private static array $routes;
|
|
|
|
/**
|
|
* Fonction principale qui va router le contenu vers la bonne méthode du bon Controlleur.
|
|
* @return void
|
|
*
|
|
* @throws InvalidRouteException Si la route voulue n'existe pas ou n'est pas bien formaté.
|
|
*/
|
|
public static function routeTo(): void {
|
|
|
|
self::$clientRouteString = $_SERVER['REQUEST_URI'];
|
|
|
|
self::$controllers = self::fetchControllers();
|
|
self::$routes = self::fetchRoutes();
|
|
|
|
$clientRoute = self::clientRouteExist();
|
|
if( !$clientRoute ){
|
|
throw new InvalidRouteException( self::$clientRouteString );
|
|
}
|
|
self::$clientRoute = $clientRoute;
|
|
|
|
if( !in_array( $_SERVER['REQUEST_METHOD'], self::$clientRoute->routeMethods ) ){
|
|
throw new InvalidRouteException( self::$clientRouteString );
|
|
} else {
|
|
self::executeRouteAction();
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Permet de récupérer tous les controllers du dossier Domain.
|
|
* @return class-string[]
|
|
*/
|
|
private static function fetchControllers(): array {
|
|
|
|
$classes = [];
|
|
|
|
$iterator = new \RecursiveIteratorIterator(
|
|
new \RecursiveDirectoryIterator( APP_ROOT . 'src/Domain', FilesystemIterator::SKIP_DOTS ),
|
|
);
|
|
|
|
foreach( $iterator as $file ){
|
|
|
|
if( $file->isFile() && $file->getExtension() === 'php' ){
|
|
|
|
$fileName = $file->getPathname();
|
|
|
|
// Transformation du chemin du fichier vers le nom complet de la classe.
|
|
$fileName = str_replace( APP_ROOT . 'src/', AutoLoader::PRIMARY_NAMESPACE, $fileName );
|
|
$fileName = str_replace( '.php', '', $fileName );
|
|
$fileName = str_replace( '/', '\\', $fileName );
|
|
|
|
|
|
/*
|
|
* Vérifie que l'on est bien sur un Controller.
|
|
* Ignore Controller car Controller n'est pas une sous-classe de Controller.
|
|
*/
|
|
if( is_subclass_of( $fileName, Controller::class ) ){
|
|
$classes[] = $fileName;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $classes;
|
|
|
|
}
|
|
|
|
/**
|
|
* Récupérer toutes les routes des controllers récupéré avant.
|
|
* @return Route[]
|
|
*/
|
|
private static function fetchRoutes(): array {
|
|
|
|
$routes = [];
|
|
|
|
foreach( self::$controllers as $controllerClassString ){
|
|
$routes = array_merge( $routes, $controllerClassString::defineRoutes() );
|
|
}
|
|
|
|
return $routes;
|
|
}
|
|
|
|
/**
|
|
* Permet de savoir si la route que le client veut existe.
|
|
* @return Route|bool Retourne la route de l'utilisateur ou false si inexistante.
|
|
*/
|
|
private static function clientRouteExist(): Route|bool {
|
|
|
|
foreach( self::$routes as $route ){
|
|
/*
|
|
if( preg_match( self::getRegexRoute( $route), self::$clientRouteString, $matches ) ){
|
|
var_dump( $matches );
|
|
}
|
|
*/
|
|
/*
|
|
if( $route->routeUrl === self::$clientRouteString ){
|
|
return $route;
|
|
}
|
|
*/
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
private static function getRegexRoute( Route $route ): string {
|
|
$routeUrl = $route->routeUrl;
|
|
$routeUrl = str_replace( "{int}", "([0-9]+)", $routeUrl );
|
|
return $routeUrl;
|
|
}
|
|
|
|
/**
|
|
* Va permettre d'exécuter la méthode du Controller->action() en parsant les arguments si existants.
|
|
* @return void
|
|
*/
|
|
private static function executeRouteAction(): void {
|
|
$controller = self::$clientRoute->routeController;
|
|
$method = self::$clientRoute->routeAction;
|
|
|
|
new $controller()->$method();
|
|
}
|
|
|
|
} |