Fix Router and finish base view system.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
namespace App\Domain\Pages;
|
||||
|
||||
use App\Domain\Controller;
|
||||
use App\Infrastructure\View;
|
||||
|
||||
/**
|
||||
* Controller pour les pages sans lien avec un contenu spécifique.
|
||||
@@ -14,7 +15,7 @@ class PagesController extends Controller {
|
||||
{
|
||||
return [
|
||||
self::Route( routeUrl: '/', routeName: 'Homepage', routeAction: 'index' ),
|
||||
self::ROute( routeUrl: '/test/{int}', routeName: 'test', routeAction: 'test' ),
|
||||
self::Route( routeUrl: '/test/{string}/baba', routeName: 'test', routeAction: 'test' ),
|
||||
];
|
||||
|
||||
}
|
||||
@@ -23,11 +24,11 @@ class PagesController extends Controller {
|
||||
* Route de la page d'accueil.
|
||||
* @return void
|
||||
*/
|
||||
public function index(): void {
|
||||
echo "Coucou";
|
||||
public function index(): View {
|
||||
return new View( 'home', [ 'ok' => 'bla' ] );
|
||||
}
|
||||
|
||||
public function test( int $id ): void {
|
||||
public function test( string $id ): void {
|
||||
echo "Coucou" . $id;
|
||||
}
|
||||
|
||||
|
||||
13
src/Exceptions/InvalidViewException.php
Normal file
13
src/Exceptions/InvalidViewException.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
use Throwable;
|
||||
|
||||
class InvalidViewException extends \Exception {
|
||||
|
||||
public function __construct( string $viewName )
|
||||
{
|
||||
parent::__construct( "View {$viewName} does not exist.", 500 );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace App\Http;
|
||||
use App\Domain\Controller;
|
||||
use App\Exceptions\InvalidRouteException;
|
||||
use App\Helpers\AutoLoader;
|
||||
use App\Kernel;
|
||||
use FilesystemIterator;
|
||||
|
||||
final class Router {
|
||||
@@ -21,6 +22,12 @@ final class Router {
|
||||
*/
|
||||
public private(set) static Route $clientRoute;
|
||||
|
||||
/**
|
||||
* Informations sur les arguments passés à la route.
|
||||
* @var array
|
||||
*/
|
||||
public private(set) static array $clientRouteArguments;
|
||||
|
||||
/**
|
||||
* Liste des controllers sorti du cache ou récupéré via fetchControllers.
|
||||
* @var array
|
||||
@@ -34,7 +41,7 @@ final class Router {
|
||||
private static array $routes;
|
||||
|
||||
/**
|
||||
* Fonction principale qui va router le contenu vers la bonne méthode du bon Controlleur.
|
||||
* Fonction principale qui va router le contenu vers la bonne méthode du bon Controller.
|
||||
* @return void
|
||||
*
|
||||
* @throws InvalidRouteException Si la route voulue n'existe pas ou n'est pas bien formaté.
|
||||
@@ -121,17 +128,14 @@ final class Router {
|
||||
*/
|
||||
private static function clientRouteExist(): Route|bool {
|
||||
|
||||
$clientRouteName = trim( self::$clientRouteString, '/' );
|
||||
foreach( self::$routes as $route ){
|
||||
/*
|
||||
if( preg_match( self::getRegexRoute( $route), self::$clientRouteString, $matches ) ){
|
||||
var_dump( $matches );
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if( $route->routeUrl === self::$clientRouteString ){
|
||||
$routeName = self::getRegexRoute( $route );
|
||||
if( preg_match( $routeName, $clientRouteName, $matches ) ){
|
||||
array_shift( $matches );
|
||||
self::$clientRouteArguments = $matches;
|
||||
return $route;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -139,20 +143,22 @@ final class Router {
|
||||
}
|
||||
|
||||
private static function getRegexRoute( Route $route ): string {
|
||||
$routeUrl = $route->routeUrl;
|
||||
$routeUrl = str_replace( "{int}", "([0-9]+)", $routeUrl );
|
||||
return $routeUrl;
|
||||
$routeUrl = trim( $route->routeUrl, '/' );
|
||||
foreach ( Kernel::$configs['route_arguments'] as $key => $value ){
|
||||
$routeUrl = str_replace( $key, $value, $routeUrl );
|
||||
}
|
||||
return "#^{$routeUrl}$#";
|
||||
}
|
||||
|
||||
/**
|
||||
* Va permettre d'exécuter la méthode du Controller->action() en parsant les arguments si existants.
|
||||
* 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();
|
||||
new $controller()->$method( ...self::$clientRouteArguments);
|
||||
}
|
||||
|
||||
}
|
||||
194
src/Infrastructure/View.php
Normal file
194
src/Infrastructure/View.php
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
namespace App\Infrastructure;
|
||||
|
||||
use App\Exceptions\InvalidViewException;
|
||||
use App\Http\Router;
|
||||
use App\Kernel;
|
||||
|
||||
/**
|
||||
* Permet de rendre une vue / contenu de la page.
|
||||
* /!\ : Une seule vue peut-être appellé par page, hormis celle en plus pour le squelette.
|
||||
*/
|
||||
final class View {
|
||||
|
||||
/**
|
||||
* Répertoire où se trouvent les vues.
|
||||
*/
|
||||
const string VIEW_PATH = APP_ROOT . 'views/';
|
||||
|
||||
/**
|
||||
* Le nom du fichier de vue.
|
||||
* @var string
|
||||
*/
|
||||
public private(set) string $viewName;
|
||||
|
||||
/**
|
||||
* Les arguments passés à la vue.
|
||||
* @var array
|
||||
*/
|
||||
public private(set) array $viewArgs;
|
||||
|
||||
/**
|
||||
* La base de la vue. (Pour ne pas répéter header/footer à chaque fois).
|
||||
* null correspond à pas de squelette.
|
||||
*
|
||||
* @var string|mixed|null
|
||||
*/
|
||||
public private(set) ?string $skeleton;
|
||||
|
||||
/**
|
||||
* Utilisé par les squelettes, permet d'injecter des contenus comme le contenu de son enfant.
|
||||
* @var array<string,string>
|
||||
*/
|
||||
public private(set) array $integratedContent;
|
||||
|
||||
/**
|
||||
* Garde la dernière instance de vue.
|
||||
* Si il y a un squelette, ce sera l'instance du squelette.
|
||||
*
|
||||
* @var View
|
||||
*/
|
||||
private static self $lastInstance;
|
||||
|
||||
/**
|
||||
* Permet de construire les informations de la vue.
|
||||
*
|
||||
* @param string $viewName Le nom du fichier de vue.
|
||||
* @param array $viewArgs Les arguments de la vue.
|
||||
* @param bool $autoRender Si la méthode $this->render() est automatiquement exécuté.
|
||||
* @param string|null $skeleton Le squelette du fichier, null correspond à aucun squelette, default correspond au
|
||||
* squelette défini dans la configuration des vues.
|
||||
* @param array<string,string> $integratedContent Le contenu intégré dans le nouveau squelette.
|
||||
*/
|
||||
public function __construct(
|
||||
string $viewName,
|
||||
array $viewArgs = [],
|
||||
bool $autoRender = true,
|
||||
?string $skeleton = 'default',
|
||||
array $integratedContent = []
|
||||
) {
|
||||
|
||||
if( !str_ends_with( $viewName, '.php' ) ) {
|
||||
$viewName .= '.php';
|
||||
}
|
||||
|
||||
$this->viewName = $viewName;
|
||||
$this->viewArgs = $viewArgs;
|
||||
|
||||
$this->skeleton = $skeleton;
|
||||
if( $this->skeleton === "default" ){
|
||||
$this->skeleton = Kernel::$configs['views']['base_view_skeleton'];
|
||||
}
|
||||
|
||||
$this->integratedContent = $integratedContent;
|
||||
|
||||
try {
|
||||
if (!file_exists(self::VIEW_PATH . $this->viewName)) {
|
||||
throw new InvalidViewException($this->viewName);
|
||||
}
|
||||
|
||||
if ($autoRender) {
|
||||
$this->render();
|
||||
}
|
||||
} catch (InvalidViewException $e) {
|
||||
die( $e->getMessage() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet de démarrer le rendu d'une vue.
|
||||
* @return void
|
||||
*/
|
||||
public function startView(): void {
|
||||
ob_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet de finir le rendu d'une vue.
|
||||
* @return void
|
||||
*/
|
||||
public function endView(): void {
|
||||
echo ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet de faire le rendu proprement de la vue.
|
||||
* @return void
|
||||
*/
|
||||
public function render(): void {
|
||||
|
||||
self::$lastInstance = $this;
|
||||
|
||||
if( $this->skeleton === null ){
|
||||
|
||||
// Si on a pas de squelette, on inclut la vue.
|
||||
// pour accéder aux éléments de la vue, on utilise les méthodes statiques de cette classe.
|
||||
$this->startView();
|
||||
require self::VIEW_PATH . $this->viewName;
|
||||
$this->endView();
|
||||
|
||||
} else {
|
||||
|
||||
// Si on a un squelette, on charge tout le contenu de la vue enfante.
|
||||
$content = file_get_contents( self::VIEW_PATH . $this->viewName );
|
||||
|
||||
// On démarre la vue du squelette.
|
||||
$base = new View( $this->skeleton, $this->viewArgs, skeleton: null, integratedContent: [ 'content' => $content ] );
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* VIEW TOOLS
|
||||
*/
|
||||
|
||||
/**
|
||||
* Permet d'injecter un contenu sauvegardé dans $this->integratedContent.
|
||||
*
|
||||
* @param string $integratedContentName
|
||||
* @return void N'affiche rien si le contenu n'existe pas.
|
||||
*/
|
||||
public static function inject( string $integratedContentName ): void {
|
||||
if( isset( self::$lastInstance->integratedContent[ $integratedContentName ] ) )
|
||||
echo self::$lastInstance->integratedContent[ $integratedContentName ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet de récupérer un argument passé à la vue.
|
||||
*
|
||||
* @param string $argumentName
|
||||
* @return mixed null si l'argument n'existe pas.
|
||||
*/
|
||||
public static function arg( string $argumentName ): mixed {
|
||||
if( isset( self::$lastInstance->viewArgs[ $argumentName ] ) )
|
||||
return self::$lastInstance->viewArgs[ $argumentName ];
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet d'intégrer un bloc à la vue.
|
||||
*
|
||||
* @param string $partialName
|
||||
* @return void N'affiche rien si le bloc n'existe pas.
|
||||
*/
|
||||
public static function partial( string $partialName ): void {
|
||||
|
||||
if( !str_ends_with( $partialName, '.php' ) ) {
|
||||
$partialName .= '.php';
|
||||
}
|
||||
|
||||
if( file_exists( self::VIEW_PATH . 'partials/' . $partialName ) ) {
|
||||
require self::VIEW_PATH . 'partials/' . $partialName;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getHeadTitle(): string {
|
||||
$siteUrl = Kernel::$configs['general']['website_name'];
|
||||
return Router::$clientRoute->routeName . ' - ' . $siteUrl;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -84,7 +84,11 @@ final class Kernel {
|
||||
*/
|
||||
private function loadConfig(): void {
|
||||
try {
|
||||
|
||||
self::$configs['general'] = ConfigFactory::loadConfigFile('general');
|
||||
self::$configs['route_arguments'] = ConfigFactory::loadConfigFile('route_arguments');
|
||||
self::$configs['views'] = ConfigFactory::loadConfigFile('views');
|
||||
|
||||
} catch( ConfigFailedLoadingException $e ){
|
||||
die( $e->getMessage() );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user