Genèse du framework
Achevé en juillet 2020, ce framework PHP se focalise sur l'automatisation avancée de la gestion des entités.
La
Factory en charge de son entité dédiée est de nature contextuelle. Ce qui permet d'automatiser le rendu des formulaires et les accès à la base de données sans devoir fournir de champs, malgré l'absence des annotations ou d'un système équivalent.

Ce framework respecte le langage PHP. Il n'utilise pas les commentaires pour autre chose que ce à quoi ils sont destinés, la phpdoc mise à part.
Il peut donc fonctionner sans système de cache, si l'on fait abstraction de celui utilisé par le système de template Twig.

La Factory fourni une instance d'entité à taille variable selon le contexte. Un model possédant 20 attributs peut très bien se retrouver instancié avec seulement 2 attributs et les 4 méthodes get/set associées.
Par exemple, le formulaire de login que vous avez peut-être utilisé, nécessite 2 champs. L'entité "User" lié n'a donc que 2 champs "email, password", dans le contexte "
signin".
En revanche, l'entité "User" de la base de données, générée à partir de l'entité "User" du formulaire de login possède plus d'une dizaine d'attributs (date d'inscription, ip, etc sont automatiquement ajouté, contexte BDD oblige).

L'entité "User" du formulaire d'inscription possède quant à elle 3 champs "pseudonym, email, password", dans le contexte "signup". Bien qu'en réalité, il y ait 2 champs "password", le développeur n'a pas à s'en occuper. C'est la Factory qui dit au formulaire et au validator combien de fois dupliquer et vérifier un champs, ici le "password".
Les regex et la nature de chaque attribut sont également gérés automatiquement par la
Factory. Le développeur n'a pas à y toucher à l'exception de la phase de développement d'une nouvelle entité et de sa Factory.

Les entités sont générées automatiquement via une commande CRUD, soit dans le projet initial, soit dans le dossier des modules du framework si un module est spécifié et dans le cas où l'on souhaiterait créer/améliorer un module :
- php cmd create entity blog/blogPost

Cette commande génère l'entité BlogPost dans le module vendor "blog" avec les fichiers suivants :
- blog/src/class/Controller/BlogPostEntityController.php
- blog/src/class/Model/BlogPost.php
- blog/src/class/Model/BlogPostFactory.php
- blog/src/class/Model/BlogPostManager.php

Ainsi que ses vues essentiels, dont voici quelques exemples :
- blog/src/views/blogpost.html
- blog/src/views/____modals/blogpost_insert.html
-
blog/src/views/____modals/blogpost_overview.html
-
blog/src/views/____partials/blogpost.html

Il ne reste alors plus qu'à relier le contrôleur front BlogController au contrôleur back BlogPostEntityController de la nouvelle entité $blogPost.
List of post subscribers:
Système de route et cheminement d'une requête
Le système de route est basé sur l'existence ou non d'un contrôleur. Il est donc inutile de définir les routes à l'avance.
A charge au contrôleur de traiter la requête que lui soumet le routeur.
Le routeur est la pierre angulaire du framework. C'est lui qui détermine les tokens, les paramètres GET/POST/autres, les id Ajax pour faire réapparaître les liens, les contrôleurs, les namespaces, l'accès administrateur ou autre, etc.

Une requête http peut ressembler à ceci :
- https://www.muretech.com
-
https://www.muretech.com/admin/blog

Une requête Ajax peut ressembler à ceci :
- https://www.muretech.com/admin/blog/post/updatemodal/2/c99a2af8e5063b2c61153805ba30122e8c9cebd1b3d3941ec435b4bdcaf6a9e3/linkf15a80af-89fe-1669-ede3-50ffae93d42d

Même si l'entrée du site se fait par app.php, l'url suivante ne fonctionnera pas :
-
https://www.muretech.com/app.php

/*****************************
* app.php
*****************************/
namespace Feralz;
// [...]
require_once 'vendor/autoload.php';
require_once 'src/constants.php';
// [...]
$router = \Feralzdev\Router::getInstance();
$router->run();

/*****************************
* Router.php
*****************************/
namespace Feralzdev;
// [...]
/**
 * routing
 * http and ajax requests
 */
class Router
{
/**
     * call the request corresponding controller
     * @param void
     */
    private function setController() {
// [...]
    }

    /**
     * return html response according to existing controller and request nature (html or ajax)
     * if not exists, return 404 error
     * @param void
     */
    public function run()
    {
// [...]
     } else {
                echo $this->error404();
            }
        } else {
         if ($this->isAjax()) {
             $ajax = Ajax::getInstance();
             echo json_encode($ajax->getData());
         } else {
             echo $this->controller->render();
         }
// [...]
    }

/*****************************
* HomeController.php
*****************************/
namespace Feralz;
// [...]
/**
 * Main Controller
 * Home page Interface
 */
class HomeController extends Controller
{
    public function __construct() {
        parent::__construct();
        $this->htmlPath = '/';
        $this->allowBot();
    }
// [...]
/**
     * Method returning rendered html
     * @return string
     */
    public function render() {
        $session = Session::getInstance();
        $router = Router::getInstance();
        
        $postManager = new BlogPostManager();
        $posts = $postManager->findAll('date'true);

        $userId = $session->getUser()->getId();
        return $this->twig->render('home.html', [
            'posts' => $posts
        ]);
    }
}
List of post subscribers: