Préparation de la base du test sur l'OO dans un modèle MVC en PHP 8
https://github.com/WebDevCF2m2021/NewsWebPrepaTest/projects/1
- Demande du client
- Installation de Twig
- Création du système de fichier MVC
- Le fichier config.php
- La base de données
- Le contrôleur frontal
- Le design par défaut du client
- Les vues pour le design par défaut du client
- Création de notre autoload sur le dossier model
- Création de notre connexion PDO
- Création du routeur
- Création des modèles de mapping de tables
Les news du Web
Il s’agit de réaliser un site qui affiche des nouvelles concernant le Web ou l’informatique en général.
Il se présente sous la forme d’un journal.
Chaque nouvelle, est un résumé d'article qui affiche :
- le titre
- la date et heure de publication
- le nom de l’auteur
- le début du texte (les 100 premiers caractères) avec possibilité de voir ensuite le texte complet sur
une autre page
Il y a un menu de navigation sur chaque page, avec :
- un lien vers l’accueil
- un lien vers la page affichant tous les articles
- un lien vers un espace d’administration avec login/mot de passe
Il y a :
- une page d’accueil affichant les 3 dernières news (les 3 plus récentes).
- une page affichant tous les extraits d'articles classés par date (du plus récent au plus ancien)
- Le client souhaiterait que ces articles aient un flux RSS
Il doit être adapté pour être responsive.
Version 1
Sur la page d’accueil, la nouvelle la plus récente est mise en évidence (par exemple : en premier ou
encadrée ou dans une zone plus large, à définir).
Les articles doivent être lus, ajoutés, modifiés et supprimés via un CRUD
Et voici les liens vers le design frontend et backend qu'il nous a fourni :
https://partage2021.webdev-cf2m.be/WEB/NewsWeb/
https://github.com/WebFormP/NewsWeb
https://github.com/WebFormP/AdminNewsWeb
https://github.com/WebFormP/NewsWeb_PHP
Vérifiez d'abord que vous utilisez PHP 8 et que composer soit installé et à jour :
composer self-update
Nous utiliserons Twig 3 comme moteur de templates :
composer require "twig/twig:^3.0"
Et pour l'installer depuis composer.json
:
composer update
public
Le dossier où se trouveront le contrôleur frontal et les fichiers publics dans des sous-dossiers (css, js, images etc ...)controller
Le dossier contenant nos contrôleursmodel
Le dossier contenant nos classes personnellesview
Le dossier contenant nos vuestwig
data
Le dossier contenant les fichiers utiles pour la création du site, les fichiers sql seront modifiés lors de la mise en production pour éviter le piratage du site.
La racine contiendra les fichiers de configurations.
Le fichier config.php
devra être récréé à la racine en copiant et en renommant config.php.ini
.
Ce fichier contient des données sensibles et ne sera pas mis sur github pour des raisons de sécurité.
Importons en MariaDB la base de données avec les datas depuis
data/newsweb_v1_structure_datas.sql
Ne contient au départ que l'appel des dépendances et l'instanciation de l'environement Twig
// dependencies
require_once "../config.php";
// Composer autoload
require_once '../vendor/autoload.php';
// Twig loader
$loader = new \Twig\Loader\FilesystemLoader('../view');
$twig = new \Twig\Environment($loader, [
//'cache' => '../view/cache',
]);
Dans data
nous avons mis le zip contenant le template par défaut proposé par le client.
Nous allons ensuite mettre les fichiers dans les dossiers css
, fonts
, js
et images
de ce design dans le
dossier public
, car c'est le seul accès frontend au site.
On va ensuite dézipper ces données dans data pour pouvoir tester le fonctionnement du template par défaut dans
data/test-default-template
Nous constatons que celui-ci diffère du modèle donné par le client consultable à cette adresse :
https://partage2021.webdev-cf2m.be/WEB/NewsWeb/sources/
Nous allons donc prendre la source du client et la mettre dans le dossier :
data/sources
Nous allons utiliser la base de index.html
se trouvant dans ce dossier pour structurer notre vue de l'accueil public.
Pour tester le fonctionnement de Twig, nous allons d'abord créer dans view
la base de toutes nos pages de template :
view/base.html.twig
Contenant, en partant de la base nécessaire à toutes les pages du modèle :
<!DOCTYPE html>
<html lang="fr">
<head>
{% block meta %}
<meta charset="UTF-8">
{% endblock %}
<title>{% block title %}NewsWeb | {% endblock %}</title>
{% block stylesheets %}{% endblock %}
</head>
<body id="{% block pagetype %}{% endblock %}">
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>
Puis un appel de render
sur ce fichier depuis public/index.php
:
...
// test render Twig
echo $twig->render('base.html.twig');
Nous allons l'étendre pour toutes nos vues publiques dans un autre fichier de template:
view/public/public.template.html.twig
Nous allons y charger les dépendances dans les blocs existants (js, css etc... ) et créer les bloques nécessaires pour les pages enfants
{% extends 'base.html.twig' %}
...
{% block body %}
<div id="wrapper">
{# On va créer les différentes zones modifiables du template dans le bloc body #}
{% block logo %}{% endblock %}
{% block nav %}{% endblock %}
{% block slider %}{% endblock %}
{% block main %}{% endblock %}
{% block footer %}Ici le footer qui
restera le même pour tous{% endblock %}
</div>
{% endblock %}
Puis un appel de render
sur ce fichier pour le tester depuis public/index.php
:
...
// test render Twig
echo $twig->render('public/public.template.html.twig');
Création de la vue homepage :
view/public/homepage.html.twig
Contenant les tags Twig
et le code html
venant du template de Pierre, tout en mettant le slider en commentaire pour
ne pas le voir :
{% extends 'public/public.template.html.twig' %}
{% block title %}{{ parent() }} Accueil {% endblock %}
{% block pagetype %}home{% endblock %}
...
{# On va remplir les différentes zones modifiables du template dans le bloc body #}
{% block logo %}ici{% endblock %}
{% block nav %}et{% endblock %}
{% block slider %}<!--aussi-->{% endblock %}
{% block main %}ici{% endblock %}
Puis un appel de render
sur ce fichier depuis public/index.php
:
...
// test render Twig
echo $twig->render('public/homepage.html.twig');
Création de la vue blog :
view/public/blog.html.twig
contenant le reste de la page :
{% extends 'public/public.template.html.twig' %}
{% block title %}{{ parent() }} Liste de nos articles {% endblock %}
{% block pagetype %}blog{% endblock %}
...
Dans public/index.php
nous allons créer un autoload permettant de charger nos classes qui se trouveront dans model
spl_autoload_register(function($class){
include_once '../model/'.$class . '.php';
});
Nous allons créer une connexion PDO personnalisée sous le nom de MyPDO
dans notre dossier model
! Nous donnerons un namespace à nos modèles : NewsWeb
, et nous l'utiliserons comme nom de dossier pour que l'autoload reste fonctionnel !
model/NewsWeb/MyPDO.php
contiendra
namespace NewsWeb;
use Exception;
use PDO;
class MyPDO extends PDO
{
// surcharge du constructeur avec l'ajout de l'argument $production
public function __construct(string $dsn, string|null $username, string|null $password, array|null $options, bool $production = true)
{
// chargement du constructeur parent (qui vient de PDO)
parent::__construct($dsn, $username, $password, $options);
// si nous sommes en production
if ($production) {
// nous désactivons l'affichage d'erreur
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
}
}
// écrasement du query venant du parent (PDO)
public function query($statement, $mode = PDO::ATTR_DEFAULT_FETCH_MODE, ...$fetch_mode_args): Exception
{
// affichage de l'erreur
throw new Exception("Query est désactivé dans MyPDO, veuillez utiliser une requête préparée");
}
}
Puis sera appelé depuis le contrôleur frontal :
...
// use NewsWeb MyPDO class
use NewsWeb\MyPDO;
...
// tentative de connexion à notre DB avec notre classe étendue de PDO : MyPDO
try {
$connectMyPDO = new MyPDO(DB_TYPE . ':dbname=' . DB_NAME . ';host=' . DB_HOST . ';charset=' . DB_CHARSET . ';port=' . DB_PORT, DB_LOGIN, DB_PWD, null, PROD);
} catch (Exception $e) {
die($e->getMessage());
}
Nous allons créer un routeur pour pouvoir passer d'une page à l'autre et le charger depuis le contrôleur frontal
public/index.php
...
// blog
if(isset($_GET['blog'])):
echo $twig->render('public/blog.html.twig');
// contact
elseif(isset($_GET['contact'])):
echo $twig->render('public/contact.html.twig');
// homepage
else:
echo $twig->render('public/homepage.html.twig');
endif;
Dans le dossier model/NewsWeb/
model/NewsWeb/AbstractMapping.php
namespace NewsWeb;
class AbstractMapping
{
// constructeur - Appelé lors de l'instanciation
public function __construct(array $tab)
{
// tentative d'hydration des données de Personnage
$this->hydrate($tab);
}
// création de notre hydratation, en partant d'un tableau associatif et de ses clefs, on va régénérer le nom des setters existants
protected function hydrate(array $assoc)
{
// tant qu'on a des éléments dans le tableau
foreach ($assoc as $clef => $valeur) {
// création du nom de la méthode
$methodeName = "set" . ucfirst($clef);
// si la méthode existe
if (method_exists($this, $methodeName)) {
$this->$methodeName($valeur);
}
}
}
}
twig extension
composer require twig/string-extra
class.upload
composer require verot/class.upload.php
pour éviter de faire le travail des web 2019 :
https://github.com/WebDevCF2019/intranetCF2m/blob/master/model/uploadDoc.php
dans thearticleManager.php
faire la partie MySQL :
// Récupération de l'article (idthearticle, thearticletitle, thearticletext, thearticleresume, thearticledate ) avec toutes les rubriques avec le lien, l'auteur et le lien vers celui-ci, via son slug
Modifiez la vue publique nommée 'article.html.twig' qui l'affiche
En partant du modèle se trouvant
NewsWebPrepaTest/data/template_admin1/startbootstrap-sb-admin-2-gh-pages/blank.html
Créez le template de base ET une page d'accueil lors de la connexion dans l'admin, et ce en se connectant avec pierre
et sandron
comme mot de passe :
- view/private/private.template.html.twig - enfant de
view/base.html.twig
et contenant la structure commune à toutes les autres pages (jss, css etc...), avec l'utilisation des blocs (blocs libres)
et
- view/private/homepage.template.html.twig - enfant de
view/private/private.template.html.twig
qui contiendra le titre, le nom de l'utilisateur connecté et son rôle, et la possibilité de se déconnecter ! Faîtes un dump de la session dans le partie contenu de la page homepage.
Cette vue sera appelée en Twig depuis controller/private/privateRouterController.php
- Il faut donc être connecté pour
la voir