Files
LesRecettesDePapis/src/Infrastructure/View.php

194 lines
5.4 KiB
PHP

<?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;
}
}