Commentaires
Aurélien Vaast
17/07/2022 à 14:55
Effectivement c'est un oubli, ces deux fonctions devraient être appelées dans le layout, dans la partie <head>
Christian HABIB JIWAN
15/07/2022 à 21:06
Bonsoir, Super le projet de "framework". Pour l'ajout des fichiers JS & CSS, ne manquet-il pas quelque chose pour qu'il soit intégrer au code HTML généré? Jamais on n'appel la méthode generateJS?
Arthur, l'apprenti développeurMais on a déjà géré les vues ! Et tu entend quoi par fichiers associés?!?

Oui on a prévu une méthode pour afficher les vues, mais je vais te faire changer légèrement l'architecture des dossiers dans les vues, pour pouvoir y gérer les fichiers associés justement, je t'explique.
Ce que j'appelle les fichiers associés, ce sont les feuilles de style css et les javascript.

Arthur, l'apprenti développeurOui on a prévu des dossiers pour ces fichiers.

Effectivement, mais les dossiers que l'on a prévu ne seront que pour les css et javascript commun à tout le site, on y mettra les librairies externe, et un fichiers global aussi bien en css qu'en js.

Par contre chaque vue peut avoir une mise en forme et des traitement spécifique, donc elle aura potentiellement un fichier css et un fichier js qui lui est propre. On pourrait créer directement dans le dossier View deux dossier css et js pour placé ces fichiers. Pour un petit site ça ne poserais pas vraiment de problème, mais vraiment un tout petit site, si tu commence à avoir une dizaine de vue, compte alors trente fichiers dans le dossier View, ou dix dans View, dix dans css et dix dans js.

Arthur, l'apprenti développeurOui ça ne me parrait pas vraiment choquant

une dizaine de vue, ça peut aller très vite tu sais, rien que pour la gestion utilisateur, tu peux créer une vue pour le formulaire d'inscription, une autre pour la validation de l'inscription, une pour l'authentification, une pour la validation de l'authentification, une pour le mot de passe perdue etc...

Et plus ton site va avoir de page et de fonctionnalité, et plus tu va augmenter le nombre de vue, très rapidement tu auras un nombre important de fichier, et des difficultés à retrouver où est afficher tel champ ou tel composant.

Arthur, l'apprenti développeurC'est vrai que ça peut vite devenir compliqué.

Ce que je te propose, c'est de créer un nouveau dossier dans le dossier View pour chaque controller, et ce dossier portera le nom de ce controller. Et dans chacun de ces dossier on y ajoutera un dossier css et un dossier js.Ainsi on aura des vues qui sont spécifique à des contrôleur, ce sera bien plus facile à gérer.

En plus de ça, je t'invite à créer un dossier Shared dans le dossier View, on pourra y place des vues qui ne sont pas spécifique à un contrôleur, mais partagé par tous les controleur de l'application.

Arthur, l'apprenti développeurOk, ça devrais ressembler à ça ?



Oui tout à fait. Maintenant, il va falloir modifier notre méthode View dans le BaseController étant donné que l'architecture de nos dossier à changé. Pense bien à récupéré le nom du contrôleur dans httpRequest, car tu en auras besoin pour construire le chemin.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseController\n\t{\n\t\tprivate $_httpRequest;\n\t\tprivate $_param;\n\t\tprivate $_config;\n\t\t\n\t\tpublic function __construct($httpRequest,$config)\n\t\t{\n\t\t\t$this->_httpRequest = $httpRequest;\n\t\t\t$this->_config = $httpRequest;\n\t\t\t$this->_param = array();\n\t\t\t$this->addParam(\"httprequest\",$this->_httpRequest);\n\t\t\t$this->addParam(\"config\",$this->_config);\n\t\t\t$this->bindManager();\n\t\t}\n\t\t\n\t\tprotected function view($filename)\n\t\t{\n\t\t\tif(file_exists(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/\" . $filename . \".php\"))\n\t\t\t{\n\t\t\t\tob_start();\n\t\t\t\textract($this->_param);\n\t\t\t\tinclude(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/\" . $filename . \".php\");\n\t\t\t\t$content = ob_get_clean();\n\t\t\t\tinclude(\"View/layout.php\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new ViewNotFoundException();\t\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic function bindManager()\n\t\t{\n\t\t\tforeach($this->_httpRequest->getRoute()->manager as $manager)\n\t\t\t{\n\t\t\t\t$this->$manager = new $manager($this->_config->database);\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic function addParam($name,$value)\n\t\t{\n\t\t\t$this->_param[$name] = $value;\n\t\t}\n\t}","filename":"BaseController;php"}



C'est ça. Maintenant on va créer une classe supplémentaire FileManager dans le framework, l'objectif est simple, cette classe doit avoir deux propriétés listCss et listJs qui contiendront, dans un tableau, la liste des fichiers css et js à charger. Et elle doit avoir quatre méthodes, deux pour ajouter des fichiers css et js, et deux pour générer le html qui sert à ajouter des fichiers css et js, pour rappel ce html ressemble à :

{"language":"application/x-httpd-php","content":"<link rel=\"stylesheet\" type=\"text/css\" href=\"chemin/fichier.css\" />\n<script src=\"chemin/fichier.js\"></script>","filename":"exemple"}


Arthur, l'apprenti développeurok ça me parait facile.

{"language":"application/x-httpd-php","content":"<?php\n\tclass FileManager\n\t{\n\t\tprivate $_listJsFile;\n private $_listCssFile;\n\t\t\n\t\tpublic function __construct()\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function addJs($file)\n {\n $this->_listJsFile[] = $file;\n }\n\n public function addCss($file)\n {\n $this->_listCssFile[] = $file;\n }\n\t\t\n\t\tpublic function generateJs($jsFile)\n {\n return '<script src=\"'. $jsFile . '\" ></script>';\n }\n\n public function generateCss($cssFile)\n {\n return '<link rel=\"stylesheet\" type=\"text/css\" href=\"' . $cssFile . '\" />';\n }\n\t}","filename":"FileManager.php"}



Tu as oublié un détail, et je n'ai peut être pas été assez précis sur la génération du html. Déjà il faut bien penser à initialiser tes propriété avec un tableau vide dans le constructeur, sinon tu auras une erreur quand tu ajouteras un élément au tableau qui n'existe pas.
Et les deux méthodes de génération doivent parcourir les listes en question, pour générer le html de l'ensemble de ces fichiers et le retourner.

Arthur, l'apprenti développeurAh oui je n'avais pas compris ça en effet, ça me parait plus cohérent de cette façon.

{"language":"application/x-httpd-php","content":"<?php\n\tclass FileManager\n\t{\n\t\tprivate $_listJsFile;\n private $_listCssFile;\n\t\t\n\t\tpublic function __construct()\n\t\t{\n\t\t\t$this->_listJsFile = array();\n\t\t\t$this->_listCssFile = array();\n\t\t}\n\t\t\n\t\tpublic function addJs($file)\n {\n $this->_listJsFile[] = $file;\n }\n\n public function addCss($file)\n {\n $this->_listCssFile[] = $file;\n }\n\t\t\n\t\tpublic function generateJs()\n {\n $jsContent = '';\n foreach($this->_listJsFile as $jsFile)\n {\n $jsContent .= '<script src=\"'. $jsFile . '\" ></script>';\n }\n return $jsContent;\n }\n\n public function generateCss()\n {\n $cssContent = '';\n foreach($this->_listCssFile as $cssFile)\n {\n $cssContent .= '<link rel=\"stylesheet\" type=\"text/css\" href=\"' . $cssFile . '\" />';\n }\n return $cssContent;\n }\n\t}","filename":"FileManager.php"}


Très bien, maintenant on va ajouter une instance de FileManager dans notre BaseController, comme ça, on pourra ajouter des fichiers à partir de n'importe quel contrôleur, pense aussi à l'instancier dans le contrôleur.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseController\n\t{\n\t\tprivate $_httpRequest;\n\t\tprivate $_param;\n\t\tprivate $_config;\n\t\tprivate $_FileManager;\n\t\t\n\t\tpublic function __construct($httpRequest,$config)\n\t\t{\n\t\t\t$this->_httpRequest = $httpRequest;\n\t\t\t$this->_config = $httpRequest;\n\t\t\t$this->_param = array();\n\t\t\t$this->addParam(\"httprequest\",$this->_httpRequest);\n\t\t\t$this->addParam(\"config\",$this->_config);\n\t\t\t$this->bindManager();\n\t\t\t$this->FileManager = new FileManager();\n\t\t}\n\t\t\n\t\tprotected function view($filename)\n\t\t{\n\t\t\tif(file_exists(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/\" . $filename . \".php\"))\n\t\t\t{\n\t\t\t\tob_start();\n\t\t\t\textract($this->_param);\n\t\t\t\tinclude(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/\" . $filename . \".php\");\n\t\t\t\t$content = ob_get_clean();\n\t\t\t\tinclude(\"View/layout.php\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new ViewNotFoundException();\t\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic function bindManager()\n\t\t{\n\t\t\tforeach($this->_httpRequest->getRoute()->getManager() as $manager)\n\t\t\t{\n\t\t\t\t$this->$manager = new $manager($this->_config->database);\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic function addParam($name,$value)\n\t\t{\n\t\t\t$this->_param[$name] = $value;\n\t\t}\n\t}","filename":"BaseController.php"}


Arthur, l'apprenti développeurEt j'ajoute un accesseur?

On pourrait tout à fait ajouter un accesseur, seulement après, pour ajouter un fichier, il faudrait appeler :

{"language":"application/x-httpd-php","content":"<?php\n\tclass ExempleController\n\t{\n\t\tpublic function Action()\n\t\t{\n\t\t\t$this->getFileManager()->addCss(\"file.css\");\t\n\t\t}\n\t}","filename":"exemple"}


Je te propose que pour cette fois, on se simplifie la vie en créant deux méthodes "passe-plat" dans le BaseController.

Arthur, l'apprenti développeurDes méthodes "passe-plat"? Tu entend quoi par là?

Tout simplement une méthode qui appelle une autre méthode d'un objet possédé par la classe. Elle ne font rien de particulier, pas de traitement en plus, elle se chargent simplement de faire un appel vers une autre méthode. Ainsi dans les contrôleurs on pourra faire directement :

{"language":"application/x-httpd-php","content":"<?php\n\tclass ExempleController\n\t{\n\t\tpublic function Action()\n\t\t{\n\t\t\t$this->addCss(\"file.css\");\t\n\t\t}\n\t}","filename":"exemple"}


Arthur, l'apprenti développeurAh je crois que j'ai compris !

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseController\n\t{\n\t\tprivate $_httpRequest;\n\t\tprivate $_param;\n\t\tprivate $_config;\n\t\tprivate $_FileManager;\n\t\t\n\t\tpublic function __construct($httpRequest,$config)\n\t\t{\n\t\t\t$this->_httpRequest = $httpRequest;\n\t\t\t$this->_config = $httpRequest;\n\t\t\t$this->_param = array();\n\t\t\t$this->addParam(\"httprequest\",$this->_httpRequest);\n\t\t\t$this->addParam(\"config\",$this->_config);\n\t\t\t$this->bindManager();\n\t\t\t$this->FileManager = new FileManager();\n\t\t}\n\t\t\n\t\tprotected function view($filename)\n\t\t{\n\t\t\tif(file_exists(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/\" . $filename . \".php\"))\n\t\t\t{\n\t\t\t\tob_start();\n\t\t\t\textract($this->_param);\n\t\t\t\tinclude(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/\" . $filename . \".php\");\n\t\t\t\t$content = ob_get_clean();\n\t\t\t\tinclude(\"View/layout.php\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new ViewNotFoundException();\t\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic function bindManager()\n\t\t{\n\t\t\tforeach($this->_httpRequest->getRoute()->getManager() as $manager)\n\t\t\t{\n\t\t\t\t$this->$manager = new $manager($this->_config->database);\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic function addParam($name,$value)\n\t\t{\n\t\t\t$this->_param[$name] = $value;\n\t\t}\n\t\t\n\t\tpublic function addCss($file)\n\t\t{\n\t\t\t$this->_fileManager->addCss($file);\n\t\t}\n\t\t\n\t\tpublic function addJs($file)\n\t\t{\n\t\t\t$this->_fileManager->addJs($file);\n\t\t}\n\t}","filename":"BaseController.php"}


C'est tout à fait ça ! Il nous reste un dernier point à voir dans ce BaseController avant de passer au premier appel. Maintenant on va avoir des fichier css et js spécifique à chaque vue, dans l'idéal on les nommera exacement de la même façon que le fichier de vue, par exemple pour une vue accueil :


  • Vue : /View/{$controller}/accueil.php

  • Css: /View/{$controller}/css/accueil.css

  • Js: /View/{$controller}/js/accueil.js



Il serait donc pratique que lorsque l'on charge un template avec la méthode view, cette méthode se charge aussi d'ajouter les fichiers css et js associé à cette vue, si et seulement s'ils existent.

Arthur, l'apprenti développeurJe m'en occupe !

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseController\n\t{\n\t\tprivate $_httpRequest;\n\t\tprivate $_param;\n\t\tprivate $_config;\n\t\tprivate $_FileManager;\n\t\t\n\t\tpublic function __construct($httpRequest,$config)\n\t\t{\n\t\t\t$this->_httpRequest = $httpRequest;\n\t\t\t$this->_config = $httpRequest;\n\t\t\t$this->_param = array();\n\t\t\t$this->addParam(\"httprequest\",$this->_httpRequest);\n\t\t\t$this->addParam(\"config\",$this->_config);\n\t\t\t$this->bindManager();\n\t\t\t$this->FileManager = new FileManager();\n\t\t}\n\t\t\n\t\tprotected function view($filename)\t\n\t\t{\n\t\t\tif(file_exists(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/css/\" . $filename . \".css\"))\n\t\t\t{\n\t\t\t\t$this->addCss(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/css/\" . $filename . \".css\");\n\t\t\t}\n\t\t\tif(file_exists(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/js/\" . $filename . \".js\"))\n\t\t\t{\n\t\t\t\t$this->addJs(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/js/\" . $filename . \".js\");\n\t\t\t}\n\t\t\tif(file_exists(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/\" . $filename . \".php\"))\n\t\t\t{\n\t\t\t\tob_start();\n\t\t\t\textract($this->_param);\n\t\t\t\tinclude(\"View/\" . $this->_httprequest->getRoute()->getController() . \"/\" . $filename . \".php\");\n\t\t\t\t$content = ob_get_clean();\n\t\t\t\tinclude(\"View/layout.php\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new ViewNotFoundException();\t\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic function bindManager()\n\t\t{\n\t\t\tforeach($this->_httpRequest->getRoute()->getManager() as $manager)\n\t\t\t{\n\t\t\t\t$this->$manager = new $manager($this->_config->database);\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic function addParam($name,$value)\n\t\t{\n\t\t\t$this->_param[$name] = $value;\n\t\t}\n\t\t\n\t\tpublic function addCss($file)\n\t\t{\n\t\t\t$this->_fileManager->addCss($file);\n\t\t}\n\t\t\n\t\tpublic function addJs($file)\n\t\t{\n\t\t\t$this->_fileManager->addJs($file);\n\t\t}\n\t}","filename":"BaseController"}


Le BaseController est finit !

Arthur, l'apprenti développeurAh enfin

Pour le moment...

Arthur, l'apprenti développeurQuoi?!?

Je plaisante, il est suffisamment construis pour que nous l'utilisions, mais garde en mémoire qu'il n'est jamais nécessairement finit, tu peux à l'avenir ajouter des fonctionnalités à ton framework qui nécessiteront de modifier le BaseController.

Arthur, l'apprenti développeurAh oui j'ai déjà plein d'idées en tête

Garde les bien, on en reparlera une autre fois. On va maintenant passer à notre premier appel. J'ai terminé cette partie
Demander de l'assistance