logoWebatoire

Mémos Symfony

Bienvenue dans la section Mémos Symfony !
vous trouverez ici toutes mes notes qui me sont utilisées pour des projets sous ce Framework (de la création d'un projet à l'utilisation d'APIs).

Installation de symfony 7

Cette section est adaptée aux Windows. Le processus d'installation Mac est différent et vous devrez consulter d'autres forums si la documentation de symfony ne vous suffit pas. (bon courage à vous !)

Installation de PHP

Dans la version actuelle de Symphony (Symphony 6), vous devez disposer d’une version de PHP supérieure ou égale à la version 8.1.

Pour savoir si vous avez PHP d'installer sur votre machine, tapez dans une invite de commande : php --version

Si vous n'avez pas PHP ou si vous n'avez pas la bonne version de PHP (retourne une version inférieure à 8.1), rendez-vous sur le site de php pour télécharger le .zip de la version Thread Safe.
Une fois téléchargé, déplacez le dossier .ZIP dans un dossier où vous avez le droit d’écrire (par exemple dans "C:\phpTools") Puis, dézippez le dossier. Puis, Dans ce dossier, regardez si vous avez un fichier “php.ini”. Si vous n’avez pas ce fichier, copier-coller le fichier “php.ini-development” et renommez le “php.ini”.

Maintenant, on va vérifier l'installation de php. Dans une nouvelle invite de commandes, retapez php --version S'il ne trouve pas votre php, il va falloir modifier vos variables d'environnement système. Pour cela, depuis le menu de windows (touche ) puis, recherchez "Modifier les variables d'environnement système" puis dans la fenêtre qui s'est ouverte, cliquez sur le bouton "Variables d'environnement...".
Double cliquez sur Path (ligne dans "variables utilisateur pour utilisateur" & celui de la ligne "variable système") et regardez si vous trouvez le chemin permettant d’accéder à votre fichier php dézippé lors des étapes précédentes. Si le chemin menant à votre dossier php n’est pas présent dans la liste des chemins, cliquez sur nouveau, puis saisissez le chemin. Si vous trouvez d’autres chemins menant vers d'autres dossiers php, cliquez sur le chemin puis sur supprimer.
Revérifiez votre php dans une nouvelle invite de commandes : php --version

Installation de Composer

Tout comme pour php, vérifier la présence (ou non) de composer sur votre machine : composer --version Si le message vous retourne une version de composer inférieur à 2.0. Alors, téléchargez le via le site de composer qui vous propose dans la section Windows Installer un lien pour télécharger une .exe pour vous faciliter l'installation. Téléchargez l'exécutable, lancez-le et installez composer.

Installation de Symfony

Rendez-vous sur le site de Symfony. Une fois sur ce site, la section Step 1 vous propose une installation Linux, macOs, Windows. En cliquant sur Windows, il vous propose une installation par Scoop et par Binaries. Dans notre cas, nous allons utiliser les Binaries. Pour se faire télécharger le dossier binaries en cliquant sur le lien "386" ou "amd64" (si vous avez des composants adm sur votre machine). Placez le zip dans votre dossier où vous avez placé votre dossier php. Extrayez le fichier symfony.exe et placez-le dans le votre version php.

Pour vérifier l'installation de symfony, ouvrez un terminal de commande et tapez : symfony local:php:list Avec cette commande, vous obtenez un tableau listant les versions de php que vous avez. La version surlignée est la version utilisée.
Si la version n’est pas la version souhaitée, créez un fichier qui a pour nom “.php-version” dans le dossier de travail. . Dans ce fichier, écrivez le nom complet de la version de php à utiliser. Vous pouvez revérifier la version utiliser avec la même commande : symfony local:php:list 📝 Le tableau que vous retourne cette commande a pour dernière colonne System?. qui vous renseigne si la version de PHP listée est la version système de PHP. Elle ne stipule en aucun cas que c'est la version php utilisée. Seul le surlignement de la colonne version donne cette information.

Création d'un projet Symfony

Maintenant que la machine est opérationnelle, il es temps de créer un projet.

Pour commencer, placer vous à l'emplacement où vous voulez créer le dossier, ouvrez une invite de commande (vous pouvez tapez cmd dans la barre de chemins de l'explorateur de fichiers pour éviter de devoir vous déplacer vous-même en passant par les lignes de commandes). Une fois au bon endroit saissez : symfony new NAME_PROJECT

Ok. Maintenant que le projet est créé, placez vous dedans avec l'invite de commande soit par une nouvelle invite de commande soit par la commande cd NAME_PROJECT Puis, procédé au reste de l'installation. Dans notre cas, nous utiliserons yarn pour compiler le code JavaScript. composer install
npm install
composer require symfony/webpack-encore-bundle
npm i yarn
yarn install
composer require symfony/orm-pack
composer require twig
composer require symfony/asset
composer require --dev symfony/profiler-pack

Et voilà, votre projet est créé ! 😊


Vous pouvez lancer votre serveur local avec la commande : symfony server:start ou, si vous avez la flemme d'avoir plusieurs invites de commandes d'ouvert, vous pouvez utiliser la commande suivant (mais vous perdez de la data) symfony server -d Et pour lancer la compilation de votre JavaScript : yarn watch
# ou directement par npm :
npm run watch

⚠️ Dans votre fichier templates/base.html.twig, il faut faire attention a bien charger le app.css et app.js. Selon le stade de l'installation où composer require symfony/webpack-encore-bundle a été exécuté, il n'a peut être pas trouvé ce fichier pour le mettre en ordre... {% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}

Interagir avec une base de données

Si vous n'avez pas encore de base de données de créée, l'idéale est de la faire en postgreSQL qui peut être manipulé avec pgAdmin4 (qui peut être installé depuis l'exécutable d'installation de postgreSQL).

Pour créer une base depuis pgAdmin 4, vous pouvez :

  1. Clic droit sur "Servers" > "Create" > "Server Group..." ;
  2. Donnez un nom à votre groupe de serveur (par exemple le nom de votre projet) ;
  3. Clic droit sur votre groupe de serveur > "Register" > "Server"
    • Section "General" : saisissez un nom ;
    • Section "Connexion" : saisissez localhost pour l'input "Host Name/address" et mettez un mot de passe simple (ça reste un serveur local) comme toto ;
    • validez votre formulaire.
  4. Cliquez sur votre serveur > "Create" > "Login/Group Role"
    • Dans "General", saisissez un nom à votre role. Par exemple admin ;
    • Dans "Definition", saisissez un mot de passe comme toto (pas besoin de faire plus compliqué, on est toujours en local) ;
    • Dans "Privileges" cochez tous les privilèges (on ne fait pas compliqué) ;
    • Enregistrez ;
  5. Clic droit sur votre serveur > "Create" > "Database"
    • Donnez un nom à votre base de données (par exemple bdd1) ;
    • Mettez admin comme Owner.
  6. Enregistrer.

Maintenant, soit vous gérez votre base de données de pgAdmin4 soit vous avez phpStorm et vous préférés l'utiliser pour gérer votre base de données. Ce qui est mon cas donc je ne détaillerai pas la partie pgAdmin4.

Pour vous connectez à votre base de données depuis phpStorm :

  1. Ouvrez l'onglet "Datatable" (onglet sur le bord droit de votre écran (sous condition de ne pas avoir trifouillé votre interface)) ;
  2. Cliquez sur le > "Data Source" > "PostgreSQL"
    • Host : localhost ;
    • Port : 5432 ;
    • User : admin (ou l'autre nom de que vous avez utilisé) ;
    • Password : toto (ou l'autre mot de passe de que vous avez utilisé) ;
    • Database : bdd1 (ou l'autre nom de base de données que vous avez utilisé ;
    • URL : jdbc:postgresql://localhost:5432/postgres (où il faudra probablement cliquer sur "télécharger" juste en dessous de l'input
  3. Testez la connexion :
    • Si Success : Validez et amusez-vous ! 👏 (double clic sur votre base de données, cliquez droit sur "public" > "new" > "table" > ...
    • Si Echec : Vérifiez votre user/password/Database. S'ils sont corrects, il y a des chance que ce soit un problème d'installation de pgAdmin4 qui n'utiliserait pas le port 5432 (conflit avec d'autres versions si vous avez fait plusieurs tentatives d'installation de pgAdmin). Dans ce cas, il faudra probablement tout désinstaller et recommencer... Si ce n'est toujours pas bon il va falloir chercher ailleurs... 😞

Avant pouvoir d'utiliser votre base de données dans votre projet, il va falloir relier les deux.

Pour celà ouvrez votre .env et repérez la ligne qui correspond à votre base de données. Pour du postgreSQL, le début ressemble à DATABASE_URL=postgresql://. Créez un fichier .env.local si vous n'en avez pas encore et déplacez y cette ligne.
Enfin complétez là avec les bonnes informations. Si vous avez suivi le tuto à la lettre vous aurez la ligne : DATABASE_URL=postgresql://admin:toto@127.0.0.1:5432/bbd1?serverVersion=15&charset=utf8

Stimulus

Pour ajouter du JS à votre front dans un projet Symfony, Stimulus et là pour avoir un code tout propre !


Pour l'installer, c'est facile : composer require symfony/stimulus-bundle
npm install --force
yarn watch
Et normalement, c'est tout ce que vous avez à faire.

Déployer votre projet sur un serveur

Mise en place du serveur

Pour déployer notre projet sur un serveur, vous pouvez utiliser Bitevise SSH Client pour rentre des lignes de commandes dans votre serveur. Pour vous connecter utiliser l'adresse IPv4 de votre serveur mot Host, "ubuntu" comme Username (j'imagine qu'il peut varier si vous prenez autre chose qu'un serveur qui tourne sur ubuntu). Sélectionnez "password" comme Initial method et enfin saisissez le mot de passe permettant l'accès à votre serveur (généré depuis un lien envoyé dans votre boite mail si vous êtes chez OVH).
Connectez vous et ouvrez un terminal.

Depuis ce terminal, nous allons commencer à installer nginx qui est un serveur web permettant de faire le lien entre votre nom de domaine et votre projet web. sudo apt update
sudo apt install nginx
sudo service nginx restart
sudo add-apt-repository universe
sudo apt install php-fpm

Installation de PostgreSQL : sudo apt install postgresql
pg_config --version

Installation de Php 8.2 : Pour installer php8.1, il suffit de faire : sudo apt install php8.1 Cependant, au moment où je rédige ce bloc, cette simplicité d'installation ne fonctionne pas avec les versions supérieures. C'est pourquoi je conseille ce tutoriel pour avoir des instructions avec images pour installer php 8.2.

Si votre base de données est en PostgreSQL, il va falloir installer la composante : php8.2-pgsql sudo apt install php8.2-pgsql

Installation de Composer : php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

sudo mv composer.phar /usr/local/bin/composer

Installation de NodeJs et de npm : cd ~
curl -sL https://deb.nodesource.com/setup_18.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh
sudo apt install nodejs

node -v
npm -v

Installation de Symfony : curl -sS https://get.symfony.com/cli/installer | bash
sudo mv .symfony5 /usr/local/bin/symfony

Installation de Git : sudo apt install git-all

Dépôt de votre projet

Pour commencer, placez-vous dans le dossier qui va centraliser vos fichiers. cd /var/www/html Si votre projet est sur git cloner le ici (dans le cas contraire, rapatriez votre projet ici). Pour que ce soit plus pratique, le dossier du projet aura pour le nom, le nom du domaine ou sous-domaine utilisé pour ce dit projet. git clone lien_github_du_projet nom_projet Placez vous dans votre dossier et installez composer et npm. puis compilez le JS. sudo composer install
sudo composer update
sudo npm install
sudo npm run watch
Une fois compilé, vous pouvez arrêter le compilateur (CTRL + C).

Maintenant, on va configurer nginx pour associer votre domaine (ou sous-domaine) à votre projet.

Si ce n'est pas déjà fait, allez sur votre hébergeur et reliez un domaine (ou sous-domaine) à l'adresse (Si vous utilisez OVH, vous pouvez le faire depuis l'onglet Redirection depuis votre nom de domaine). Pour notre exemple, on va prendre comme sous-domaine "tuto-symfony.imanora.fr".

Du côté serveur, on va créer un fichier de configuration du site nginx propre au projet. En séparant les projets, celà permet de ne pas mélanger les routes entre deux projets (tout en permettant de mettre des spécificités différentes entre chaque projet). sudo nano /etc/nginx/sites-available/tuto-symfony.imanora.fr


server {
    listen 80;

    server_name tuto-symfony.imanora.fr;

    client_max_body_size 20M;

    root /var/www/html/tuto-symfony.imanora.fr/public;
    index index.html  index.php;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS off;
    }

    location ~ \.php$ {
        return 404;
    }
    location ~ /\.ht {
	deny all;
    }
    error_log /var/log/nginx/tuto-symfony.imanora.fr_error.log;
    access_log /var/log/nginx/tuto-symfony.imanora.fr_access.log;
}


    

Sauvegardez votre fichier avec CTRL + S puis fermez le avec CTRL + X.

La ligne client_max_body_size 20M; Permet de limiter la taille des fichiers que les utilisateurs peuvent déposer sur le serveur à 20Mo.

Une fois votre fichier de configuration créé, on va pour l'activer avec les lignes suivantes : sudo ln -s /etc/nginx/sites-available/tuto-symfony.imanora.fr /etc/nginx/sites-enabled/
sudo unlink /etc/nginx/sites-enabled/default
sudo systemctl reload nginx

Si vous devez plus tard mettre votre code à jour et que vous souhaitez le faire depuis votre repo github, il vous suffit de vous replacer dans votre dossier de votre projet (depuis le terminal serveur) et de faire la commande sudo git pull

À ce stade, votre site doit être accessible en HTTP. Pour passer en HTTPS, nous allons maintenant faire une demande de certification SSL

Si vous avez déjà utilisé Certbot pour faire cette certification, il vous faut simplement faire la demande de certification sur le nouveau nom de domain / sous-domaine : sudo certbot --nginx -d tuto-symfony.imanora.fr
Dans le cas contraire il va falloir installer Certbot avant : sudo snap install core; sudo snap refresh core
sudo apt remove certbot
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Et maintenant vous pouvez faire la demande de certification : sudo certbot --nginx -d tuto-symfony.imanora.fr Tada ! Votre site est désormais accessible par tout le monde (et en https) ! 😊

Si vous utilisez une base de données, pensez à ajouter à votre projet le .env.local pour éviter que le site râle sur un DATABASE_URL qu'il ne trouve pas.

Si vous voulez modifier votre dossier de travail depuis une interface SFTP, vous devez vous assurer d'avoir les droits : sudo chown -R ubuntu:ubuntu /var/www/html/tuto-symfony.imanora.fr

Sources : Déploiement ; Certification SSL

Petits bonus

Lors de la configuration nginx, j'ai évoqué la ligne client_max_body_size 20M; qui permet d'autoriser les utilisateurs à déposer un fichier <= 20Mo. Mais il ne faut pas oublier d'adapter le php.ini en conséquence...
Mission 1 : trouver le fichier. Dans ma config nginx, on parle du php php8.2-fpm. Pour trouver son php.ini, on peut faire find / -name php.ini Une fois trouvé, ouvrez-le. Dans mon cas : sudo nano /etc/php/8.2/fpm/php.ini Il faut aussi le faire sur la version cli : sudo nano /etc/php/8.2/cli/php.ini Puis trouvez la partie File Uploads et modifiez la ligne upload_max_filesize pour changer la taille Max de fichier accepté. On peut en profiter pour ajuster le nombre de fichier max déposable en une seule requête : ;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;

; Whether to allow HTTP file uploads.
; https://php.net/file-uploads
file_uploads = On
; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
; https://php.net/upload-tmp-dir
;upload_tmp_dir =

; Maximum allowed size for uploaded files.
; https://php.net/upload-max-filesize
upload_max_filesize = 20M

; Maximum number of files that can be uploaded via a single request
max_file_uploads = 1
Après avoir modifier notre php.ini, il faut redémarrer notre service php : sudo systemctl restart php8.2-fpm.service Donner une limite de fichier, c'est bien. Mais si vous déposer une image de 15M dans votre formulaire et que vous l'envoyé, il ne va rien se passer. Par défaut, votre php.ini limite la taille des POST à 8M. Pour ajuster cette limite il faut remodifier dans les php.ini la ligne post_max_size que vous pouvez par exemple mettre à 0 si vous ne voulez plus jamais rencontrer ce problème (attention, niveau sécurité on peut plus facilement pourrir le serveur avec cette limitation en moins...). ;;;;;;;;;;;;;;;;;
; Data Handling ;
;;;;;;;;;;;;;;;;;

...

; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; https://php.net/post-max-size
post_max_size = 30M
Attention, si le dossier de dépôt ne donne pas la permission de dépôt ça peut être embarrassant...
Pour avoir un exemple, on va dire que notre utilisateur peut déposer et supprimer des images dans le dossier public/images/uploads. # Accédez au répertoire contenant les images
cd /var/www/html/tuto-symfony.imanora.fr

# Vérifiez les permissions du dossier (si on est bon, pas besoin de faire la suite)
ls -l public/images/uploads

# Changez les permissions du dossier (propriétaire et groupe)
sudo chown -R www-data:www-data public/images/uploads

#Ajustez les Permissions
sudo chmod -R 755 public/images/uploads

#Redémarrez le Serveur Nginx
sudo systemctl restart nginx

Installation de la base de données

Lancez pgsql avec la commande : sudo -u postgres psql Puis créez un admin pour votre base de donnée : create role admin LOGIN SUPERUSER PASSWORD 'lv7<*Y94ivHODFhdf79!'; Ensuite, créez votre base de donnée : create database bdd_name Enfin, lancez vos scripts de base de données depuis des outils externes tels que DataGrip, PhpStorm...

N'oubliez pas le ';' à la fin de chaque commande sql. Sinon votre commande sera en attente d'un ';' et ne sera pas exécutée....

N'oubliez pas d'ajouter un fichier .env.local à votre projet avec les bonnes données pour vous connectez avec votre base de données

En essayant de vous connecter, il est probable que vous ayez une échec de connexion. Dans ce cas, il faut travailler les droits d'accès à la base de données du serveur.
Pour ce faire, on va donner le droit d'accès à tout le monde (l'idéal est de mettre vos ip personnels afin que vous seul puisse y accéder...).

Premier fichier à modifier (si besoin, modifiez la première commande pour l'adapter à votre version de postgresql) : sudo nano /etc/postgresql/15/main/postgresql.conf trouvez et décommentez la ligne #listen_addresses = 'localhost' Remplacez 'localhost' par '*' pour avoir : listen_addresses = '*' # what IP address(es) to listen on; Sauvegardez et fermez le fichier (CTRL + S puis CTRL + X).
Puis, ouvrez un nouveau fichier (même commentaire que ci-dessus pour al version de postgresql) : sudo nano /etc/postgresql/15/main/pg_hba.con Trouvez la partie du code qui contient les deux lignes suivantes : # IPv4 local connections:
host all all 127.0.0.1/32 scram-sha-256
Et modifier l'adresse ip pour avoir : # IPv4 local connections:
host all all 0.0.0.0/0 scram-sha-256
Enfin, redémarrez PostgreSQL : sudo service postgresql restart Et vous pouvez maintenant vous connecter à votre base de données ! 😊

Fontawesome

Fontawesome est une bibliothèque icons bien pratique pour utiliser des icônes au format svg sans devoir les faire sois-même.


Pour l'installer, c'est facile : npm i font-awesome Puis, dans votre fichier app.js (rangé dans le dossier assets), vous ajoutez les deux lignes suivantes : require('@fortawesome/fontawesome-free/css/all.min.css');
require('@fortawesome/fontawesome-free/js/all.js');
Et... Tada ! Fontawesome est prêt à l'emploi !

Mécanismes de comptes

Comme pour les autres sections, on va commencer par installer tout ce dont on a besoin (on en profite pour générer les fichiers nécessaires) : composer require symfony/security-bundle
composer require --dev symfony/maker-bundle
php bin/console make:controller Login
composer require symfony/uid
Maintenant la partie installation faite, il vous faut une table utilisateur à votre base de données.
On va en profiter pour y ajouter un utilisateur (identifiant : toto; mot de passe : toto), qui aura le rôle d'admin.
create table utilisateur
( id uuid not null
constraint utilisateur_pk
primary key,
identifiant varchar not null,
password varchar,
roles json not null,
);
alter table utilisateur
owner to admin;
INSERT INTO public.utilisateur (id, identifiant, password, roles) VALUES ('f32b5e6f-82e3-4686-86c7-2aaf53df94c0', 'toto', '$2y$10$j8LnD4waXiqK5BKnEJ.cju5vUEO3tcwaHSYwG18RuxwiInjcwWhPG', '{"0": "ROLE_ADMIN"}');
On oublie pas de créer l'Entity Utilisateur pour faire la liaison entre notre projet et notre base de données (ainsi que son Repository).

Pour rendre la suite plus pratique, les fichiers utiles sont fournis dans le zip ci-dessous :

Télécharger le dossier mecanismes_comptes.zip

Dans ce dossier vous pouvez y retrouver :

  • le fichier Utilisateur.php qui correspond à l'Entity de la table utilisateur donnée plus haut ;
  • le fichier UtilisateurRepository.php qui correspond à le Repository pour compléter l'Entity Utilisateur ;
  • Le dossier login qui contient le fichier index.html.twig qui correspond au formulaire de connexion et le fichier accessDenied403.html.twig qui correspond au template retourné lorsqu'on ne dispose pas les droits pour accéder à une page. Libre à vous d'adapter leur contenu. Leur place est dans le dossier templates/login qui contient déjà un fichier index.html.twig que vous pouvez remplacer par le nouveau fichier.
  • Le dossier Security est a placé dans le dossier src de votre projet. Il permet de gérer l'authentification et les contrôles d'accès. Dans UserAuthenticator.php, on gère les pages à retourner après connexion (ligne 64)

    ⚠️ Si votre l'entity de votre utilisateur à un nom différent de "Utilisateur", il faut penser à modifier son appel dans le fichier UserChecker.php

    ⚠️ Si vous avez nommé le fichier accessDenied403.html.twig différemment, il faut penser à modifier son appel dans le fichier AccessDeniedHandler.php

  • Enfin le fichier security.yaml permet de faire fonctionner le tout (donc vaut mieux ne pas l'oublier). Il est à mettre dans config/packages. Il y a déjà un fichier de même nom créé, donc libre à vous de l'écraser ou juste de remplacer son contenu.

    ⚠️ Si votre l'entity de votre utilisateur à un nom différent de "Utilisateur", il faut penser à modifier le nom dans ce fichier. Il en va de même pour les fichiers dans le dossier Security, si vous avez donné des noms différents de ce fourni dans le zip, alors il faut également modifier leurs appels dans ce fichier.

Créer des fichiers Core

Le but d'un Core est multiple :

  • Organisation du projet : Les fonctions routes sont dans les fichiers Controller. Les autres fonctions créées qui permettent de réduire la taille des fonctions vont être placés dans ces fichiers Core.
  • Réutilisation des fonctions : L'avantage du Core, c'est qu'on peut appeler les fonctions core dans plusieurs controller. Ca évite d'avoir des fonctions dupliquées pour rien.
  • Pratique pour l'entityManager : au lieu de le mettre en paramètres de chaque fonction, on va profiter de la structure du projet avec des cores pour généraliser cet appel.

C'est parti !

On va commencer par créer un dossier src/Core. Puis, on va créer notre fichier core (OutilCore.php pour notre exemple). Dans ce fichier on va y mettre toutes nos fonctions qu'on ne veut pas dans notre controller.


<?php

namespace App\Core;

class OutilCore
{
    private variable...
    public function maFonction()
    {
        ...
    }
}


    

Ok, maintenant on va créer un Controller qui va permettre d'appeler ces Cores et de les utiliser facilement dans les autres Controllers. Le nom sera généralement NomProjetController.php. (on peut en faire plusieurs si on veut donner l'accès à certaines fonction uniquement à certains controllers. Ça va être le cas si on utilise des rôles [utilisateurs, admin, etc...]).

Dans ce fichier, on va faire appels à nos cores qu'on souhaite centraliser et on peut en profiter pour y mettre notre entityManager :


<?php

namespace App\Controller;

use App\Core\OutilCore;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class NomProjetController extends AbstractController
{
    protected OutilCore $outilCore;
    protected EntityManagerInterface $entityManager;

    public function __construct(OutilCore $outilCore, EntityManagerInterface $entityManager)
    {
        $this->outilCore = $outilCore;
        $this->entityManager = $entityManager;
    }
}


    

Ok. Maintenant dans notre controller (par exemple MainController), on va extends NomProjetController et non AbstractController. Comme NomProjetController extends AbstractController, on va pouvoir continuer à utiliser les fonctions accessibles grâce à AbstractController (comme render->()).
Voilà un exemple d'utilisation :


class MainController extends NomProjetController {
    ....
    public maFunction(){
       $x = $this->outilCore->maFonction();
       $y = $this->entityManager->getRepository(MaClass:class)->findAll();
    }
}


    

Créer des modales

Plutôt que de réécrire toute une modale à fois qu'on veut en utiliser une, on va généraliser cette dernière dans le fichier base.html.twig :


{% block modal %}
    <div id="myModal" class="modal d-none">
        <div id="modal-content" class="modal-content bubble" data-modal-target="content">
            <h1> Chargement ...</h1>
        </div>
    </div>
{% endblock %}


    

Maintenant, on va s'occuper des fonctions pour gérer les modales. Histoire d'avoir un joli code, on va utiliser Stimulus. Dans votre élement body on va y ajouter : data-controller="modal" Puis on va créer notre fichier modal_controller.js dans le dossier assets/controllers.
On va y ajouter nos fonctions de controls :


import {Controller} from '@hotwired/stimulus';
import application from '../stimulus';

export default class extends Controller {
    static targets = ["content"];

    openModal(event) {
        fetch(event.currentTarget.getAttribute('data-path'))
            .then(response => {
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                return response.text();
            })
            .then(data => {
                this.contentTarget.innerHTML = data;
                document.getElementById('myModal').classList.remove('d-none');

                setTimeout(()=> {
                    document.getElementById('modal-content').style.transform = 'scale(1)';
                    document.getElementById('modal-content').style.opacity = '1';
                }, 20);

                // Trouver et initialiser les contrôleurs dans le contenu nouvellement chargé
                const controllers = application.controllers;
                const elements = this.contentTarget.querySelectorAll("[data-controller]");
                elements.forEach(element => {
                    const controllerNames = element.getAttribute("data-controller").split(" ");
                    controllerNames.forEach(controllerName => {
                        const controller = controllers.find(c => c.identifier === controllerName);
                        if (controller) {
                            controller.initialize(element);
                        }
                    });
                });
            })
            .catch(error => {
                console.error('Erreur lors de la récupération des données : ', error);
            });
    }

    closeModal() {
        setTimeout(()=> {
            document.getElementById('modal-content').style.transform = 'scale(0)';
            document.getElementById('modal-content').style.opacity = '0';
        }, 20);
        setTimeout(()=>document.getElementById('myModal').classList.add('d-none'), 500);
        document.getElementById('modal-content').innerHTML = `<h1> Chargement ...</h1>`;

    }

    async ok(e) {
        e.preventDefault();
        const form = new FormData(this.element.getElementsByTagName('form')[0]);
        await fetch(e.currentTarget.dataset.url, {method: 'POST', body: form});
        this.closeModal();
    }
}


    

La fonction ok(e) est à utiliser dans votre modale lorsque, voulez traiter du php avant de fermer votre modale. Comme, valider un formulaire.

Pour ouvrir une modale, vous devez avoir une route dans un controller qui retourne un template classique et appelé votre route en passant par votre controller stimulus : <div data-action="click->modal#openModal" data-path="{{ path('maRoute') }}"> Ouvrir modale </div>

Concernant le CSS, on va utiliser la class modal pour empêcher les interactions avec le contenu de la mage hors modale. Dans le code ci-dessous on en profite pour flouter et foncer l'arrière-plan.

L'élément de class modal-content va contenir le template a afficher dans la modale. C'est pourquoi dans le code css ci-dessous, on le centre sur la page en lui donnant une dimension inférieure à 100vw x 100vh.


.modal {
    z-index: 10000;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.2);
    backdrop-filter: blur(10px);
}

.modal-content {
    position: absolute;
    left: 50%;
    top: 50%;
    translate:-50% -50%;
    padding: 20px;
    width: 80%;
    max-height: 80vh;
    min-height: 50vh;
    transition: all .5s;
    transform: scale(0);
    opacity: 0;
}


    

API Mailjet

Mailjet est un outil permettant l'envoie de mails qui autorise 6 000 envoie de mails par jour dans sa version gratuite.

Pour commencer, créez-vous un compte Mailjet afin de récupérer vos clés api.

Pour l'installer : composer require symfony/mailjet-mailer Puis, dans votre .env.local, on va y ajouter nos clés : MAILER_DSN=mailjet+api://PUBLIC_KEY:PRIVATE_KEY@api.mailjet.com

Ensuite, on va créer des fichiers services dans notre projet pour gérer nos envois de mails. Pour ce faire, veillez à avoir un dossier src/Service dans votre projet. Puis créez-y les fichiers suivants :

Fichier MailjetService.php : va permettre de demander l'envoie du mail a mailjet


<?php

namespace App\Service;

use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;

class MailjetService
{
    public function __construct(MailerInterface $mailer)
    {
        $this->mailer = $mailer;
    }

    public function sendMail($mailData)
    {
        $email = (new Email())
            ->from('adresse_liee_mailjet@email.fr') // insérez ici votre adresse mail associée à votre mailjet (adresse qui servira pour envoyer vos emails)
            ->to($mailData['to'])
            ->subject($mailData['subject'])
            ->html($mailData['message'])
        ;

        $this->mailer->send($email);
    }
}


    

Fichier EmailsTemplateSenderService.php : permet de mettre en forme vos emails à partir de templates twig. Voici deux exemples de fonctions que vous pouvez avoir :


<?php

namespace App\Service;

use Twig\Environment;

class EmailsTemplateSenderService
{
    private $mailer;
    private $twig;

    public function __construct(Environment $twig, MailjetService $mailer)
    {
        $this->mailer = $mailer;
        $this->twig = $twig;
    }


    public function sendMailBienvenue($destinataire)
    {
        $mailData = [
            'to' => $destinataire,
            'subject' => 'Bienvenue sur notre site',
            'message' => $this->twig->render('emails/bienvenue.html.twig'),
        ];
        $this->mailer->sendMail($mailData);
    }

    public function sendMailInformations($destinataire, $message, $client)
    {
        $mailData = [
            'to' => $destinataire,
            'subject' => 'EGN - site web',
            'message' => $this->twig->render('emails/information.html.twig', [
                'client' => $client,
                'message' => $message,
            ]),
        ];
        $this->mailer->sendMail($mailData);
    }
}


    

Pour ordonnez vous projets, créés vos templates d'emails dans le même dossier dans le répertoire template. Par exemple, dans mon cas, je range tous mes templates de mails dans templates/emails

il ne reste plus qu'à trigger vos fonctions d'envoi quand vous le voulez pour envoyer votre message :
1. Déclarer votre EmailsTemplateSenderService dans votre fonction de route : #[Route (path:'/ma-route', name:'maRoute' )]
public function maRoute(Request $request, EmailsTemplateSenderService $emailService): Response
{
...
Puis appelez votre fonction : $emailService->sendMailInformations('destinataire@email.fr',$message, $client);
$this->addFlash('success', 'Message envoyé !'); // c'est toujours sympa pour confirmer l'envoie de l'email

API BAN (Base Adresse Nationale)

L'API BAN permet de de faire des requêtes vers une base d'adresses postales.
Dans cette section on va voir comment l'utiliser dans le cas de l'autocomplétion d'un input.


Les installation requises : composer require symfony/http-client

Vous retrouverez les fichiers à créer ici :

Télécharger le dossier api_ban.zip

Ce dossier comprend :

  • Le fichier AdresseApiService.php à placer dans le dossier (à créer si inexistant) src/Service. Cette classe pgp va nous permettre d'interagir avec la base d'adresses. Dans notre cas, toutes les méthodes ne vont pas être utilisées donc libre à vous de conserver celles qui vous intéressent ;
  • Le fichier AdresseApiController.php à placer dans le dossier src/Controller. Ce controller va nous permettre de trigger les fonctions du fichier précédent

Enregistrez le service dans votre fichier de configuration des services config/services.yaml


services:
    App\Service\AdresseApiService:
        arguments:
            $client: '@http_client'


    

Dans votre formulaire Symfony, ajoutez le champ de saisie d'adresse :


 ->add('adresse', TextType::class, [
                'label' => false,
                'attr' => ['placeholder'=>'Adresse postale complète'],
                'required' => true
            ])


    

Puis ajoutez le JavaScript (qui utilise jquery donc il faut penser à l'installer) :


    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    <script>
        $(function() {
            $("#pre_reservation_cible_adresse").autocomplete({
                source: function(request, response) {
                    $.ajax({
                        url: "{{ path('autocomplete_address') }}",
                        dataType: "json",
                        data: {
                            q: request.term
                        },
                        success: function(data) {
                            response(data);
                        }
                    });
                },
                minLength: 3,
                select: function(event, ui) {
                    console.log("Selected: " + ui.item.value + " with id " + ui.item.id);
                }
            });
        });
    </script>


    

API Google reCaptcha v3

L'api Google reCaptcha v3 permet de limiter les robots sur vos formulaires de vos sites en calculant "la probabilité d'être un robot" selon les interactions de l'utilisateur sur l'ensemble de la page qui contient le formulaire.

Tout d'avoir, rendez-vous sur le site de Google reCaptcha et allez sur l'interface "v3 Admin Console" puis créez un projet. Sur ce projet ajoutez le domaine de votre projet s'il est déjà héberger et/ou localhost pour tester sur le serveur local.

Lors de l'ajout de vos domaines, n'oubliez pas d'appuyez sur entrée pour validée la saisie...

Pour la partie code, on va utiliser la bibliothèque KarserRecaptcha3Bundle. Pour l'installer : composer require karser/karser-recaptcha3-bundle Où on va suivre les instructions données sur github : on répond non (n) pour le recipe google/recaptcha et oui (y) pour le recipe karser/karser-recaptcha3-bundle.
Puis, dans le fichier config/packages/karser_recaptcha3.yaml, on va vérifier sa structure :


karser_recaptcha3:
    site_key: '%env(RECAPTCHA3_KEY)%'
    secret_key: '%env(RECAPTCHA3_SECRET)%'
    score_threshold: 0.5
    enabled: true


    

À vous de feuilleter la documentation de Google reCaptcha v3 pour voir si d'autres paramètres peuvent vous être utils.

Puis, dans votre fichier .env.local, on va y mettre nos clés RECAPTCHA3_KEY=clé_du_site
RECAPTCHA3_SECRET=clé_secrete

ReCaptcha v3 est prêt a être utilisé, pour ce faire, allez sur votre formulaire et ajoutez le champ de recaptcha à la toute fin du formulaire :


 ->add('captcha', Recaptcha3Type::class, [
                'constraints' => new Recaptcha3(),
                'action_name' => 'action' //mot pour définir le but du formulaire. Par exemple 'depot' si le formulaire sert à déposer un document
            ])
    

    
Loading…
Loading the web debug toolbar…
Attempt #