<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://wiki.abdoulaye-diallo.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Abdoulaye</id>
	<title>Gandal - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.abdoulaye-diallo.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Abdoulaye"/>
	<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Sp%C3%A9cial:Contributions/Abdoulaye"/>
	<updated>2026-07-07T16:00:42Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.40.1</generator>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Bonnes_pratiques_:_Mettre_en_place_un_projet_VibeCod%C3%A9&amp;diff=97</id>
		<title>Bonnes pratiques : Mettre en place un projet VibeCodé</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Bonnes_pratiques_:_Mettre_en_place_un_projet_VibeCod%C3%A9&amp;diff=97"/>
		<updated>2026-03-07T22:35:31Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Respect de la charte graphique : ===&lt;br /&gt;
Créer un fichier de charte graphique afin de le fournir à l'gent codant du front pour garder une cohérence sur tout le projet. Il faut y préciser où se trouve le fichier de thème dans lequesl on retrouve toutes les couleurs utilisées sur l'application et autre paramètres concernant le design.&lt;br /&gt;
&lt;br /&gt;
==== Maquetter l'interface : ====&lt;br /&gt;
Grâce à des IA comme Stitch de Google, on peut rapidement grâce à un prompt, généré un beau visuel et l'adapter afin d'avoir une maquette sur laquelle partir pour le développement.&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Bonnes_pratiques_:_Mettre_en_place_un_projet_VibeCod%C3%A9&amp;diff=96</id>
		<title>Bonnes pratiques : Mettre en place un projet VibeCodé</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Bonnes_pratiques_:_Mettre_en_place_un_projet_VibeCod%C3%A9&amp;diff=96"/>
		<updated>2026-03-07T22:13:31Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « ==== Maquetter l'interface : ==== Grâce à des IA comme Stitch de Google, on peut rapidement grâce à un prompt, généré un beau visuel et l'adapter afin d'avoir une maquette sur laquelle partir pour le développement. »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Maquetter l'interface : ====&lt;br /&gt;
Grâce à des IA comme Stitch de Google, on peut rapidement grâce à un prompt, généré un beau visuel et l'adapter afin d'avoir une maquette sur laquelle partir pour le développement.&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=MediaWiki:Sidebar&amp;diff=95</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=MediaWiki:Sidebar&amp;diff=95"/>
		<updated>2026-03-07T22:04:48Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* Catégories&lt;br /&gt;
** :Catégorie:AI|AI&lt;br /&gt;
** :Catégorie:Apache|Apache&lt;br /&gt;
** :Catégorie:Bootstrap|Bootstrap&lt;br /&gt;
** :Catégorie:Centos|Centos&lt;br /&gt;
** :Catégorie:Docker|Docker&lt;br /&gt;
** :Catégorie:Drupal|Drupal&lt;br /&gt;
** :Catégorie:Git|Git&lt;br /&gt;
** :Catégorie:Github|Github&lt;br /&gt;
** :Catégorie:Laravel|Laravel&lt;br /&gt;
** :Catégorie:Linux|Linux&lt;br /&gt;
** :Catégorie:Mediawiki|Mediawiki&lt;br /&gt;
** :Catégorie:MQL5|MQL5&lt;br /&gt;
** :Catégorie:MySQL|MySQL&lt;br /&gt;
** :Catégorie:N8N|N8N&lt;br /&gt;
** :Catégorie:NextJs|NextJS&lt;br /&gt;
** :Catégorie:Nodejs|Nodejs&lt;br /&gt;
** :Catégorie:Plesk|Plesk&lt;br /&gt;
** :Catégorie:React|React&lt;br /&gt;
** :Catégorie:Rsync|Rsync&lt;br /&gt;
** :Catégorie:Symfony|Symfony&lt;br /&gt;
** :Catégorie:Twig|Twig&lt;br /&gt;
** :Catégorie:Vue.js|Vue.js&lt;br /&gt;
** :Catégorie:Wordpress|Wordpress&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Branchement_docker_%C3%A0_un_nom_de_domaine_Plesk,_debug&amp;diff=94</id>
		<title>Branchement docker à un nom de domaine Plesk, debug</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Branchement_docker_%C3%A0_un_nom_de_domaine_Plesk,_debug&amp;diff=94"/>
		<updated>2026-02-07T15:50:32Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il faut aller dans les directives Apaches du nom de domaine et rajouter :&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
# Activer le mode proxy&lt;br /&gt;
ProxyRequests Off&lt;br /&gt;
ProxyPreserveHost On&lt;br /&gt;
&lt;br /&gt;
# WebSocket : upgrade des connexions ws/wss&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteCond %{HTTP:Upgrade} websocket [NC]&lt;br /&gt;
RewriteCond %{HTTP:Connection} upgrade [NC]&lt;br /&gt;
RewriteRule ^/(.*) ws://127.0.0.1:8010/$1 [P,L]&lt;br /&gt;
&lt;br /&gt;
# Configuration pour les requêtes HTTP normales&lt;br /&gt;
&amp;lt;Location /&amp;gt;&lt;br /&gt;
    ProxyPass http://127.0.0.1:8010/&lt;br /&gt;
    ProxyPassReverse http://127.0.0.1:8010/&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[index.php?title=Catégorie:Plesk]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=MediaWiki:Sidebar&amp;diff=93</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=MediaWiki:Sidebar&amp;diff=93"/>
		<updated>2025-12-07T14:32:02Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* Catégories&lt;br /&gt;
** :Catégorie:Apache|Apache&lt;br /&gt;
** :Catégorie:Bootstrap|Bootstrap&lt;br /&gt;
** :Catégorie:Centos|Centos&lt;br /&gt;
** :Catégorie:Docker|Docker&lt;br /&gt;
** :Catégorie:Drupal|Drupal&lt;br /&gt;
** :Catégorie:Git|Git&lt;br /&gt;
** :Catégorie:Github|Github&lt;br /&gt;
** :Catégorie:Laravel|Laravel&lt;br /&gt;
** :Catégorie:Linux|Linux&lt;br /&gt;
** :Catégorie:Mediawiki|Mediawiki&lt;br /&gt;
** :Catégorie:MQL5|MQL5&lt;br /&gt;
** :Catégorie:MySQL|MySQL&lt;br /&gt;
** :Catégorie:N8N|N8N&lt;br /&gt;
** :Catégorie:NextJs|NextJS&lt;br /&gt;
** :Catégorie:Nodejs|Nodejs&lt;br /&gt;
** :Catégorie:Plesk|Plesk&lt;br /&gt;
** :Catégorie:React|React&lt;br /&gt;
** :Catégorie:Rsync|Rsync&lt;br /&gt;
** :Catégorie:Symfony|Symfony&lt;br /&gt;
** :Catégorie:Twig|Twig&lt;br /&gt;
** :Catégorie:Vue.js|Vue.js&lt;br /&gt;
** :Catégorie:Wordpress|Wordpress&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=N8N_You_have_a_connection_issue_or_the_server_is_down._ou_probl%C3%A8me_docker_et_connection_websocket_avec_PLESK&amp;diff=92</id>
		<title>N8N You have a connection issue or the server is down. ou problème docker et connection websocket avec PLESK</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=N8N_You_have_a_connection_issue_or_the_server_is_down._ou_probl%C3%A8me_docker_et_connection_websocket_avec_PLESK&amp;diff=92"/>
		<updated>2025-12-07T14:28:57Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il faut prendre en considération les connection websocket dans la config Apache : &amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ProxyPreserveHost On&lt;br /&gt;
ProxyRequests Off&lt;br /&gt;
&lt;br /&gt;
# Support WebSocket&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteCond %{HTTP:Upgrade} =websocket [NC]&lt;br /&gt;
RewriteRule /(.*) ws://127.0.0.1:&amp;lt;port&amp;gt;/$1 [P,L]&lt;br /&gt;
RewriteCond %{HTTP:Upgrade} !=websocket [NC]&lt;br /&gt;
RewriteRule /(.*) http://127.0.0.1:&amp;lt;port&amp;gt;/$1 [P,L]&lt;br /&gt;
&lt;br /&gt;
ProxyPass / http://127.0.0.1:&amp;lt;port&amp;gt;/&lt;br /&gt;
ProxyPassReverse / http://127.0.0.1:&amp;lt;port&amp;gt;/&lt;br /&gt;
&lt;br /&gt;
# Headers pour WebSocket&lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
RequestHeader set X-Forwarded-Port &amp;quot;443&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Plesk]]&lt;br /&gt;
[[Category:N8N]]&lt;br /&gt;
[[Category:Apache]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Docker]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=N8N_You_have_a_connection_issue_or_the_server_is_down._ou_probl%C3%A8me_docker_et_connection_websocket_avec_PLESK&amp;diff=91</id>
		<title>N8N You have a connection issue or the server is down. ou problème docker et connection websocket avec PLESK</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=N8N_You_have_a_connection_issue_or_the_server_is_down._ou_probl%C3%A8me_docker_et_connection_websocket_avec_PLESK&amp;diff=91"/>
		<updated>2025-12-07T14:28:28Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il faut prendre en considération les connection websocket dans la config Apache : &amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ProxyPreserveHost On&lt;br /&gt;
ProxyRequests Off&lt;br /&gt;
&lt;br /&gt;
# Support WebSocket&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteCond %{HTTP:Upgrade} =websocket [NC]&lt;br /&gt;
RewriteRule /(.*) ws://127.0.0.1:&amp;lt;port&amp;gt;/$1 [P,L]&lt;br /&gt;
RewriteCond %{HTTP:Upgrade} !=websocket [NC]&lt;br /&gt;
RewriteRule /(.*) http://127.0.0.1:&amp;lt;port&amp;gt;/$1 [P,L]&lt;br /&gt;
&lt;br /&gt;
ProxyPass / http://127.0.0.1:&amp;lt;port&amp;gt;/&lt;br /&gt;
ProxyPassReverse / http://127.0.0.1:&amp;lt;port&amp;gt;/&lt;br /&gt;
&lt;br /&gt;
# Headers pour WebSocket&lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
RequestHeader set X-Forwarded-Port &amp;quot;443&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Plesk]]&lt;br /&gt;
[[Category:N8N]]&lt;br /&gt;
[[Category:Apache]]&lt;br /&gt;
[[Category:Linux]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=N8N_You_have_a_connection_issue_or_the_server_is_down._ou_probl%C3%A8me_docker_et_connection_websocket_avec_PLESK&amp;diff=90</id>
		<title>N8N You have a connection issue or the server is down. ou problème docker et connection websocket avec PLESK</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=N8N_You_have_a_connection_issue_or_the_server_is_down._ou_probl%C3%A8me_docker_et_connection_websocket_avec_PLESK&amp;diff=90"/>
		<updated>2025-12-07T14:24:03Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « Il faut prendre en considération les connection websocket dans la config Apache : &amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt; ProxyPreserveHost On ProxyRequests Off  # Support WebSocket RewriteEngine On RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule /(.*) ws://127.0.0.1:&amp;lt;port&amp;gt;/$1 [P,L] RewriteCond %{HTTP:Upgrade} !=websocket [NC] RewriteRule /(.*) http://127.0.0.1:&amp;lt;port&amp;gt;/$1 [P,L]  ProxyPass / http://127.0.0.1:&amp;lt;port&amp;gt;/ ProxyPassReverse / http://127.0.0.1:&amp;lt;port&amp;gt;/  # Heade... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il faut prendre en considération les connection websocket dans la config Apache : &amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ProxyPreserveHost On&lt;br /&gt;
ProxyRequests Off&lt;br /&gt;
&lt;br /&gt;
# Support WebSocket&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteCond %{HTTP:Upgrade} =websocket [NC]&lt;br /&gt;
RewriteRule /(.*) ws://127.0.0.1:&amp;lt;port&amp;gt;/$1 [P,L]&lt;br /&gt;
RewriteCond %{HTTP:Upgrade} !=websocket [NC]&lt;br /&gt;
RewriteRule /(.*) http://127.0.0.1:&amp;lt;port&amp;gt;/$1 [P,L]&lt;br /&gt;
&lt;br /&gt;
ProxyPass / http://127.0.0.1:&amp;lt;port&amp;gt;/&lt;br /&gt;
ProxyPassReverse / http://127.0.0.1:&amp;lt;port&amp;gt;/&lt;br /&gt;
&lt;br /&gt;
# Headers pour WebSocket&lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
RequestHeader set X-Forwarded-Port &amp;quot;443&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Debug_:_impossible_de_g%C3%A9n%C3%A9rer_certificat_SSL_Let%27sEncrypt&amp;diff=89</id>
		<title>Debug : impossible de générer certificat SSL Let'sEncrypt</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Debug_:_impossible_de_g%C3%A9n%C3%A9rer_certificat_SSL_Let%27sEncrypt&amp;diff=89"/>
		<updated>2025-11-10T20:45:26Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « Si lorsqu'on essaye de créer un certificat SSL sur Plesk pour un domaine on tombe sur l'erreur :  &amp;lt;code/&amp;gt; Could not issue an SSL/TLS certificate for pgadmin.weltaflow.weltaare-tech.com Details Could not issue a Let's Encrypt SSL/TLS certificate for pgadmin.weltaflow.weltaare-tech.com.  The authorization token is not available at http://[Votre domaine]/.well-known/acme-challenge/BFjRGfmgj25eSrQ0n1yXtTKrFgcSTAor4ygd8HYU-MA. To resolve the issue, make sure that the... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Si lorsqu'on essaye de créer un certificat SSL sur Plesk pour un domaine on tombe sur l'erreur : &lt;br /&gt;
&amp;lt;code/&amp;gt;&lt;br /&gt;
Could not issue an SSL/TLS certificate for pgadmin.weltaflow.weltaare-tech.com&lt;br /&gt;
Details&lt;br /&gt;
Could not issue a Let's Encrypt SSL/TLS certificate for pgadmin.weltaflow.weltaare-tech.com.&lt;br /&gt;
&lt;br /&gt;
The authorization token is not available at http://[Votre domaine]/.well-known/acme-challenge/BFjRGfmgj25eSrQ0n1yXtTKrFgcSTAor4ygd8HYU-MA.&lt;br /&gt;
To resolve the issue, make sure that the token file can be downloaded via the above URL.&lt;br /&gt;
See the related Knowledge Base article for details.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cela signifie que Let's encrypt n'arrive pas à accéder au token de vérification à à cette adresse. Cela peut être dû au fait que qu'une redirection est faite par le proxy par exemple si vous avez une configuration docker est en place. Il faudra tout simplement la retirer temporairement pour la génération du token et la remettre.&lt;br /&gt;
&lt;br /&gt;
[[Category:Plesk]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Plesk_:_The_%22node%22(%22npm%22)_command_exists_in_these_versions&amp;diff=88</id>
		<title>Plesk : The &quot;node&quot;(&quot;npm&quot;) command exists in these versions</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Plesk_:_The_%22node%22(%22npm%22)_command_exists_in_these_versions&amp;diff=88"/>
		<updated>2025-11-07T01:21:18Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Quand on rencontre l'erreur dans le titre,&lt;br /&gt;
[[Fichier:Gsdfgsdfg.png|centré|sans_cadre|615x615px]]&lt;br /&gt;
on se connecte en ssh en tant que l'utilisateur souhaité puis entrer :&lt;br /&gt;
&lt;br /&gt;
nodenv local &amp;lt;version&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Plesk]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Plesk_:_The_%22node%22(%22npm%22)_command_exists_in_these_versions&amp;diff=87</id>
		<title>Plesk : The &quot;node&quot;(&quot;npm&quot;) command exists in these versions</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Plesk_:_The_%22node%22(%22npm%22)_command_exists_in_these_versions&amp;diff=87"/>
		<updated>2025-11-07T01:20:55Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Quand on rencontre l'erreur dans le titre,&lt;br /&gt;
[[Fichier:Gsdfgsdfg.png|centré|sans_cadre|615x615px]]&lt;br /&gt;
on se connecte en ssh en tant que l'utilisateur souhaité puis entrer :&lt;br /&gt;
&lt;br /&gt;
nodenv local &amp;lt;version&amp;gt;&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Fichier:Gsdfgsdfg.png&amp;diff=86</id>
		<title>Fichier:Gsdfgsdfg.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Fichier:Gsdfgsdfg.png&amp;diff=86"/>
		<updated>2025-11-07T01:20:10Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;gsdfgsdfg&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Plesk_:_The_%22node%22(%22npm%22)_command_exists_in_these_versions&amp;diff=85</id>
		<title>Plesk : The &quot;node&quot;(&quot;npm&quot;) command exists in these versions</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Plesk_:_The_%22node%22(%22npm%22)_command_exists_in_these_versions&amp;diff=85"/>
		<updated>2025-11-07T01:19:18Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « Quand on rencontre l'erreur dans le titre, on se connecte en ssh en tant que l'utilisateur souhaité puis entrer :  nodenv local &amp;lt;version&amp;gt;  850x850px »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Quand on rencontre l'erreur dans le titre, on se connecte en ssh en tant que l'utilisateur souhaité puis entrer :&lt;br /&gt;
&lt;br /&gt;
nodenv local &amp;lt;version&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Node not working.png|centré|sans_cadre|850x850px]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Fichier:Node_not_working.png&amp;diff=84</id>
		<title>Fichier:Node not working.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Fichier:Node_not_working.png&amp;diff=84"/>
		<updated>2025-11-07T01:17:49Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;node not working&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_en_place_une_CI/CD&amp;diff=83</id>
		<title>Mettre en place une CI/CD</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_en_place_une_CI/CD&amp;diff=83"/>
		<updated>2025-10-22T20:23:14Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Prérequis ==&lt;br /&gt;
Avant de suivre ce Tuto, en particulier pour la partie déploiement, s'assurer d'avoir cloner le repo sur le serveur de déploiement.&lt;br /&gt;
&lt;br /&gt;
== Le CI/CD en développement ==&lt;br /&gt;
Le CI/CD, ou Intégration Continue/Livraison Continue, est une pratique logicielle qui vise à automatiser le processus de développement et de déploiement logiciel. Il s'agit d'une approche DevOps qui permet d'améliorer la qualité, la rapidité et la fiabilité du développement logiciel.&lt;br /&gt;
&lt;br /&gt;
== Les étapes ==&lt;br /&gt;
&lt;br /&gt;
# Intégration Continue (CI) :&lt;br /&gt;
#* La CI consiste à intégrer fréquemment les modifications de code dans un référentiel partagé.&lt;br /&gt;
#* Les développeurs fusionnent régulièrement leur code dans une branche commune, déclenchant des processus automatisés qui vérifient la qualité du code.&lt;br /&gt;
# Tests Automatisés :&lt;br /&gt;
#* Les systèmes CI exécutent des tests automatisés pour s'assurer que les nouvelles modifications n'ont pas introduit de régressions.&lt;br /&gt;
#* Les tests peuvent inclure des tests unitaires, des tests d'intégration et d'autres formes de tests automatisés.&lt;br /&gt;
# Déploiement Continu (CD) :&lt;br /&gt;
#* L'Implémentation Continue (ou Déploiement Continu) étend la CI en automatisant la livraison du logiciel.&lt;br /&gt;
#* Le déploiement continu implique la mise en œuvre automatisée des modifications validées dans l'environnement de production.&lt;br /&gt;
&lt;br /&gt;
== Créer un fichier de workflow ==&lt;br /&gt;
Un fichier de workflow est le script qui sera exécuté par Github lors d'un évènement définis commpe un push sur la branch main ou la complétion d'un autre workflow.&lt;br /&gt;
&lt;br /&gt;
C'est généralement un ou plusieurs fichies qui doivent être placés dans le dossier '''&amp;lt;code&amp;gt;.github/workflows/&amp;lt;/code&amp;gt;''' (par exemple &amp;lt;code&amp;gt;'''.github/workflows/ci.yam'''l&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Exemple commenté d'un workflow d'intégration et de test continue Laravel ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# Nom du workflow&lt;br /&gt;
name: Laravel CI&lt;br /&gt;
&lt;br /&gt;
# Déclencheurs pour le workflow&lt;br /&gt;
on:&lt;br /&gt;
  push:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]   # Déclencher lorsqu'un push est effectué sur la branche principale&lt;br /&gt;
  pull_request:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]   # Déclencher lorsqu'une pull request est ouverte sur la branche principale&lt;br /&gt;
&lt;br /&gt;
# Définition des jobs&lt;br /&gt;
jobs:&lt;br /&gt;
  laravel-tests:&lt;br /&gt;
    runs-on: ubuntu-latest   # Utiliser l'image Ubuntu la plus récente comme environnement d'exécution&lt;br /&gt;
&lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: shivammathur/setup-php@v2   # Utiliser l'action pour configurer PHP&lt;br /&gt;
        with:&lt;br /&gt;
          php-version: '8.1'   # Spécifier la version de PHP à utiliser&lt;br /&gt;
      - uses: actions/checkout@v2   # Utiliser l'action pour effectuer un checkout du code&lt;br /&gt;
&lt;br /&gt;
      - name: Copy .env   # Étape pour copier le fichier .env s'il n'existe pas&lt;br /&gt;
        run: php -r &amp;quot;file_exists('.env') || copy('.env.example', '.env');&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      - name: Install Dependencies   # Étape pour installer les dépendances Composer&lt;br /&gt;
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist&lt;br /&gt;
&lt;br /&gt;
      - name: Generate key   # Étape pour générer la clé d'application Laravel&lt;br /&gt;
        run: php artisan key:generate&lt;br /&gt;
&lt;br /&gt;
      - name: Directory Permissions   # Étape pour définir les permissions sur les répertoires&lt;br /&gt;
        run: chmod -R 777 storage bootstrap/cache&lt;br /&gt;
&lt;br /&gt;
      - name: Create Database   # Étape pour créer une base de données SQLite&lt;br /&gt;
        run: |&lt;br /&gt;
          mkdir -p database&lt;br /&gt;
          touch database/database.sqlite&lt;br /&gt;
&lt;br /&gt;
      - name: Execute tests (Unit and Feature tests) via PHPUnit   # Étape pour exécuter les tests PHPUnit&lt;br /&gt;
        env:&lt;br /&gt;
          DB_CONNECTION: sqlite&lt;br /&gt;
          DB_DATABASE: database/database.sqlite   # Configurer la base de données pour les tests&lt;br /&gt;
        run: vendor/bin/phpunit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;En incluant ce fichier dans notre système de fichiers, lors du push Github va effectuer les installations nécessaires pour lancer une version de test du projet et également exécuter tous les test unitaires et de features compris dans le projet.&lt;br /&gt;
&lt;br /&gt;
Le déploiement demande un peu plus travail :&lt;br /&gt;
&lt;br /&gt;
=== Exemple commenté d'un workflow de déploiement continue Laravel ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Nom du workflow&lt;br /&gt;
name: Laravel CD&lt;br /&gt;
&lt;br /&gt;
# Déclencheur pour le workflow : déclenche lorsqu'une exécution du workflow &amp;quot;Laravel CI&amp;quot; est terminée&lt;br /&gt;
on:&lt;br /&gt;
  workflow_run:&lt;br /&gt;
    workflows: [&amp;quot;Laravel CI&amp;quot;]&lt;br /&gt;
    types:&lt;br /&gt;
      - completed&lt;br /&gt;
&lt;br /&gt;
# Définition des jobs&lt;br /&gt;
jobs:&lt;br /&gt;
  deploy:&lt;br /&gt;
    runs-on: ubuntu-latest   # Utiliser l'image Ubuntu la plus récente comme environnement d'exécution&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      name: 'MyPlesk'   # Nom de l'environnement de déploiement&lt;br /&gt;
&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Deploy to Server   # Étape pour déployer sur le serveur&lt;br /&gt;
        uses: appleboy/ssh-action@master   # Utiliser l'action SSH pour effectuer le déploiement&lt;br /&gt;
        with:&lt;br /&gt;
          host: ${{ secrets.SERVER_HOST }}   # Adresse IP ou nom d'hôte du serveur&lt;br /&gt;
          username: ${{ secrets.SERVER_USERNAME }}   # Nom d'utilisateur pour la connexion SSH&lt;br /&gt;
          key: ${{ secrets.SSH_PRIVATE_KEY }}   # Clé privée SSH pour l'authentification&lt;br /&gt;
          script: |&lt;br /&gt;
            cd /var/www/vhosts/abdoulaye-diallo.com/api.abdoulaye-diallo.com/Cv_back/   # Se déplacer vers le répertoire du projet&lt;br /&gt;
            git pull origin main   # Mettre à jour le code depuis la branche principale&lt;br /&gt;
            php artisan migrate   # Exécuter les migrations de base de données&lt;br /&gt;
            composer update   # Mettre à jour les dépendances Composer (si nécessaire)&lt;br /&gt;
            composer install   # Installer les dépendances Composer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;A savoir, sur Plesk il arrive souvent que la commande php n'est pas trouvée, il faut alors aller sur le terminal du domaine, lancer la commande &amp;lt;code&amp;gt;which php&amp;lt;/code&amp;gt;  pour avoir le chemin d'accès au script php, puis une fois le chemin otenu, le spécifier dans le fichier de déploiment comme par exemple : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;php artisan migrate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
devient :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/var/www/vhosts/quizzical-bassi.91-212-26-79.plesk.page/.phpenv/shims/php artisan migrate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple de workflow CI/CD pour un projet React en un seul fichier : ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
name: React CICD&lt;br /&gt;
&lt;br /&gt;
on:&lt;br /&gt;
  push:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]&lt;br /&gt;
  pull_request:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  build:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        node-version: [18.x]&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Checkout Repository&lt;br /&gt;
        uses: actions/checkout@v2&lt;br /&gt;
      - name: Use Node.js ${{ matrix.node-version }}&lt;br /&gt;
        uses: actions/setup-node@v3&lt;br /&gt;
        with:&lt;br /&gt;
          node-version: ${{ matrix.node-version }}&lt;br /&gt;
          cache: 'npm'&lt;br /&gt;
      - name: Install Dependencies&lt;br /&gt;
        run: npm ci&lt;br /&gt;
      - name: Build Project&lt;br /&gt;
        run: npm run build --if-present&lt;br /&gt;
      - name: Run Tests&lt;br /&gt;
        run: npm test --if-present&lt;br /&gt;
&lt;br /&gt;
  deploy:&lt;br /&gt;
    needs: build&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    environment:&lt;br /&gt;
      name: &amp;quot;MyPlesk&amp;quot;&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Checkout Repository&lt;br /&gt;
        uses: actions/checkout@v2&lt;br /&gt;
      - name: Deploy to Server&lt;br /&gt;
        uses: appleboy/ssh-action@master&lt;br /&gt;
        with:&lt;br /&gt;
          host: ${{ secrets.SERVER_HOST }}&lt;br /&gt;
          username: ${{ secrets.SERVER_USERNAME }}&lt;br /&gt;
          key: ${{ secrets.SSH_PRIVATE_KEY }}&lt;br /&gt;
          script: |&lt;br /&gt;
            cd /var/www/vhosts/abdoulaye-diallo.com/httpdocs/Front/&lt;br /&gt;
            git pull origin main&lt;br /&gt;
            npm ci --production&lt;br /&gt;
            npm run build&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;⚠️⚠️⚠️: Les variables d'environnements Github ou Gitlab ne sont pas chargés dans le script lancé sur le serveur de production. Il faut donc les écrire en dur.&lt;br /&gt;
&lt;br /&gt;
== Créer un environnement et des secrets sur Github ==&lt;br /&gt;
Comme on peut le voir dans ce code, on doit se connecter en SSH au serveur de production afin de déployer les MAJ. Pour cela et pour des raisons de sécurités, on stock les informations dans les secrets de GitHub (voir https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) . Ici en l'occurrence nous avons créés des secrets dans un environnement nommé MyPlesk sur GitHub (MAJ : les environnements Github semblent avoir disparus maintenant) :&lt;br /&gt;
[[Fichier:Github Secrets.png|centré|sans_cadre|1071x1071px]]&lt;br /&gt;
=== Création des clés ssh ===&lt;br /&gt;
[[Fichier:Plesk ssh keys.png|vignette]]&lt;br /&gt;
La connexion au serveur distant se fait via une clé ssh (d'où le secrets.SSH_PRIVATE_KEY à la ligne 25), pour cela nous allons ouvrir un terminal en local par exemple et lancer la commande de génération de clé ssh : &amp;lt;code&amp;gt;ssh-keygen -t rsa -b 4096 -C &amp;quot;monmail@email.com&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Il faudra ensuite copier la clé privée dans le secret de Github ( secrets.SSH_PRIVATE_KEY) et ajouter la clé publique parmis les clés SSH autorisés du serveur distant (sur Plesk, aller dans l'abonnement concerné et cliquer sur SSH KEYS).&lt;br /&gt;
&lt;br /&gt;
Il faut également renseigner le nom de l'utilisateur qui a accès au serveur.&lt;br /&gt;
&lt;br /&gt;
[[index.php?title=Catégorie:Github]]  &lt;br /&gt;
[[index.php?title=Catégorie:Git]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=R%C3%A9solutions_d%27erreurs_CORS&amp;diff=82</id>
		<title>Résolutions d'erreurs CORS</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=R%C3%A9solutions_d%27erreurs_CORS&amp;diff=82"/>
		<updated>2025-10-19T18:20:21Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Histoire 1 : React.js (1 journée de 9h passée à trouver la solution 😒) ===&lt;br /&gt;
Dans des requêtes faites à une API via axios, je tombait pour certaines requêtes (et seulement certaines) sur des blocages CORS. Ce qui était encore plus étrange c'est que tout fonctionnait parfaitement quand mon api était hébergée en local, les problèmes sont apparus quand je l'ai hébergée en ligne.&lt;br /&gt;
&lt;br /&gt;
Bref, après une journée à tester mille et une solutions dont l'ajout des headers Acess-Control[....] dans la config d'Apache (.htaccess et config.d) et côté client en rajoutant des &amp;quot;Access-Control-Allow-Origin&amp;quot;: &amp;quot;*&amp;quot; à l'en-tête de mes requêtes; je parviens à faire passer mes requêtes en '''retirant un slash ( / ) qui trainait à la fin de l'url de ma requête''' côté client react.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Vérifier le sanctum&lt;br /&gt;
&lt;br /&gt;
Si votre application front-end est hébergée sur un domaine différent, assurez-vous de configurer les paramètres CORS dans le fichier &amp;lt;code&amp;gt;config/sanctum.php&amp;lt;/code&amp;gt;. Ajoutez votre domaine dans la section &amp;lt;code&amp;gt;stateful&amp;lt;/code&amp;gt; :&lt;br /&gt;
 'stateful' =&amp;gt; explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(&lt;br /&gt;
         '%s%s',&lt;br /&gt;
         'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,&amp;lt;nowiki&amp;gt;https://abdoulaye-diallo.com'&amp;lt;/nowiki&amp;gt;,&lt;br /&gt;
         Sanctum::currentApplicationUrlWithPort()&lt;br /&gt;
     ))),&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Vérifier très bien la syntaxe de vos URL&lt;br /&gt;
&lt;br /&gt;
Encore plusieurs jours de perdus car incohérence dans les URL. Revérifier à plusieurs reprises que le front fait bien appel à l'api correctement. &lt;br /&gt;
&lt;br /&gt;
J'avais une erreur car mon front faisait appel à  'https://api.vtcprivetoure.fr/api&amp;lt;nowiki/&amp;gt;' alors que je devais appeler 'https://api.vtcprivetoure.fr/api&amp;lt;nowiki/&amp;gt;'. ici c'est le sous-domaine api qui m'a induit en erreur.&lt;br /&gt;
&lt;br /&gt;
[[index.php?title=Catégorie:React]]&lt;br /&gt;
&lt;br /&gt;
4. Sur plesk lorsqu'on lance l'application depuis un docker avec un front discossié du back j'ai dû gérer les entêtes CORS depuis les configurations Apache directement. Pour cela j'ai du désactiver le CORS sur laravel, pour cela il suffit de commenter ou retirer la ligne concernant le middleware HandleCors dans app/http/kernel.php. Puis aller sur le domaine connecté au conteneur du back-end, dans les paramètres apaches et nginx =&amp;gt; Additional Apache directives, mettre pour le http et le https, un code similaire : &amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Activer le mode proxy&lt;br /&gt;
ProxyRequests Off&lt;br /&gt;
ProxyPreserveHost On&lt;br /&gt;
&lt;br /&gt;
# Activer les en-têtes CORS&lt;br /&gt;
Header always set Access-Control-Allow-Origin &amp;quot;https://mondomainefront-end.example&amp;quot;&lt;br /&gt;
Header always set Access-Control-Allow-Methods &amp;quot;GET, POST, PUT, DELETE, OPTIONS&amp;quot;&lt;br /&gt;
Header always set Access-Control-Allow-Headers &amp;quot;Content-Type, Authorization, X-Requested-With&amp;quot;&lt;br /&gt;
Header always set Access-Control-Expose-Headers &amp;quot;Authorization&amp;quot;&lt;br /&gt;
Header always set Access-Control-Allow-Credentials &amp;quot;true&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Gérer les requêtes OPTIONS (preflight)&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteCond %{REQUEST_METHOD} OPTIONS&lt;br /&gt;
RewriteRule ^(.*)$ $1 [R=200,L]&lt;br /&gt;
&lt;br /&gt;
# Configuration pour les requêtes HTTP normales&lt;br /&gt;
&amp;lt;Location /&amp;gt;&lt;br /&gt;
	ProxyPass http://127.0.0.1:8000/&lt;br /&gt;
	ProxyPassReverse http://127.0.0.1:8000/&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
⚠️Attention à bien renseigner le domaine front-end autorisé&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=R%C3%A9solutions_d%27erreurs_CORS&amp;diff=81</id>
		<title>Résolutions d'erreurs CORS</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=R%C3%A9solutions_d%27erreurs_CORS&amp;diff=81"/>
		<updated>2025-10-19T18:19:45Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Histoire 1 : React.js (1 journée de 9h passée à trouver la solution 😒) ===&lt;br /&gt;
Dans des requêtes faites à une API via axios, je tombait pour certaines requêtes (et seulement certaines) sur des blocages CORS. Ce qui était encore plus étrange c'est que tout fonctionnait parfaitement quand mon api était hébergée en local, les problèmes sont apparus quand je l'ai hébergée en ligne.&lt;br /&gt;
&lt;br /&gt;
Bref, après une journée à tester mille et une solutions dont l'ajout des headers Acess-Control[....] dans la config d'Apache (.htaccess et config.d) et côté client en rajoutant des &amp;quot;Access-Control-Allow-Origin&amp;quot;: &amp;quot;*&amp;quot; à l'en-tête de mes requêtes; je parviens à faire passer mes requêtes en '''retirant un slash ( / ) qui trainait à la fin de l'url de ma requête''' côté client react.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Vérifier le sanctum&lt;br /&gt;
&lt;br /&gt;
Si votre application front-end est hébergée sur un domaine différent, assurez-vous de configurer les paramètres CORS dans le fichier &amp;lt;code&amp;gt;config/sanctum.php&amp;lt;/code&amp;gt;. Ajoutez votre domaine dans la section &amp;lt;code&amp;gt;stateful&amp;lt;/code&amp;gt; :&lt;br /&gt;
 'stateful' =&amp;gt; explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(&lt;br /&gt;
         '%s%s',&lt;br /&gt;
         'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,&amp;lt;nowiki&amp;gt;https://abdoulaye-diallo.com'&amp;lt;/nowiki&amp;gt;,&lt;br /&gt;
         Sanctum::currentApplicationUrlWithPort()&lt;br /&gt;
     ))),&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Vérifier très bien la syntaxe de vos URL&lt;br /&gt;
&lt;br /&gt;
Encore plusieurs jours de perdus car incohérence dans les URL. Revérifier à plusieurs reprises que le front fait bien appel à l'api correctement. &lt;br /&gt;
&lt;br /&gt;
J'avais une erreur car mon front faisait appel à  'https://api.vtcprivetoure.fr/api&amp;lt;nowiki/&amp;gt;' alors que je devais appeler 'https://api.vtcprivetoure.fr/api&amp;lt;nowiki/&amp;gt;'. ici c'est le sous-domaine api qui m'a induit en erreur.&lt;br /&gt;
&lt;br /&gt;
[[index.php?title=Catégorie:React]]&lt;br /&gt;
&lt;br /&gt;
4. Sur plesk lorsqu'on lance l'application depuis un docker avec un front discossié du back j'ai dû gérer les entêtes CORS depuis les configurations Apache directement. Pour cela j'ai du désactiver le CORS sur laravel, pour cela il suffit de commenter ou retirer la ligne concernant le middleware HandleCors dans app/http/kernel.php. Puis aller sur le domaine connecté au conteneur du back-end, dans les paramètres apaches et nginx =&amp;gt; Additional Apache directives, mettre pour le http et le https, un code similaire : &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Attention à bien renseigner le domaine front-end autorisé&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=R%C3%A9solutions_d%27erreurs_CORS&amp;diff=80</id>
		<title>Résolutions d'erreurs CORS</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=R%C3%A9solutions_d%27erreurs_CORS&amp;diff=80"/>
		<updated>2025-10-19T18:19:11Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Histoire 1 : React.js (1 journée de 9h passée à trouver la solution 😒) ===&lt;br /&gt;
Dans des requêtes faites à une API via axios, je tombait pour certaines requêtes (et seulement certaines) sur des blocages CORS. Ce qui était encore plus étrange c'est que tout fonctionnait parfaitement quand mon api était hébergée en local, les problèmes sont apparus quand je l'ai hébergée en ligne.&lt;br /&gt;
&lt;br /&gt;
Bref, après une journée à tester mille et une solutions dont l'ajout des headers Acess-Control[....] dans la config d'Apache (.htaccess et config.d) et côté client en rajoutant des &amp;quot;Access-Control-Allow-Origin&amp;quot;: &amp;quot;*&amp;quot; à l'en-tête de mes requêtes; je parviens à faire passer mes requêtes en '''retirant un slash ( / ) qui trainait à la fin de l'url de ma requête''' côté client react.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Vérifier le sanctum&lt;br /&gt;
&lt;br /&gt;
Si votre application front-end est hébergée sur un domaine différent, assurez-vous de configurer les paramètres CORS dans le fichier &amp;lt;code&amp;gt;config/sanctum.php&amp;lt;/code&amp;gt;. Ajoutez votre domaine dans la section &amp;lt;code&amp;gt;stateful&amp;lt;/code&amp;gt; :&lt;br /&gt;
 'stateful' =&amp;gt; explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(&lt;br /&gt;
         '%s%s',&lt;br /&gt;
         'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,&amp;lt;nowiki&amp;gt;https://abdoulaye-diallo.com'&amp;lt;/nowiki&amp;gt;,&lt;br /&gt;
         Sanctum::currentApplicationUrlWithPort()&lt;br /&gt;
     ))),&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Vérifier très bien la syntaxe de vos URL&lt;br /&gt;
&lt;br /&gt;
Encore plusieurs jours de perdus car incohérence dans les URL. Revérifier à plusieurs reprises que le front fait bien appel à l'api correctement. &lt;br /&gt;
&lt;br /&gt;
J'avais une erreur car mon front faisait appel à  'https://api.vtcprivetoure.fr/api&amp;lt;nowiki/&amp;gt;' alors que je devais appeler 'https://api.vtcprivetoure.fr/api&amp;lt;nowiki/&amp;gt;'. ici c'est le sous-domaine api qui m'a induit en erreur.&lt;br /&gt;
&lt;br /&gt;
[[index.php?title=Catégorie:React]]&lt;br /&gt;
&lt;br /&gt;
4. Sur plesk lorsqu'on lance l'application depuis un docker avec un front discossié du back j'ai dû gérer les entêtes CORS depuis les configurations Apache directement. Pour cela j'ai du désactiver le CORS sur laravel, pour cela il suffit de commenter ou retirer la ligne concernant le middleware HandleCors dans app/http/kernel.php. Puis aller sur le domaine connecté au conteneur du back-end, dans les paramètres apaches et nginx =&amp;gt; Additional Apache directives, mettre pour le http et le https, un code similaire : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
# Activer le mode proxy&lt;br /&gt;
ProxyRequests Off&lt;br /&gt;
ProxyPreserveHost On&lt;br /&gt;
&lt;br /&gt;
# Activer les en-têtes CORS&lt;br /&gt;
Header always set Access-Control-Allow-Origin &amp;quot;https://mondomainefront-end.example&amp;quot;&lt;br /&gt;
Header always set Access-Control-Allow-Methods &amp;quot;GET, POST, PUT, DELETE, OPTIONS&amp;quot;&lt;br /&gt;
Header always set Access-Control-Allow-Headers &amp;quot;Content-Type, Authorization, X-Requested-With&amp;quot;&lt;br /&gt;
Header always set Access-Control-Expose-Headers &amp;quot;Authorization&amp;quot;&lt;br /&gt;
Header always set Access-Control-Allow-Credentials &amp;quot;true&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Gérer les requêtes OPTIONS (preflight)&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteCond %{REQUEST_METHOD} OPTIONS&lt;br /&gt;
RewriteRule ^(.*)$ $1 [R=200,L]&lt;br /&gt;
&lt;br /&gt;
# Configuration pour les requêtes HTTP normales&lt;br /&gt;
&amp;lt;Location /&amp;gt;&lt;br /&gt;
	ProxyPass http://127.0.0.1:8000/&lt;br /&gt;
	ProxyPassReverse http://127.0.0.1:8000/&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Attention à bien renseigner le domaine front-end autorisé&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Branchement_docker_%C3%A0_un_nom_de_domaine_Plesk,_debug&amp;diff=79</id>
		<title>Branchement docker à un nom de domaine Plesk, debug</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Branchement_docker_%C3%A0_un_nom_de_domaine_Plesk,_debug&amp;diff=79"/>
		<updated>2025-10-13T19:19:32Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il faut aller dans les directives Apaches du nom de domaine et rajouter :&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
# Activer le mode proxy&lt;br /&gt;
ProxyRequests Off&lt;br /&gt;
ProxyPreserveHost On&lt;br /&gt;
# Configuration pour les requêtes HTTP normales&lt;br /&gt;
&amp;lt;Location /&amp;gt;&lt;br /&gt;
	ProxyPass http://127.0.0.1:&amp;lt;port du conteneur docker&amp;gt;/&lt;br /&gt;
	ProxyPassReverse http://127.0.0.1:&amp;lt;port du conteneur docker&amp;gt;/&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category: Plesk]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Branchement_docker_%C3%A0_un_nom_de_domaine_Plesk,_debug&amp;diff=78</id>
		<title>Branchement docker à un nom de domaine Plesk, debug</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Branchement_docker_%C3%A0_un_nom_de_domaine_Plesk,_debug&amp;diff=78"/>
		<updated>2025-10-13T19:17:28Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « Il faut aller dans les directives Apaches du nom de domaine et rajouter : # Activer le mode proxy ProxyRequests Off ProxyPreserveHost On  # Configuration pour les requêtes HTTP normales &amp;lt;Location /&amp;gt; 	ProxyPass http://127.0.0.1:&amp;lt;port du conteneur docker&amp;gt;/ 	ProxyPassReverse http://127.0.0.1:&amp;lt;port du conteneur docker&amp;gt;/ &amp;lt;/Location&amp;gt; »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il faut aller dans les directives Apaches du nom de domaine et rajouter :&lt;br /&gt;
# Activer le mode proxy&lt;br /&gt;
ProxyRequests Off&lt;br /&gt;
ProxyPreserveHost On&lt;br /&gt;
&lt;br /&gt;
# Configuration pour les requêtes HTTP normales&lt;br /&gt;
&amp;lt;Location /&amp;gt;&lt;br /&gt;
	ProxyPass http://127.0.0.1:&amp;lt;port du conteneur docker&amp;gt;/&lt;br /&gt;
	ProxyPassReverse http://127.0.0.1:&amp;lt;port du conteneur docker&amp;gt;/&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Connecter_automatiquement_un_nom_de_domaine_ionos_sur_Plesk_avec_domain_connect&amp;diff=77</id>
		<title>Connecter automatiquement un nom de domaine ionos sur Plesk avec domain connect</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Connecter_automatiquement_un_nom_de_domaine_ionos_sur_Plesk_avec_domain_connect&amp;diff=77"/>
		<updated>2025-10-11T20:51:16Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « == Configuration automatique d'un nom de domaine avec Domain Connect ==  === Prérequis === * Extension '''Domain Connect''' installée et activée sur Plesk * Nom de domaine enregistré chez IONOS * Accès administrateur à Plesk  === Vue d'ensemble === L'extension Domain Connect permet de configurer automatiquement les paramètres DNS d'un domaine en se connectant directement au registraire (IONOS). Cette méthode simplifie grandement la configuration DNS en é... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuration automatique d'un nom de domaine avec Domain Connect ==&lt;br /&gt;
&lt;br /&gt;
=== Prérequis ===&lt;br /&gt;
* Extension '''Domain Connect''' installée et activée sur Plesk&lt;br /&gt;
* Nom de domaine enregistré chez IONOS&lt;br /&gt;
* Accès administrateur à Plesk&lt;br /&gt;
&lt;br /&gt;
=== Vue d'ensemble ===&lt;br /&gt;
L'extension Domain Connect permet de configurer automatiquement les paramètres DNS d'un domaine en se connectant directement au registraire (IONOS). Cette méthode simplifie grandement la configuration DNS en évitant les modifications manuelles.&lt;br /&gt;
&lt;br /&gt;
=== Étape 1 : Réinitialisation des paramètres DNS sur IONOS ===&lt;br /&gt;
{{Info|Cette étape est cruciale pour permettre à Domain Connect de prendre le contrôle des paramètres DNS.}}&lt;br /&gt;
&lt;br /&gt;
# Connectez-vous à votre espace client '''IONOS'''&lt;br /&gt;
# Accédez à la gestion de votre nom de domaine&lt;br /&gt;
# Dans la section '''DNS''', réinitialisez les paramètres DNS aux valeurs par défaut&lt;br /&gt;
# Assurez-vous qu'aucune configuration DNS personnalisée n'interfère avec le processus&lt;br /&gt;
&lt;br /&gt;
=== Étape 2 : Ajout du domaine dans Plesk ===&lt;br /&gt;
# Connectez-vous à l'interface d'administration '''Plesk'''&lt;br /&gt;
# Cliquez sur '''Ajouter un nouveau domaine''' ou '''Sites Web &amp;amp; Domaines'''&lt;br /&gt;
# Saisissez votre nom de domaine et validez l'enregistrement&lt;br /&gt;
&lt;br /&gt;
=== Étape 3 : Configuration DNS avec Domain Connect ===&lt;br /&gt;
# Accédez aux '''Paramètres DNS''' du domaine nouvellement ajouté&lt;br /&gt;
# Recherchez un message automatique proposant la connexion via '''Domain Connect'''&lt;br /&gt;
&lt;br /&gt;
==== Si le message de connexion automatique apparaît ====&lt;br /&gt;
# Cliquez sur le lien de connexion Domain Connect&lt;br /&gt;
# Suivez les instructions pour autoriser la modification des paramètres DNS&lt;br /&gt;
# La configuration se fait automatiquement&lt;br /&gt;
&lt;br /&gt;
==== Si aucun message ne s'affiche ====&lt;br /&gt;
{{Attention|Il peut être nécessaire de réactiver le service DNS pour déclencher la détection Domain Connect.}}&lt;br /&gt;
&lt;br /&gt;
# Dans les '''Paramètres DNS''' du domaine :&lt;br /&gt;
## Cliquez sur '''Désactiver''' le service DNS&lt;br /&gt;
## Attendez quelques secondes&lt;br /&gt;
## Cliquez sur '''Activer''' le service DNS&lt;br /&gt;
# Actualisez la page&lt;br /&gt;
# Le message de connexion Domain Connect devrait maintenant apparaître&lt;br /&gt;
# Procédez à la connexion comme indiqué ci-dessus&lt;br /&gt;
&lt;br /&gt;
=== Vérification ===&lt;br /&gt;
Une fois la configuration terminée :&lt;br /&gt;
* Les enregistrements DNS sont automatiquement créés&lt;br /&gt;
* Le domaine pointe vers votre serveur Plesk&lt;br /&gt;
* La propagation DNS peut prendre jusqu'à 24-48 heures&lt;br /&gt;
&lt;br /&gt;
=== Résolution des problèmes ===&lt;br /&gt;
* '''Le message Domain Connect n'apparaît pas''' : Vérifiez que l'extension est bien installée et que le domaine est enregistré chez un registraire compatible&lt;br /&gt;
* '''Échec de la connexion''' : Assurez-vous que les paramètres DNS sur IONOS sont bien réinitialisés&lt;br /&gt;
* '''Propagation lente''' : Utilisez des outils comme `nslookup` ou `dig` pour vérifier la propagation DNS&lt;br /&gt;
&lt;br /&gt;
{{Note|Cette procédure fonctionne uniquement avec les registraires supportant le protocole Domain Connect, comme IONOS.}}&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Plesk]]&lt;br /&gt;
[[Catégorie:DNS]]&lt;br /&gt;
[[Catégorie:Configuration]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:N8N&amp;diff=76</id>
		<title>Catégorie:N8N</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:N8N&amp;diff=76"/>
		<updated>2025-08-12T14:44:33Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « 🔗 N8N - Automatisation et Workflows Intelligents N8N est une plateforme d'automatisation open-source qui révolutionne la façon dont nous connectons les applications, automatisons les processus métier et créons des workflows intelligents. Avec son interface visuelle intuitive et ses capacités d'intégration étendues, N8N devient rapidement l'outil incontournable pour créer des &amp;quot;employés virtuels&amp;quot; et optimiser les opérations d'entreprise.  🎯 Pourquoi... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;🔗 N8N - Automatisation et Workflows Intelligents&lt;br /&gt;
N8N est une plateforme d'automatisation open-source qui révolutionne la façon dont nous connectons les applications, automatisons les processus métier et créons des workflows intelligents. Avec son interface visuelle intuitive et ses capacités d'intégration étendues, N8N devient rapidement l'outil incontournable pour créer des &amp;quot;employés virtuels&amp;quot; et optimiser les opérations d'entreprise.&lt;br /&gt;
&lt;br /&gt;
🎯 Pourquoi N8N ?&lt;br /&gt;
Dans un monde où l'efficacité opérationnelle détermine la compétitivité, N8N offre une solution accessible pour automatiser sans limite. Contrairement aux alternatives propriétaires comme Zapier ou Microsoft Power Automate, N8N vous donne un contrôle total sur vos données et processus, tout en étant économiquement viable à grande échelle.&lt;br /&gt;
&lt;br /&gt;
⚡ Capacités Principales&lt;br /&gt;
400+ intégrations natives : APIs, bases de données, services cloud, outils métier&lt;br /&gt;
Interface visuelle no-code/low-code : Création intuitive de workflows complexes&lt;br /&gt;
Exécution auto-hébergée : Sécurité et confidentialité maximales&lt;br /&gt;
Logique conditionnelle avancée : Branches, boucles, transformations de données&lt;br /&gt;
Intégration IA : OpenAI, Claude, modèles personnalisés pour des workflows intelligents&lt;br /&gt;
Scalabilité enterprise : Gestion de millions d'exécutions&lt;br /&gt;
🤖 Cas d'Usage Couverts&lt;br /&gt;
Automatisation Business&lt;br /&gt;
Automatisation des processus répétitifs, gestion des leads, rapports automatiques, synchronisation de données entre systèmes.&lt;br /&gt;
&lt;br /&gt;
Agents Virtuels Intelligents&lt;br /&gt;
Création d'assistants autonomes capables de traiter emails, analyser données, prendre des décisions et interagir avec clients.&lt;br /&gt;
&lt;br /&gt;
Intégration IoT &amp;amp; Web&lt;br /&gt;
Connexion de capteurs IoT avec applications web, dashboards temps réel, alertes automatiques et actions correctives.&lt;br /&gt;
&lt;br /&gt;
Marketing &amp;amp; Sales Automation&lt;br /&gt;
Campagnes personnalisées, nurturing leads, publication sociale automatique, analytics et reporting.&lt;br /&gt;
&lt;br /&gt;
📚 Contenu de cette Catégorie&lt;br /&gt;
Cette section du wiki rassemble tout ce que vous devez savoir pour maîtriser N8N :&lt;br /&gt;
&lt;br /&gt;
🚀 Guides de démarrage : Installation, configuration, premiers workflows&lt;br /&gt;
🔧 Tutoriels techniques : Intégrations avancées, custom nodes, best practices&lt;br /&gt;
🏗️ Architectures de référence : Patterns éprouvés pour cas d'usage complexes&lt;br /&gt;
🤖 Agents intelligents : Construction d'employés virtuels avec IA&lt;br /&gt;
📈 Cas d'étude réels : Exemples concrets d'automatisations business&lt;br /&gt;
🛠️ Ressources &amp;amp; outils : Templates, scripts, intégrations personnalisées&lt;br /&gt;
🎓 Pour qui ?&lt;br /&gt;
Développeurs : Étendez vos applications avec des workflows automatisés puissants&lt;br /&gt;
Business Analysts : Automatisez les processus sans coder&lt;br /&gt;
Entrepreneurs : Optimisez vos opérations et réduisez les coûts&lt;br /&gt;
IT Operations : Orchestrez vos systèmes et surveillances&lt;br /&gt;
&lt;br /&gt;
🚀 Commencer dès Maintenant&lt;br /&gt;
Que vous soyez débutant cherchant à automatiser vos premières tâches ou expert souhaitant créer des systèmes complexes, cette documentation vous accompagne pas à pas. N8N représente l'avenir de l'automatisation intelligente - accessible, puissant, et sans limites.&lt;br /&gt;
&lt;br /&gt;
Explorez les guides ci-dessous et transformez votre façon de travailler !&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=MediaWiki:Sidebar&amp;diff=75</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=MediaWiki:Sidebar&amp;diff=75"/>
		<updated>2025-08-12T14:38:24Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* Catégories&lt;br /&gt;
** :Catégorie:Apache|Apache&lt;br /&gt;
** :Catégorie:Bootstrap|Bootstrap&lt;br /&gt;
** :Catégorie:Centos|Centos&lt;br /&gt;
** :Catégorie:Drupal|Drupal&lt;br /&gt;
** :Catégorie:Git|Git&lt;br /&gt;
** :Catégorie:Github|Github&lt;br /&gt;
** :Catégorie:Laravel|Laravel&lt;br /&gt;
** :Catégorie:Linux|Linux&lt;br /&gt;
** :Catégorie:Mediawiki|Mediawiki&lt;br /&gt;
** :Catégorie:MQL5|MQL5&lt;br /&gt;
** :Catégorie:MySQL|MySQL&lt;br /&gt;
** :Catégorie:N8N|N8N&lt;br /&gt;
** :Catégorie:NextJs|NextJS&lt;br /&gt;
** :Catégorie:Nodejs|Nodejs&lt;br /&gt;
** :Catégorie:Plesk|Plesk&lt;br /&gt;
** :Catégorie:React|React&lt;br /&gt;
** :Catégorie:Rsync|Rsync&lt;br /&gt;
** :Catégorie:Symfony|Symfony&lt;br /&gt;
** :Catégorie:Twig|Twig&lt;br /&gt;
** :Catégorie:Vue.js|Vue.js&lt;br /&gt;
** :Catégorie:Wordpress|Wordpress&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Laravel_:_Utiliser_les_event_listeners_Eloquent&amp;diff=74</id>
		<title>Laravel : Utiliser les event listeners Eloquent</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Laravel_:_Utiliser_les_event_listeners_Eloquent&amp;diff=74"/>
		<updated>2025-07-22T12:34:26Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « = Guide Complet : Event Listeners Eloquent =  == Qu'est-ce que les Event Listeners Eloquent ? ==  Les '''Event Listeners Eloquent''' sont des hooks qui permettent d'exécuter du code automatiquement à des moments précis du cycle de vie d'un modèle Eloquent (création, mise à jour, suppression, etc.).  C'est comme avoir des &amp;quot;déclencheurs&amp;quot; qui s'activent automatiquement quand quelque chose arrive à vos données.  == Le cycle de vie d'un modèle Eloquent ==  &amp;lt;... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Guide Complet : Event Listeners Eloquent =&lt;br /&gt;
&lt;br /&gt;
== Qu'est-ce que les Event Listeners Eloquent ? ==&lt;br /&gt;
&lt;br /&gt;
Les '''Event Listeners Eloquent''' sont des hooks qui permettent d'exécuter du code automatiquement à des moments précis du cycle de vie d'un modèle Eloquent (création, mise à jour, suppression, etc.).&lt;br /&gt;
&lt;br /&gt;
C'est comme avoir des &amp;quot;déclencheurs&amp;quot; qui s'activent automatiquement quand quelque chose arrive à vos données.&lt;br /&gt;
&lt;br /&gt;
== Le cycle de vie d'un modèle Eloquent ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Création:     retrieved → creating → created → saving → saved&lt;br /&gt;
Mise à jour:  retrieved → updating → updated → saving → saved  &lt;br /&gt;
Suppression:  retrieved → deleting → deleted&lt;br /&gt;
Restauration: retrieved → restoring → restored&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Les événements disponibles ==&lt;br /&gt;
&lt;br /&gt;
=== Événements principaux ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Événement !! Moment de déclenchement !! Peut empêcher l'action&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;retrieved&amp;lt;/code&amp;gt; || Quand un modèle est récupéré de la DB || ❌ Non&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;creating&amp;lt;/code&amp;gt; || '''Avant''' la création || ✅ Oui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;created&amp;lt;/code&amp;gt; || '''Après''' la création || ❌ Non&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;updating&amp;lt;/code&amp;gt; || '''Avant''' la mise à jour || ✅ Oui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;updated&amp;lt;/code&amp;gt; || '''Après''' la mise à jour || ❌ Non&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;saving&amp;lt;/code&amp;gt; || '''Avant''' création OU mise à jour || ✅ Oui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;saved&amp;lt;/code&amp;gt; || '''Après''' création OU mise à jour || ❌ Non&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;deleting&amp;lt;/code&amp;gt; || '''Avant''' la suppression || ✅ Oui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;deleted&amp;lt;/code&amp;gt; || '''Après''' la suppression || ❌ Non&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;restoring&amp;lt;/code&amp;gt; || '''Avant''' la restauration (soft delete) || ✅ Oui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;restored&amp;lt;/code&amp;gt; || '''Après''' la restauration || ❌ Non&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Comment utiliser les Event Listeners ==&lt;br /&gt;
&lt;br /&gt;
=== Méthode 1 : Dans la méthode boot() du modèle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
namespace App\Models;&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Eloquent\Model;&lt;br /&gt;
use Illuminate\Support\Str;&lt;br /&gt;
&lt;br /&gt;
class User extends Model&lt;br /&gt;
{&lt;br /&gt;
    protected $fillable = ['nom', 'email', 'password'];&lt;br /&gt;
&lt;br /&gt;
    protected static function boot()&lt;br /&gt;
    {&lt;br /&gt;
        parent::boot(); // ⚠️ OBLIGATOIRE !&lt;br /&gt;
&lt;br /&gt;
        // Avant création&lt;br /&gt;
        static::creating(function ($user) {&lt;br /&gt;
            $user-&amp;gt;uuid = Str::uuid();&lt;br /&gt;
            $user-&amp;gt;slug = Str::slug($user-&amp;gt;nom);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Après création&lt;br /&gt;
        static::created(function ($user) {&lt;br /&gt;
            // Envoyer email de bienvenue&lt;br /&gt;
            \Mail::to($user-&amp;gt;email)-&amp;gt;send(new WelcomeEmail($user));&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Avant mise à jour&lt;br /&gt;
        static::updating(function ($user) {&lt;br /&gt;
            if ($user-&amp;gt;isDirty('email')) {&lt;br /&gt;
                $user-&amp;gt;email_verified_at = null;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Avant suppression&lt;br /&gt;
        static::deleting(function ($user) {&lt;br /&gt;
            // Supprimer tous les posts de l'utilisateur&lt;br /&gt;
            $user-&amp;gt;posts()-&amp;gt;delete();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exemples pratiques détaillés ==&lt;br /&gt;
&lt;br /&gt;
=== Exemple 1 : Gestion automatique des slugs ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class Article extends Model&lt;br /&gt;
{&lt;br /&gt;
    protected $fillable = ['titre', 'contenu', 'auteur_id'];&lt;br /&gt;
&lt;br /&gt;
    protected static function boot()&lt;br /&gt;
    {&lt;br /&gt;
        parent::boot();&lt;br /&gt;
&lt;br /&gt;
        // Générer le slug automatiquement&lt;br /&gt;
        static::creating(function ($article) {&lt;br /&gt;
            $article-&amp;gt;slug = Str::slug($article-&amp;gt;titre);&lt;br /&gt;
            &lt;br /&gt;
            // Gérer les doublons&lt;br /&gt;
            $originalSlug = $article-&amp;gt;slug;&lt;br /&gt;
            $counter = 1;&lt;br /&gt;
            &lt;br /&gt;
            while (static::where('slug', $article-&amp;gt;slug)-&amp;gt;exists()) {&lt;br /&gt;
                $article-&amp;gt;slug = $originalSlug . '-' . $counter;&lt;br /&gt;
                $counter++;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Mettre à jour le slug si le titre change&lt;br /&gt;
        static::updating(function ($article) {&lt;br /&gt;
            if ($article-&amp;gt;isDirty('titre')) {&lt;br /&gt;
                $article-&amp;gt;slug = Str::slug($article-&amp;gt;titre);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple 2 : Audit automatique ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class Commande extends Model&lt;br /&gt;
{&lt;br /&gt;
    protected $fillable = ['user_id', 'total', 'statut'];&lt;br /&gt;
&lt;br /&gt;
    protected static function boot()&lt;br /&gt;
    {&lt;br /&gt;
        parent::boot();&lt;br /&gt;
&lt;br /&gt;
        // Log toutes les modifications&lt;br /&gt;
        static::saving(function ($commande) {&lt;br /&gt;
            if ($commande-&amp;gt;exists) {&lt;br /&gt;
                // C'est une mise à jour&lt;br /&gt;
                $changes = $commande-&amp;gt;getDirty();&lt;br /&gt;
                if (!empty($changes)) {&lt;br /&gt;
                    AuditLog::create([&lt;br /&gt;
                        'model_type' =&amp;gt; get_class($commande),&lt;br /&gt;
                        'model_id' =&amp;gt; $commande-&amp;gt;id,&lt;br /&gt;
                        'action' =&amp;gt; 'updated',&lt;br /&gt;
                        'changes' =&amp;gt; $changes,&lt;br /&gt;
                        'user_id' =&amp;gt; auth()-&amp;gt;id(),&lt;br /&gt;
                    ]);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        static::created(function ($commande) {&lt;br /&gt;
            AuditLog::create([&lt;br /&gt;
                'model_type' =&amp;gt; get_class($commande),&lt;br /&gt;
                'model_id' =&amp;gt; $commande-&amp;gt;id,&lt;br /&gt;
                'action' =&amp;gt; 'created',&lt;br /&gt;
                'user_id' =&amp;gt; auth()-&amp;gt;id(),&lt;br /&gt;
            ]);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple 3 : Gestion des fichiers ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class Document extends Model&lt;br /&gt;
{&lt;br /&gt;
    protected $fillable = ['nom', 'chemin', 'taille'];&lt;br /&gt;
&lt;br /&gt;
    protected static function boot()&lt;br /&gt;
    {&lt;br /&gt;
        parent::boot();&lt;br /&gt;
&lt;br /&gt;
        // Supprimer le fichier physique quand le modèle est supprimé&lt;br /&gt;
        static::deleting(function ($document) {&lt;br /&gt;
            if (Storage::exists($document-&amp;gt;chemin)) {&lt;br /&gt;
                Storage::delete($document-&amp;gt;chemin);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Calculer la taille automatiquement&lt;br /&gt;
        static::creating(function ($document) {&lt;br /&gt;
            if ($document-&amp;gt;chemin &amp;amp;&amp;amp; Storage::exists($document-&amp;gt;chemin)) {&lt;br /&gt;
                $document-&amp;gt;taille = Storage::size($document-&amp;gt;chemin);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Empêcher une action ==&lt;br /&gt;
&lt;br /&gt;
=== Retourner false pour annuler l'opération ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class User extends Model&lt;br /&gt;
{&lt;br /&gt;
    protected static function boot()&lt;br /&gt;
    {&lt;br /&gt;
        parent::boot();&lt;br /&gt;
&lt;br /&gt;
        // Empêcher la suppression de l'admin&lt;br /&gt;
        static::deleting(function ($user) {&lt;br /&gt;
            if ($user-&amp;gt;role === 'admin') {&lt;br /&gt;
                // Empêche la suppression&lt;br /&gt;
                return false;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Validation avant sauvegarde&lt;br /&gt;
        static::saving(function ($user) {&lt;br /&gt;
            if (empty($user-&amp;gt;email)) {&lt;br /&gt;
                return false; // Empêche la sauvegarde&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Avec exceptions pour plus de clarté ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
static::deleting(function ($user) {&lt;br /&gt;
    if ($user-&amp;gt;commandes()-&amp;gt;exists()) {&lt;br /&gt;
        throw new \Exception('Impossible de supprimer un utilisateur avec des commandes');&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Méthodes utiles dans les Event Listeners ==&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les changements ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
static::updating(function ($model) {&lt;br /&gt;
    // Vérifier si un champ spécifique a changé&lt;br /&gt;
    if ($model-&amp;gt;isDirty('email')) {&lt;br /&gt;
        // L'email a changé&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Obtenir la valeur originale&lt;br /&gt;
    $oldEmail = $model-&amp;gt;getOriginal('email');&lt;br /&gt;
    $newEmail = $model-&amp;gt;email;&lt;br /&gt;
&lt;br /&gt;
    // Obtenir tous les champs modifiés&lt;br /&gt;
    $changes = $model-&amp;gt;getDirty();&lt;br /&gt;
    // ['email' =&amp;gt; 'new@email.com', 'nom' =&amp;gt; 'Nouveau Nom']&lt;br /&gt;
&lt;br /&gt;
    // Vérifier si c'est une création ou mise à jour&lt;br /&gt;
    if ($model-&amp;gt;exists) {&lt;br /&gt;
        // C'est une mise à jour&lt;br /&gt;
    } else {&lt;br /&gt;
        // C'est une création&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Méthode 2 : Observers (Plus propre pour la logique complexe) ==&lt;br /&gt;
&lt;br /&gt;
=== Créer un Observer ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;php artisan make:observer UserObserver --model=User&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dans app/Observers/UserObserver.php ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
namespace App\Observers;&lt;br /&gt;
&lt;br /&gt;
use App\Models\User;&lt;br /&gt;
use App\Mail\WelcomeEmail;&lt;br /&gt;
use Illuminate\Support\Facades\Mail;&lt;br /&gt;
&lt;br /&gt;
class UserObserver&lt;br /&gt;
{&lt;br /&gt;
    public function creating(User $user): void&lt;br /&gt;
    {&lt;br /&gt;
        $user-&amp;gt;uuid = Str::uuid();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function created(User $user): void&lt;br /&gt;
    {&lt;br /&gt;
        Mail::to($user-&amp;gt;email)-&amp;gt;send(new WelcomeEmail($user));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function updating(User $user): void&lt;br /&gt;
    {&lt;br /&gt;
        if ($user-&amp;gt;isDirty('email')) {&lt;br /&gt;
            $user-&amp;gt;email_verified_at = null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function deleting(User $user): void&lt;br /&gt;
    {&lt;br /&gt;
        if ($user-&amp;gt;role === 'admin') {&lt;br /&gt;
            throw new \Exception('Impossible de supprimer un admin');&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function deleted(User $user): void&lt;br /&gt;
    {&lt;br /&gt;
        // Nettoyer les données associées&lt;br /&gt;
        $user-&amp;gt;posts()-&amp;gt;delete();&lt;br /&gt;
        $user-&amp;gt;comments()-&amp;gt;delete();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enregistrer l'Observer dans AppServiceProvider ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
namespace App\Providers;&lt;br /&gt;
&lt;br /&gt;
use App\Models\User;&lt;br /&gt;
use App\Observers\UserObserver;&lt;br /&gt;
use Illuminate\Support\ServiceProvider;&lt;br /&gt;
&lt;br /&gt;
class AppServiceProvider extends ServiceProvider&lt;br /&gt;
{&lt;br /&gt;
    public function boot(): void&lt;br /&gt;
    {&lt;br /&gt;
        User::observe(UserObserver::class);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Event Listeners conditionnels ==&lt;br /&gt;
&lt;br /&gt;
=== Exécuter seulement dans certaines conditions ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class Product extends Model&lt;br /&gt;
{&lt;br /&gt;
    protected static function boot()&lt;br /&gt;
    {&lt;br /&gt;
        parent::boot();&lt;br /&gt;
&lt;br /&gt;
        static::updating(function ($product) {&lt;br /&gt;
            // Seulement si le prix change&lt;br /&gt;
            if ($product-&amp;gt;isDirty('prix')) {&lt;br /&gt;
                // Notifier les utilisateurs qui suivent ce produit&lt;br /&gt;
                $product-&amp;gt;followers()-&amp;gt;each(function ($user) {&lt;br /&gt;
                    Mail::to($user)-&amp;gt;send(new PriceChangedEmail($product));&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Seulement en production&lt;br /&gt;
        static::created(function ($product) {&lt;br /&gt;
            if (app()-&amp;gt;environment('production')) {&lt;br /&gt;
                // Indexer dans Elasticsearch&lt;br /&gt;
                $product-&amp;gt;searchableIndex();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Performances et bonnes pratiques ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Éviter les requêtes N+1 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// ❌ Mauvais&lt;br /&gt;
static::deleting(function ($user) {&lt;br /&gt;
    foreach ($user-&amp;gt;posts as $post) { // N+1 query !&lt;br /&gt;
        $post-&amp;gt;delete();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// ✅ Bon&lt;br /&gt;
static::deleting(function ($user) {&lt;br /&gt;
    $user-&amp;gt;posts()-&amp;gt;delete(); // Une seule requête&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. Utiliser les queues pour les tâches lourdes ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
static::created(function ($user) {&lt;br /&gt;
    // ❌ Bloque la réponse&lt;br /&gt;
    Mail::to($user)-&amp;gt;send(new WelcomeEmail($user));&lt;br /&gt;
    &lt;br /&gt;
    // ✅ Asynchrone&lt;br /&gt;
    Mail::to($user)-&amp;gt;queue(new WelcomeEmail($user));&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Attention aux boucles infinies ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// ❌ Risque de boucle infinie !&lt;br /&gt;
static::updating(function ($user) {&lt;br /&gt;
    $user-&amp;gt;update(['last_modified' =&amp;gt; now()]); // Re-déclenche updating !&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// ✅ Correct&lt;br /&gt;
static::updating(function ($user) {&lt;br /&gt;
    $user-&amp;gt;last_modified = now(); // Pas de nouvelle requête&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tester les Event Listeners ==&lt;br /&gt;
&lt;br /&gt;
=== Test unitaire ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
namespace Tests\Unit;&lt;br /&gt;
&lt;br /&gt;
use App\Models\User;&lt;br /&gt;
use Illuminate\Foundation\Testing\RefreshDatabase;&lt;br /&gt;
use Tests\TestCase;&lt;br /&gt;
&lt;br /&gt;
class UserEventTest extends TestCase&lt;br /&gt;
{&lt;br /&gt;
    use RefreshDatabase;&lt;br /&gt;
&lt;br /&gt;
    public function test_user_gets_uuid_on_creation()&lt;br /&gt;
    {&lt;br /&gt;
        $user = User::create([&lt;br /&gt;
            'nom' =&amp;gt; 'Test User',&lt;br /&gt;
            'email' =&amp;gt; 'test@example.com',&lt;br /&gt;
            'password' =&amp;gt; 'password123'&lt;br /&gt;
        ]);&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;assertNotNull($user-&amp;gt;uuid);&lt;br /&gt;
        $this-&amp;gt;assertEquals(36, strlen($user-&amp;gt;uuid)); // UUID length&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function test_email_verification_reset_on_email_change()&lt;br /&gt;
    {&lt;br /&gt;
        $user = User::factory()-&amp;gt;verified()-&amp;gt;create();&lt;br /&gt;
        $this-&amp;gt;assertNotNull($user-&amp;gt;email_verified_at);&lt;br /&gt;
&lt;br /&gt;
        $user-&amp;gt;update(['email' =&amp;gt; 'new@example.com']);&lt;br /&gt;
        $this-&amp;gt;assertNull($user-&amp;gt;fresh()-&amp;gt;email_verified_at);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Cas d'usage courants ==&lt;br /&gt;
&lt;br /&gt;
=== 1. E-commerce ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Gestion des stocks&lt;br /&gt;
static::created(function ($commande) {&lt;br /&gt;
    foreach ($commande-&amp;gt;items as $item) {&lt;br /&gt;
        $item-&amp;gt;product-&amp;gt;decrement('stock', $item-&amp;gt;quantite);&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. Blog ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Cache invalidation&lt;br /&gt;
static::saved(function ($article) {&lt;br /&gt;
    Cache::forget('articles.latest');&lt;br /&gt;
    Cache::forget(&amp;quot;article.{$article-&amp;gt;slug}&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. CRM ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Score de lead automatique&lt;br /&gt;
static::creating(function ($lead) {&lt;br /&gt;
    $lead-&amp;gt;score = $this-&amp;gt;calculateLeadScore($lead);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Comparaison : boot() vs Observer ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Critère !! boot() !! Observer&lt;br /&gt;
|-&lt;br /&gt;
| '''Simplicité''' || ✅ Simple pour logique basique || ❌ Plus de setup&lt;br /&gt;
|-&lt;br /&gt;
| '''Lisibilité''' || ❌ Peut devenir lourd || ✅ Code séparé et organisé&lt;br /&gt;
|-&lt;br /&gt;
| '''Testabilité''' || ❌ Plus difficile à tester || ✅ Facile à tester&lt;br /&gt;
|-&lt;br /&gt;
| '''Réutilisabilité''' || ❌ Lié au modèle || ✅ Réutilisable&lt;br /&gt;
|-&lt;br /&gt;
| '''Performance''' || ✅ Léger || ✅ Léger&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Recommandations ==&lt;br /&gt;
&lt;br /&gt;
=== Utilisez boot() pour ===&lt;br /&gt;
* Logique simple (1-3 lignes)&lt;br /&gt;
* Actions basiques (slugs, timestamps)&lt;br /&gt;
* Prototypage rapide&lt;br /&gt;
&lt;br /&gt;
=== Utilisez Observer pour ===&lt;br /&gt;
* Logique complexe&lt;br /&gt;
* Plusieurs événements&lt;br /&gt;
* Code réutilisable&lt;br /&gt;
* Tests unitaires&lt;br /&gt;
&lt;br /&gt;
== Exemple complet : Système de blog ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Modèle Article&lt;br /&gt;
class Article extends Model&lt;br /&gt;
{&lt;br /&gt;
    protected static function boot()&lt;br /&gt;
    {&lt;br /&gt;
        parent::boot();&lt;br /&gt;
&lt;br /&gt;
        // Slug automatique&lt;br /&gt;
        static::creating(function ($article) {&lt;br /&gt;
            $article-&amp;gt;slug = Str::slug($article-&amp;gt;titre);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Invalidation du cache&lt;br /&gt;
        static::saved(function ($article) {&lt;br /&gt;
            Cache::forget('articles.published');&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Observer ArticleObserver&lt;br /&gt;
class ArticleObserver&lt;br /&gt;
{&lt;br /&gt;
    public function created(Article $article): void&lt;br /&gt;
    {&lt;br /&gt;
        // Notifier les abonnés&lt;br /&gt;
        $article-&amp;gt;author-&amp;gt;followers()-&amp;gt;each(function ($follower) use ($article) {&lt;br /&gt;
            Notification::send($follower, new NewArticleNotification($article));&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function updating(Article $article): void&lt;br /&gt;
    {&lt;br /&gt;
        // Log les modifications importantes&lt;br /&gt;
        if ($article-&amp;gt;isDirty('statut')) {&lt;br /&gt;
            ActivityLog::create([&lt;br /&gt;
                'action' =&amp;gt; 'status_changed',&lt;br /&gt;
                'model' =&amp;gt; $article,&lt;br /&gt;
                'old_value' =&amp;gt; $article-&amp;gt;getOriginal('statut'),&lt;br /&gt;
                'new_value' =&amp;gt; $article-&amp;gt;statut,&lt;br /&gt;
            ]);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function deleting(Article $article): bool&lt;br /&gt;
    {&lt;br /&gt;
        // Empêcher la suppression d'articles publiés&lt;br /&gt;
        if ($article-&amp;gt;statut === 'published') {&lt;br /&gt;
            throw new \Exception('Impossible de supprimer un article publié');&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Règle d'or :''' Gardez-les simples et focalisés sur une responsabilité !&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Laravel]]&lt;br /&gt;
[[Catégorie:PHP]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=R%C3%A9solutions_d%27erreurs_CORS&amp;diff=73</id>
		<title>Résolutions d'erreurs CORS</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=R%C3%A9solutions_d%27erreurs_CORS&amp;diff=73"/>
		<updated>2025-07-20T23:00:22Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Histoire 1 : React.js (1 journée de 9h passée à trouver la solution 😒) ===&lt;br /&gt;
Dans des requêtes faites à une API via axios, je tombait pour certaines requêtes (et seulement certaines) sur des blocages CORS. Ce qui était encore plus étrange c'est que tout fonctionnait parfaitement quand mon api était hébergée en local, les problèmes sont apparus quand je l'ai hébergée en ligne.&lt;br /&gt;
&lt;br /&gt;
Bref, après une journée à tester mille et une solutions dont l'ajout des headers Acess-Control[....] dans la config d'Apache (.htaccess et config.d) et côté client en rajoutant des &amp;quot;Access-Control-Allow-Origin&amp;quot;: &amp;quot;*&amp;quot; à l'en-tête de mes requêtes; je parviens à faire passer mes requêtes en '''retirant un slash ( / ) qui trainait à la fin de l'url de ma requête''' côté client react.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Vérifier le sanctum&lt;br /&gt;
&lt;br /&gt;
Si votre application front-end est hébergée sur un domaine différent, assurez-vous de configurer les paramètres CORS dans le fichier &amp;lt;code&amp;gt;config/sanctum.php&amp;lt;/code&amp;gt;. Ajoutez votre domaine dans la section &amp;lt;code&amp;gt;stateful&amp;lt;/code&amp;gt; :&lt;br /&gt;
 'stateful' =&amp;gt; explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(&lt;br /&gt;
         '%s%s',&lt;br /&gt;
         'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,&amp;lt;nowiki&amp;gt;https://abdoulaye-diallo.com'&amp;lt;/nowiki&amp;gt;,&lt;br /&gt;
         Sanctum::currentApplicationUrlWithPort()&lt;br /&gt;
     ))),&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Vérifier très bien la syntaxe de vos URL&lt;br /&gt;
&lt;br /&gt;
Encore plusieurs jours de perdus car incohérence dans les URL. Revérifier à plusieurs reprises que le front fait bien appel à l'api correctement. &lt;br /&gt;
&lt;br /&gt;
J'avais une erreur car mon front faisait appel à  'https://api.vtcprivetoure.fr/api&amp;lt;nowiki/&amp;gt;' alors que je devais appeler 'https://api.vtcprivetoure.fr/api&amp;lt;nowiki/&amp;gt;'. ici c'est le sous-domaine api qui m'a induit en erreur.&lt;br /&gt;
&lt;br /&gt;
[[index.php?title=Catégorie:React]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_%C3%A0_jour_les_versions_php,_node_et_npm_d%27un_utilisateur_sur_Plesk&amp;diff=72</id>
		<title>Mettre à jour les versions php, node et npm d'un utilisateur sur Plesk</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_%C3%A0_jour_les_versions_php,_node_et_npm_d%27un_utilisateur_sur_Plesk&amp;diff=72"/>
		<updated>2024-09-04T03:43:53Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Problème que j'ai rencontré en mettant en place un CD avec Github Workflow, les sources des commande php et node étaient différentes de celle de l'utilisateur concerné et celles du route.&lt;br /&gt;
&lt;br /&gt;
J'ai alors rajouté dans mon script de déploiement les commandes suivantes pour savoir où se situent les commandes de références et quelles sont leurs versions : &amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
php -v&lt;br /&gt;
which php&lt;br /&gt;
npm -v&lt;br /&gt;
which npm&lt;br /&gt;
node -v&lt;br /&gt;
which node&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;En inpectant les logs de l'action on obtiens ainsi ces informations qui nous montrent d'où vient le soucis.&lt;br /&gt;
&lt;br /&gt;
Une des solutions possible est alors d'aller chercher les sources des bonnes version directement de puis le teminal de Plesk toujours avec les même commandes. Ensuite il faut remplacer la sources de commandes du Github Actions par celles du serveur plesk ayant la bonne version. Avant de faire la manipulation on s'assure de faire un backup de la version actuelle défaillante, par exemple : &amp;lt;code&amp;gt;mv /usr/bin/node /usr/bin/node-backup&amp;lt;/code&amp;gt;  et ensuite rajouter à la place un lien symbolique vers la commande ayant la bonne version par exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ln -s /opt/plesk/node/22/bin/node /usr/bin/node&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Plesk]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_%C3%A0_jour_les_versions_php,_node_et_npm_d%27un_utilisateur_sur_Plesk&amp;diff=71</id>
		<title>Mettre à jour les versions php, node et npm d'un utilisateur sur Plesk</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_%C3%A0_jour_les_versions_php,_node_et_npm_d%27un_utilisateur_sur_Plesk&amp;diff=71"/>
		<updated>2024-09-04T03:43:26Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Problème que j'ai rencontré en mettant en place un CD avec Github Workflow, les sources des commande php et node étaient différentes de celle de l'utilisateur concerné et celles du route.&lt;br /&gt;
&lt;br /&gt;
J'ai alors rajouté dans mon script de déploiement les commandes suivantes pour savoir où se situent les commandes de références et quelles sont leurs versions : &amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
php -v&lt;br /&gt;
which php&lt;br /&gt;
npm -v&lt;br /&gt;
which npm&lt;br /&gt;
node -v&lt;br /&gt;
which node&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;En inpectant les logs de l'action on obtiens ainsi ces informations qui nous montrent d'où vient le soucis.&lt;br /&gt;
&lt;br /&gt;
Une des solutions possible est alors d'aller chercher les sources des bonnes version directement de puis le teminal de Plesk toujours avec les même commandes. Ensuite il faut remplacer la sources de commandes du Github Actions par celles du serveur plesk ayant la bonne version. Avant de faire la manipulation on s'assure de faire un backup de la version actuelle défaillante, par exemple : &amp;lt;code&amp;gt;mv /usr/bin/node /usr/bin/node-backup&amp;lt;/code&amp;gt;  et ensuite rajouter à la place un lien symbolique vers la commande ayant la bonne version par exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ln -s /opt/plesk/node/22/bin/node /usr/bin/node&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Plesk:Plesk]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_%C3%A0_jour_les_versions_php,_node_et_npm_d%27un_utilisateur_sur_Plesk&amp;diff=70</id>
		<title>Mettre à jour les versions php, node et npm d'un utilisateur sur Plesk</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_%C3%A0_jour_les_versions_php,_node_et_npm_d%27un_utilisateur_sur_Plesk&amp;diff=70"/>
		<updated>2024-09-04T03:43:00Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « Problème que j'ai rencontré en mettant en place un CD avec Github Workflow, les sources des commande php et node étaient différentes de celle de l'utilisateur concerné et celles du route.  J'ai alors rajouté dans mon script de déploiement les commandes suivantes pour savoir où se situent les commandes de références et quelles sont leurs versions : &amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt; php -v which php npm -v which npm node -v which node &amp;lt;/syntaxhighlight&amp;gt;En inp... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Problème que j'ai rencontré en mettant en place un CD avec Github Workflow, les sources des commande php et node étaient différentes de celle de l'utilisateur concerné et celles du route.&lt;br /&gt;
&lt;br /&gt;
J'ai alors rajouté dans mon script de déploiement les commandes suivantes pour savoir où se situent les commandes de références et quelles sont leurs versions : &amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
php -v&lt;br /&gt;
which php&lt;br /&gt;
npm -v&lt;br /&gt;
which npm&lt;br /&gt;
node -v&lt;br /&gt;
which node&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;En inpectant les logs de l'action on obtiens ainsi ces informations qui nous montrent d'où vient le soucis.&lt;br /&gt;
&lt;br /&gt;
Une des solutions possible est alors d'aller chercher les sources des bonnes version directement de puis le teminal de Plesk toujours avec les même commandes. Ensuite il faut remplacer la sources de commandes du Github Actions par celles du serveur plesk ayant la bonne version. Avant de faire la manipulation on s'assure de faire un backup de la version actuelle défaillante, par exemple : &amp;lt;code&amp;gt;mv /usr/bin/node /usr/bin/node-backup&amp;lt;/code&amp;gt;  et ensuite rajouter à la place un lien symbolique vers la commande ayant la bonne version par exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ln -s /opt/plesk/node/22/bin/node /usr/bin/node&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Conception_et_d%C3%A9veloppement_de_SilverEvents&amp;diff=69</id>
		<title>Conception et développement de SilverEvents</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Conception_et_d%C3%A9veloppement_de_SilverEvents&amp;diff=69"/>
		<updated>2024-08-10T16:21:03Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
npm create svelte@latest silver-events&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Choisis &amp;lt;code&amp;gt;Skeleton project&amp;lt;/code&amp;gt; pour une configuration minimale.&lt;br /&gt;
* Sélectionne &amp;lt;code&amp;gt;Yes&amp;lt;/code&amp;gt; pour ajouter TypeScript.&lt;br /&gt;
* Sélectionne &amp;lt;code&amp;gt;Yes&amp;lt;/code&amp;gt; pour ESLint et Prettier et Vitest&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
npm install&lt;br /&gt;
&lt;br /&gt;
npm run dev&lt;br /&gt;
&lt;br /&gt;
npm install @prisma/client&lt;br /&gt;
&lt;br /&gt;
npm install -D prisma&lt;br /&gt;
&lt;br /&gt;
npx prisma init&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans le dossier Le fichier &amp;lt;code&amp;gt;schema.prisma&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
generator client {&lt;br /&gt;
  provider = &amp;quot;prisma-client-js&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
datasource db {&lt;br /&gt;
  provider = &amp;quot;mysql&amp;quot; &lt;br /&gt;
  url      = env(&amp;quot;DATABASE_URL&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans le .env, paramétrer la base de donnée :&lt;br /&gt;
&lt;br /&gt;
DATABASE_URL=&amp;quot;file:./dev.db&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Lancer la migration pour vérifier la connexion : &lt;br /&gt;
&lt;br /&gt;
npx prisma migrate dev --name init&lt;br /&gt;
&lt;br /&gt;
Crée un fichier &amp;lt;code&amp;gt;prisma.ts&amp;lt;/code&amp;gt; dans &amp;lt;code&amp;gt;src/lib&amp;lt;/code&amp;gt; pour initialiser Prisma :&amp;lt;syntaxhighlight lang=&amp;quot;ts&amp;quot;&amp;gt;&lt;br /&gt;
import { PrismaClient } from '@prisma/client';&lt;br /&gt;
&lt;br /&gt;
const prisma = new PrismaClient();&lt;br /&gt;
&lt;br /&gt;
export default prisma;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Conception_et_d%C3%A9veloppement_de_SilverEvents&amp;diff=68</id>
		<title>Conception et développement de SilverEvents</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Conception_et_d%C3%A9veloppement_de_SilverEvents&amp;diff=68"/>
		<updated>2024-08-10T16:20:13Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; npm create svelte@latest silver-events &amp;lt;/syntaxhighlight&amp;gt;  * Choisis &amp;lt;code&amp;gt;Skeleton project&amp;lt;/code&amp;gt; pour une configuration minimale. * Sélectionne &amp;lt;code&amp;gt;Yes&amp;lt;/code&amp;gt; pour ajouter TypeScript. * Sélectionne &amp;lt;code&amp;gt;Yes&amp;lt;/code&amp;gt; pour ESLint et Prettier et Vitest  npm install  npm run dev  npm install @prisma/client  npm install -D prisma  npx prisma init  Dans le dossier Le fichier &amp;lt;code&amp;gt;schema.prisma&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt; gener... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
npm create svelte@latest silver-events&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Choisis &amp;lt;code&amp;gt;Skeleton project&amp;lt;/code&amp;gt; pour une configuration minimale.&lt;br /&gt;
* Sélectionne &amp;lt;code&amp;gt;Yes&amp;lt;/code&amp;gt; pour ajouter TypeScript.&lt;br /&gt;
* Sélectionne &amp;lt;code&amp;gt;Yes&amp;lt;/code&amp;gt; pour ESLint et Prettier et Vitest&lt;br /&gt;
&lt;br /&gt;
npm install&lt;br /&gt;
&lt;br /&gt;
npm run dev&lt;br /&gt;
&lt;br /&gt;
npm install @prisma/client&lt;br /&gt;
&lt;br /&gt;
npm install -D prisma&lt;br /&gt;
&lt;br /&gt;
npx prisma init&lt;br /&gt;
&lt;br /&gt;
Dans le dossier Le fichier &amp;lt;code&amp;gt;schema.prisma&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
generator client {&lt;br /&gt;
  provider = &amp;quot;prisma-client-js&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
datasource db {&lt;br /&gt;
  provider = &amp;quot;mysql&amp;quot; &lt;br /&gt;
  url      = env(&amp;quot;DATABASE_URL&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans le .env, paramétrer la base de donnée :&lt;br /&gt;
&lt;br /&gt;
DATABASE_URL=&amp;quot;file:./dev.db&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Lancer la migration pour vérifier la connexion : &lt;br /&gt;
&lt;br /&gt;
npx prisma migrate dev --name init&lt;br /&gt;
&lt;br /&gt;
Crée un fichier &amp;lt;code&amp;gt;prisma.ts&amp;lt;/code&amp;gt; dans &amp;lt;code&amp;gt;src/lib&amp;lt;/code&amp;gt; pour initialiser Prisma :&amp;lt;syntaxhighlight lang=&amp;quot;ts&amp;quot;&amp;gt;&lt;br /&gt;
import { PrismaClient } from '@prisma/client';&lt;br /&gt;
&lt;br /&gt;
const prisma = new PrismaClient();&lt;br /&gt;
&lt;br /&gt;
export default prisma;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Setup_TastyIgniter&amp;diff=67</id>
		<title>Setup TastyIgniter</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Setup_TastyIgniter&amp;diff=67"/>
		<updated>2024-07-20T16:32:56Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Choisir la V4 sur Github&lt;br /&gt;
# La base de donnée si elle pose des problèmes de longueur de clé, voir [[Laravel : Corriger l'erreur Syntax error or access violation: 1071 La clé est trop longue. Longueur maximale: 1000]]&lt;br /&gt;
# Dans la base de donnée, il faut s'assurer que dans la table themes l'attribut data est bien encodé en utf8mb4_unicode_ci.&lt;br /&gt;
#S'assurer que dans le .env la variable APP_URL contient bien le nom de domaine absolu afin d'éviter des problèmes d'affichage d'images et autres&lt;br /&gt;
#Parfois il faut toucher au parfeu (réduire les règles ou les paramétrer afin) sur le serveur et égalament au base_url de php (que j'ai set à none)&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Setup_TastyIgniter&amp;diff=66</id>
		<title>Setup TastyIgniter</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Setup_TastyIgniter&amp;diff=66"/>
		<updated>2024-07-20T16:30:14Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « # Choisir la V4 sur Github # La base de donnée si elle pose des problèmes de longueur de clé, voir Laravel : Corriger l'erreur Syntax error or access violation: 1071 La clé est trop longue. Longueur maximale: 1000 # Dans la base de donnée, il faut s'assurer que dans la table themes l'attribut data est bien encodé en utf8mb4_unicode_ci. # »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Choisir la V4 sur Github&lt;br /&gt;
# La base de donnée si elle pose des problèmes de longueur de clé, voir [[Laravel : Corriger l'erreur Syntax error or access violation: 1071 La clé est trop longue. Longueur maximale: 1000]]&lt;br /&gt;
# Dans la base de donnée, il faut s'assurer que dans la table themes l'attribut data est bien encodé en utf8mb4_unicode_ci.&lt;br /&gt;
#&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:Laravel&amp;diff=65</id>
		<title>Catégorie:Laravel</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:Laravel&amp;diff=65"/>
		<updated>2024-07-19T18:59:07Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutos Laravel ==&lt;br /&gt;
[[Mise en place des rôles sur Laravel]]&lt;br /&gt;
&lt;br /&gt;
[[Mise en place de l'authentification sur Laravel]]&lt;br /&gt;
&lt;br /&gt;
[[Mettre en place une base de donnée locale sqlite pour Laravel]]&lt;br /&gt;
&lt;br /&gt;
[[Déployer une application Laravel]]&lt;br /&gt;
&lt;br /&gt;
[[Génération de QRCode Laravel|Génération de QRCode Laravel — Gandal (abdoulaye-diallo.com)]]&lt;br /&gt;
&lt;br /&gt;
[[Laravel : Corriger l'erreur Syntax error or access violation: 1071 La clé est trop longue. Longueur maximale: 1000|Laravel : Corriger l'erreur Syntax error or access violation: 1071 La clé est trop longue. Longueur maximale: 1000 — Gandal (abdoulaye-diallo.com)]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Laravel_:_Corriger_l%27erreur_Syntax_error_or_access_violation:_1071_La_cl%C3%A9_est_trop_longue._Longueur_maximale:_1000&amp;diff=64</id>
		<title>Laravel : Corriger l'erreur Syntax error or access violation: 1071 La clé est trop longue. Longueur maximale: 1000</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Laravel_:_Corriger_l%27erreur_Syntax_error_or_access_violation:_1071_La_cl%C3%A9_est_trop_longue._Longueur_maximale:_1000&amp;diff=64"/>
		<updated>2024-07-19T18:58:41Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « Depuis Laravel 5.4, un changement au jeu de caractères par défaut de la base de données (utf8mb4 qui inclut le support pour le stockage des emojis) risque de vous poser quelques problèmes lors de l'installation de votre BDD MySQL ou MariaDB.  Ce soucis n'affecte que les nouvelles applications avec une version de MySQL inférieure à v5.7.7.  Vous allez rencontrer cette erreur lorsque vous essayez d'exécuter des migrations :  &amp;lt;code&amp;gt;[Illuminate\Database\QueryE... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Depuis Laravel 5.4, un changement au jeu de caractères par défaut de la base de données (utf8mb4 qui inclut le support pour le stockage des emojis) risque de vous poser quelques problèmes lors de l'installation de votre BDD MySQL ou MariaDB.&lt;br /&gt;
&lt;br /&gt;
Ce soucis n'affecte que les nouvelles applications avec une version de MySQL inférieure à v5.7.7.&lt;br /&gt;
&lt;br /&gt;
Vous allez rencontrer cette erreur lorsque vous essayez d'exécuter des migrations :&lt;br /&gt;
 &amp;lt;code&amp;gt;[Illuminate\Database\QueryException]   &lt;br /&gt;
 SQLSTATE[42000]: Syntax error or access violation: 1071 La clé est trop longue. Longueur maximale: 1000 (SQL: alter table `users` add unique `users_email_unique`(`email`))&amp;lt;/code&amp;gt;&lt;br /&gt;
Pour corriger ce problème, vous avez deux solutions: Mettre MySQL à jour (recommandé) ou modifier votre fichier AppServiceProvider.php et définir une longueur de chaîne par défaut dans la méthode boot:&lt;br /&gt;
&lt;br /&gt;
app/Providers/AppServiceProvider.php&lt;br /&gt;
 &amp;lt;code&amp;gt;// Inclure la facade &amp;quot;Schema&amp;quot;&lt;br /&gt;
 use Illuminate\Support\Facades\Schema;&lt;br /&gt;
 &lt;br /&gt;
 // dans la méthode boot(), inclure la ligne suivante&lt;br /&gt;
 public function boot()&lt;br /&gt;
 {&lt;br /&gt;
     Schema::defaultStringLength(191);&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
Après cela, tout devrait fonctionner normalement.&lt;br /&gt;
&lt;br /&gt;
N'oubliez pas de vider votre base de donnée avant de refaire la migration, sans quoi vous vous retrouverez avec une erreur.&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=G%C3%A9n%C3%A9ration_de_QRCode_Laravel&amp;diff=63</id>
		<title>Génération de QRCode Laravel</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=G%C3%A9n%C3%A9ration_de_QRCode_Laravel&amp;diff=63"/>
		<updated>2024-06-11T15:52:03Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Version plus complète : &amp;lt;nowiki&amp;gt;https://github.com/endroid/qr-code&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SimpleSoftwareIO/simple-qrcode: An easy-to-use PHP QrCode generator with first-party support for Laravel. (github.com)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/* Un exemple*/&lt;br /&gt;
private function generateQrCode($text)&lt;br /&gt;
    {&lt;br /&gt;
        $result = Builder::create()&lt;br /&gt;
            -&amp;gt;writer(new PngWriter())&lt;br /&gt;
            -&amp;gt;writerOptions([])&lt;br /&gt;
            -&amp;gt;data($text)&lt;br /&gt;
            -&amp;gt;encoding(new Encoding('UTF-8'))&lt;br /&gt;
            -&amp;gt;errorCorrectionLevel(ErrorCorrectionLevel::High)&lt;br /&gt;
            -&amp;gt;size(300)&lt;br /&gt;
            -&amp;gt;margin(10)&lt;br /&gt;
            -&amp;gt;roundBlockSizeMode(RoundBlockSizeMode::Margin)&lt;br /&gt;
            -&amp;gt;foregroundColor(new Color(0, 0, 0))&lt;br /&gt;
            -&amp;gt;backgroundColor(new Color(255, 255, 255))&lt;br /&gt;
            -&amp;gt;logoPath(&amp;quot;https://www.mouleagaufres.com/wp-content/uploads/2022/03/logoMAG-blanc.png&amp;quot;)&lt;br /&gt;
            -&amp;gt;logoResizeToWidth(50)&lt;br /&gt;
            -&amp;gt;logoPunchoutBackground(true)&lt;br /&gt;
            -&amp;gt;validateResult(false)&lt;br /&gt;
            -&amp;gt;build();&lt;br /&gt;
&lt;br /&gt;
        return $result-&amp;gt;getString();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=G%C3%A9n%C3%A9ration_de_QRCode_Laravel&amp;diff=62</id>
		<title>Génération de QRCode Laravel</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=G%C3%A9n%C3%A9ration_de_QRCode_Laravel&amp;diff=62"/>
		<updated>2024-06-11T15:40:21Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Version plus complète : &amp;lt;nowiki&amp;gt;https://github.com/endroid/qr-code&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SimpleSoftwareIO/simple-qrcode: An easy-to-use PHP QrCode generator with first-party support for Laravel. (github.com)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
namespace App\Http\Controllers;&lt;br /&gt;
&lt;br /&gt;
use App\Mail\TicketPurchased;&lt;br /&gt;
use App\Models\Participant;&lt;br /&gt;
use App\Models\Ticket;&lt;br /&gt;
use Illuminate\Http\Request;&lt;br /&gt;
use Illuminate\Http\JsonResponse;&lt;br /&gt;
use Illuminate\Support\Facades\Mail;&lt;br /&gt;
use SimpleSoftwareIO\QrCode\Facades\QrCode;&lt;br /&gt;
&lt;br /&gt;
class TicketController extends Controller&lt;br /&gt;
{&lt;br /&gt;
    /**&lt;br /&gt;
     * Purchase a ticket&lt;br /&gt;
     *&lt;br /&gt;
     * @param Request $request&lt;br /&gt;
     * @response array{message: &amp;quot;Ticket purchased successfully and email sent.&amp;quot;}&lt;br /&gt;
     * @return JsonResponse&lt;br /&gt;
     */&lt;br /&gt;
    public function purchase(Request $request)&lt;br /&gt;
    {&lt;br /&gt;
        // Generate a unique code for the ticket&lt;br /&gt;
        $ticketCode = uniqid();&lt;br /&gt;
&lt;br /&gt;
        // Generate a link to validate the ticket&lt;br /&gt;
        $qrCodeUrl = route('validate.ticket', ['code' =&amp;gt; $ticketCode]);&lt;br /&gt;
        &lt;br /&gt;
        // Generate QR code with the link&lt;br /&gt;
        $qrCode = QrCode::format('png')-&amp;gt;size(200)-&amp;gt;generate($qrCodeUrl);&lt;br /&gt;
&lt;br /&gt;
        // Create ticket&lt;br /&gt;
        $ticket = Ticket::create([&lt;br /&gt;
            'type' =&amp;gt; $request-&amp;gt;type,&lt;br /&gt;
            'price' =&amp;gt; $request-&amp;gt;price,&lt;br /&gt;
            'code' =&amp;gt; $ticketCode,&lt;br /&gt;
            'qr_code' =&amp;gt; base64_encode($qrCode),&lt;br /&gt;
            'status' =&amp;gt; 'unvalidated',&lt;br /&gt;
            'event_id' =&amp;gt; $request-&amp;gt;event_id,&lt;br /&gt;
            'participant_id' =&amp;gt; $request-&amp;gt;participant_id,&lt;br /&gt;
        ]);&lt;br /&gt;
&lt;br /&gt;
        // Send email with QR code&lt;br /&gt;
        $participant = Participant::find($request-&amp;gt;participant_id);&lt;br /&gt;
        Mail::to($participant-&amp;gt;email)-&amp;gt;send(new TicketPurchased($ticket));&lt;br /&gt;
&lt;br /&gt;
        return response()-&amp;gt;json(['message' =&amp;gt; 'Ticket purchased successfully and email sent.', 'ticketCode' =&amp;gt; $ticketCode, 'qrCode' =&amp;gt; $qrCodeUrl], 201);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:Laravel&amp;diff=61</id>
		<title>Catégorie:Laravel</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:Laravel&amp;diff=61"/>
		<updated>2024-06-11T15:36:00Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutos Laravel ==&lt;br /&gt;
[[Mise en place des rôles sur Laravel]]&lt;br /&gt;
&lt;br /&gt;
[[Mise en place de l'authentification sur Laravel]]&lt;br /&gt;
&lt;br /&gt;
[[Mettre en place une base de donnée locale sqlite pour Laravel]]&lt;br /&gt;
&lt;br /&gt;
[[Déployer une application Laravel]]&lt;br /&gt;
&lt;br /&gt;
[[Génération de QRCode Laravel|Génération de QRCode Laravel — Gandal (abdoulaye-diallo.com)]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=G%C3%A9n%C3%A9ration_de_QRCode_Laravel&amp;diff=60</id>
		<title>Génération de QRCode Laravel</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=G%C3%A9n%C3%A9ration_de_QRCode_Laravel&amp;diff=60"/>
		<updated>2024-06-11T15:35:42Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « &amp;lt;nowiki&amp;gt;https://github.com/endroid/qr-code&amp;lt;/nowiki&amp;gt;  SimpleSoftwareIO/simple-qrcode: An easy-to-use PHP QrCode generator with first-party support for Laravel. (github.com)  &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt; &amp;lt;?php  namespace App\Http\Controllers;  use App\Mail\TicketPurchased; use App\Models\Participant; use App\Models\Ticket; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Mail; use SimpleSoftwareIO\QrCode\Facades\QrCode;... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;https://github.com/endroid/qr-code&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SimpleSoftwareIO/simple-qrcode: An easy-to-use PHP QrCode generator with first-party support for Laravel. (github.com)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
namespace App\Http\Controllers;&lt;br /&gt;
&lt;br /&gt;
use App\Mail\TicketPurchased;&lt;br /&gt;
use App\Models\Participant;&lt;br /&gt;
use App\Models\Ticket;&lt;br /&gt;
use Illuminate\Http\Request;&lt;br /&gt;
use Illuminate\Http\JsonResponse;&lt;br /&gt;
use Illuminate\Support\Facades\Mail;&lt;br /&gt;
use SimpleSoftwareIO\QrCode\Facades\QrCode;&lt;br /&gt;
&lt;br /&gt;
class TicketController extends Controller&lt;br /&gt;
{&lt;br /&gt;
    /**&lt;br /&gt;
     * Purchase a ticket&lt;br /&gt;
     *&lt;br /&gt;
     * @param Request $request&lt;br /&gt;
     * @response array{message: &amp;quot;Ticket purchased successfully and email sent.&amp;quot;}&lt;br /&gt;
     * @return JsonResponse&lt;br /&gt;
     */&lt;br /&gt;
    public function purchase(Request $request)&lt;br /&gt;
    {&lt;br /&gt;
        // Generate a unique code for the ticket&lt;br /&gt;
        $ticketCode = uniqid();&lt;br /&gt;
&lt;br /&gt;
        // Generate a link to validate the ticket&lt;br /&gt;
        $qrCodeUrl = route('validate.ticket', ['code' =&amp;gt; $ticketCode]);&lt;br /&gt;
        &lt;br /&gt;
        // Generate QR code with the link&lt;br /&gt;
        $qrCode = QrCode::format('png')-&amp;gt;size(200)-&amp;gt;generate($qrCodeUrl);&lt;br /&gt;
&lt;br /&gt;
        // Create ticket&lt;br /&gt;
        $ticket = Ticket::create([&lt;br /&gt;
            'type' =&amp;gt; $request-&amp;gt;type,&lt;br /&gt;
            'price' =&amp;gt; $request-&amp;gt;price,&lt;br /&gt;
            'code' =&amp;gt; $ticketCode,&lt;br /&gt;
            'qr_code' =&amp;gt; base64_encode($qrCode),&lt;br /&gt;
            'status' =&amp;gt; 'unvalidated',&lt;br /&gt;
            'event_id' =&amp;gt; $request-&amp;gt;event_id,&lt;br /&gt;
            'participant_id' =&amp;gt; $request-&amp;gt;participant_id,&lt;br /&gt;
        ]);&lt;br /&gt;
&lt;br /&gt;
        // Send email with QR code&lt;br /&gt;
        $participant = Participant::find($request-&amp;gt;participant_id);&lt;br /&gt;
        Mail::to($participant-&amp;gt;email)-&amp;gt;send(new TicketPurchased($ticket));&lt;br /&gt;
&lt;br /&gt;
        return response()-&amp;gt;json(['message' =&amp;gt; 'Ticket purchased successfully and email sent.', 'ticketCode' =&amp;gt; $ticketCode, 'qrCode' =&amp;gt; $qrCodeUrl], 201);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:React&amp;diff=59</id>
		<title>Catégorie:React</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:React&amp;diff=59"/>
		<updated>2024-06-10T08:21:01Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Routing Vues.js et React.js Serveur Apache|Routing Vues.js et React.js Serveur Apache — Gandal (abdoulaye-diallo.com)]]&lt;br /&gt;
&lt;br /&gt;
[[Résolutions d'erreurs CORS|Résolutions d'erreurs CORS — Gandal (abdoulaye-diallo.com)]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:React&amp;diff=58</id>
		<title>Catégorie:React</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:React&amp;diff=58"/>
		<updated>2024-06-10T08:20:40Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « Routing Vues.js et React.js Serveur Apache — Gandal (abdoulaye-diallo.com) »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Routing Vues.js et React.js Serveur Apache|Routing Vues.js et React.js Serveur Apache — Gandal (abdoulaye-diallo.com)]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:Vue.js&amp;diff=57</id>
		<title>Catégorie:Vue.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:Vue.js&amp;diff=57"/>
		<updated>2024-06-10T08:20:31Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « Routing Vues.js et React.js Serveur Apache — Gandal (abdoulaye-diallo.com) »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Routing Vues.js et React.js Serveur Apache|Routing Vues.js et React.js Serveur Apache — Gandal (abdoulaye-diallo.com)]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Routing_Vues.js_et_React.js_Serveur_Apache&amp;diff=56</id>
		<title>Routing Vues.js et React.js Serveur Apache</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Routing_Vues.js_et_React.js_Serveur_Apache&amp;diff=56"/>
		<updated>2024-06-10T08:20:11Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « Par défaut, Apache ne sait pas comment gérer les routes de votre application VueJS ou ReactJS et renvoie une erreur 404 lorsque vous essayez d'accéder directement à une route autre que la page d'accueil. Pour résoudre ce problème, vous devez configurer votre serveur Apache pour qu'il redirige toutes les requêtes vers le fichier &amp;lt;code&amp;gt;index.html&amp;lt;/code&amp;gt; de votre application VueJS. Voici comment vous pouvez procéder :  # '''Créer un fichier .htaccess''' : C... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Par défaut, Apache ne sait pas comment gérer les routes de votre application VueJS ou ReactJS et renvoie une erreur 404 lorsque vous essayez d'accéder directement à une route autre que la page d'accueil. Pour résoudre ce problème, vous devez configurer votre serveur Apache pour qu'il redirige toutes les requêtes vers le fichier &amp;lt;code&amp;gt;index.html&amp;lt;/code&amp;gt; de votre application VueJS. Voici comment vous pouvez procéder :&lt;br /&gt;
&lt;br /&gt;
# '''Créer un fichier .htaccess''' : Ce fichier permet de configurer Apache pour rediriger toutes les requêtes vers &amp;lt;code&amp;gt;index.html&amp;lt;/code&amp;gt;, sauf celles visant des fichiers ou des répertoires existants.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;IfModule mod_rewrite.c&amp;gt;&lt;br /&gt;
    RewriteEngine On&lt;br /&gt;
    RewriteBase /&lt;br /&gt;
    RewriteRule ^index\.html$ - [L]&lt;br /&gt;
    RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
    RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
    RewriteRule . /index.html [L]&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''Placer le fichier .htaccess à la racine de votre projet VueJS''' : À côté de votre &amp;lt;code&amp;gt;index.html&amp;lt;/code&amp;gt;.&lt;br /&gt;
# '''Ajouter les directives nécessaires dans le fichier .htaccess''' : (pas nécessaire sur Plesk)&lt;br /&gt;
&lt;br /&gt;
Ces directives font les choses suivantes :&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;RewriteEngine On&amp;lt;/code&amp;gt; : Active le moteur de réécriture.&lt;br /&gt;
* &amp;lt;code&amp;gt;RewriteBase /&amp;lt;/code&amp;gt; : Définit la base de l'URL utilisée pour la réécriture.&lt;br /&gt;
* &amp;lt;code&amp;gt;RewriteRule ^index\.html$ - [L]&amp;lt;/code&amp;gt; : Si l'URL demandée est &amp;lt;code&amp;gt;index.html&amp;lt;/code&amp;gt;, ne rien faire (le laisser tel quel).&lt;br /&gt;
* &amp;lt;code&amp;gt;RewriteCond %{REQUEST_FILENAME} !-f&amp;lt;/code&amp;gt; : Si le fichier demandé n'existe pas...&lt;br /&gt;
* &amp;lt;code&amp;gt;RewriteCond %{REQUEST_FILENAME} !-d&amp;lt;/code&amp;gt; : ... et si le répertoire demandé n'existe pas...&lt;br /&gt;
* &amp;lt;code&amp;gt;RewriteRule . /index.html [L]&amp;lt;/code&amp;gt; : ... alors rediriger la demande vers &amp;lt;code&amp;gt;index.html&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
# '''Activer le module mod_rewrite d’Apache''' (si ce n'est pas déjà fait) :  Pour cela, vous devrez vous assurer que le module &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt; est activé. Vous pouvez le faire via l'interface de gestion de Plesk ou en accédant à la configuration Apache si vous avez les privilèges nécessaires. Voici une commande que vous pouvez utiliser si vous avez accès au terminal :&lt;br /&gt;
&lt;br /&gt;
Une fois ces étapes terminées, Apache redirigera toutes les requêtes vers &amp;lt;code&amp;gt;index.html&amp;lt;/code&amp;gt;, permettant à votre application VueJS de gérer les routes côté client comme prévu.&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=MediaWiki:Sidebar&amp;diff=55</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=MediaWiki:Sidebar&amp;diff=55"/>
		<updated>2024-06-10T08:15:20Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* Catégories&lt;br /&gt;
** :Catégorie:Apache|Apache&lt;br /&gt;
** :Catégorie:Bootstrap|Bootstrap&lt;br /&gt;
** :Catégorie:Centos|Centos&lt;br /&gt;
** :Catégorie:Drupal|Drupal&lt;br /&gt;
** :Catégorie:Git|Git&lt;br /&gt;
** :Catégorie:Github|Github&lt;br /&gt;
** :Catégorie:Laravel|Laravel&lt;br /&gt;
** :Catégorie:Linux|Linux&lt;br /&gt;
** :Catégorie:Mediawiki|Mediawiki&lt;br /&gt;
** :Catégorie:MQL5|MQL5&lt;br /&gt;
** :Catégorie:MySQL|MySQL&lt;br /&gt;
** :Catégorie:NextJs|NextJS&lt;br /&gt;
** :Catégorie:Nodejs|Nodejs&lt;br /&gt;
** :Catégorie:Plesk|Plesk&lt;br /&gt;
** :Catégorie:React|React&lt;br /&gt;
** :Catégorie:Rsync|Rsync&lt;br /&gt;
** :Catégorie:Symfony|Symfony&lt;br /&gt;
** :Catégorie:Twig|Twig&lt;br /&gt;
** :Catégorie:Vue.js|Vue.js&lt;br /&gt;
** :Catégorie:Wordpress|Wordpress&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_en_place_une_CI/CD&amp;diff=54</id>
		<title>Mettre en place une CI/CD</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_en_place_une_CI/CD&amp;diff=54"/>
		<updated>2024-05-28T15:41:22Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : /* Exemple commenté d'un workflow de déploiement continue Laravel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Prérequis ==&lt;br /&gt;
Avant de suivre ce Tuto, en particulier pour la partie déploiement, s'assurer d'avoir cloner le repo sur le serveur de déploiement.&lt;br /&gt;
&lt;br /&gt;
== Le CI/CD en développement ==&lt;br /&gt;
Le CI/CD, ou Intégration Continue/Livraison Continue, est une pratique logicielle qui vise à automatiser le processus de développement et de déploiement logiciel. Il s'agit d'une approche DevOps qui permet d'améliorer la qualité, la rapidité et la fiabilité du développement logiciel.&lt;br /&gt;
&lt;br /&gt;
== Les étapes ==&lt;br /&gt;
&lt;br /&gt;
# Intégration Continue (CI) :&lt;br /&gt;
#* La CI consiste à intégrer fréquemment les modifications de code dans un référentiel partagé.&lt;br /&gt;
#* Les développeurs fusionnent régulièrement leur code dans une branche commune, déclenchant des processus automatisés qui vérifient la qualité du code.&lt;br /&gt;
# Tests Automatisés :&lt;br /&gt;
#* Les systèmes CI exécutent des tests automatisés pour s'assurer que les nouvelles modifications n'ont pas introduit de régressions.&lt;br /&gt;
#* Les tests peuvent inclure des tests unitaires, des tests d'intégration et d'autres formes de tests automatisés.&lt;br /&gt;
# Déploiement Continu (CD) :&lt;br /&gt;
#* L'Implémentation Continue (ou Déploiement Continu) étend la CI en automatisant la livraison du logiciel.&lt;br /&gt;
#* Le déploiement continu implique la mise en œuvre automatisée des modifications validées dans l'environnement de production.&lt;br /&gt;
&lt;br /&gt;
== Créer un fichier de workflow ==&lt;br /&gt;
Un fichier de workflow est le script qui sera exécuté par Github lors d'un évènement définis commpe un push sur la branch main ou la complétion d'un autre workflow.&lt;br /&gt;
&lt;br /&gt;
C'est généralement un ou plusieurs fichies qui doivent être placés dans le dossier '''&amp;lt;code&amp;gt;.github/workflows/&amp;lt;/code&amp;gt;''' (par exemple &amp;lt;code&amp;gt;'''.github/workflows/ci.yam'''l&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Exemple commenté d'un workflow d'intégration et de test continue Laravel ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# Nom du workflow&lt;br /&gt;
name: Laravel CI&lt;br /&gt;
&lt;br /&gt;
# Déclencheurs pour le workflow&lt;br /&gt;
on:&lt;br /&gt;
  push:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]   # Déclencher lorsqu'un push est effectué sur la branche principale&lt;br /&gt;
  pull_request:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]   # Déclencher lorsqu'une pull request est ouverte sur la branche principale&lt;br /&gt;
&lt;br /&gt;
# Définition des jobs&lt;br /&gt;
jobs:&lt;br /&gt;
  laravel-tests:&lt;br /&gt;
    runs-on: ubuntu-latest   # Utiliser l'image Ubuntu la plus récente comme environnement d'exécution&lt;br /&gt;
&lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: shivammathur/setup-php@v2   # Utiliser l'action pour configurer PHP&lt;br /&gt;
        with:&lt;br /&gt;
          php-version: '8.1'   # Spécifier la version de PHP à utiliser&lt;br /&gt;
      - uses: actions/checkout@v2   # Utiliser l'action pour effectuer un checkout du code&lt;br /&gt;
&lt;br /&gt;
      - name: Copy .env   # Étape pour copier le fichier .env s'il n'existe pas&lt;br /&gt;
        run: php -r &amp;quot;file_exists('.env') || copy('.env.example', '.env');&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      - name: Install Dependencies   # Étape pour installer les dépendances Composer&lt;br /&gt;
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist&lt;br /&gt;
&lt;br /&gt;
      - name: Generate key   # Étape pour générer la clé d'application Laravel&lt;br /&gt;
        run: php artisan key:generate&lt;br /&gt;
&lt;br /&gt;
      - name: Directory Permissions   # Étape pour définir les permissions sur les répertoires&lt;br /&gt;
        run: chmod -R 777 storage bootstrap/cache&lt;br /&gt;
&lt;br /&gt;
      - name: Create Database   # Étape pour créer une base de données SQLite&lt;br /&gt;
        run: |&lt;br /&gt;
          mkdir -p database&lt;br /&gt;
          touch database/database.sqlite&lt;br /&gt;
&lt;br /&gt;
      - name: Execute tests (Unit and Feature tests) via PHPUnit   # Étape pour exécuter les tests PHPUnit&lt;br /&gt;
        env:&lt;br /&gt;
          DB_CONNECTION: sqlite&lt;br /&gt;
          DB_DATABASE: database/database.sqlite   # Configurer la base de données pour les tests&lt;br /&gt;
        run: vendor/bin/phpunit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;En incluant ce fichier dans notre système de fichiers, lors du push Github va effectuer les installations nécessaires pour lancer une version de test du projet et également exécuter tous les test unitaires et de features compris dans le projet.&lt;br /&gt;
&lt;br /&gt;
Le déploiement demande un peu plus travail :&lt;br /&gt;
&lt;br /&gt;
=== Exemple commenté d'un workflow de déploiement continue Laravel ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Nom du workflow&lt;br /&gt;
name: Laravel CD&lt;br /&gt;
&lt;br /&gt;
# Déclencheur pour le workflow : déclenche lorsqu'une exécution du workflow &amp;quot;Laravel CI&amp;quot; est terminée&lt;br /&gt;
on:&lt;br /&gt;
  workflow_run:&lt;br /&gt;
    workflows: [&amp;quot;Laravel CI&amp;quot;]&lt;br /&gt;
    types:&lt;br /&gt;
      - completed&lt;br /&gt;
&lt;br /&gt;
# Définition des jobs&lt;br /&gt;
jobs:&lt;br /&gt;
  deploy:&lt;br /&gt;
    runs-on: ubuntu-latest   # Utiliser l'image Ubuntu la plus récente comme environnement d'exécution&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      name: 'MyPlesk'   # Nom de l'environnement de déploiement&lt;br /&gt;
&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Deploy to Server   # Étape pour déployer sur le serveur&lt;br /&gt;
        uses: appleboy/ssh-action@master   # Utiliser l'action SSH pour effectuer le déploiement&lt;br /&gt;
        with:&lt;br /&gt;
          host: ${{ secrets.SERVER_HOST }}   # Adresse IP ou nom d'hôte du serveur&lt;br /&gt;
          username: ${{ secrets.SERVER_USERNAME }}   # Nom d'utilisateur pour la connexion SSH&lt;br /&gt;
          key: ${{ secrets.SSH_PRIVATE_KEY }}   # Clé privée SSH pour l'authentification&lt;br /&gt;
          script: |&lt;br /&gt;
            cd /var/www/vhosts/abdoulaye-diallo.com/api.abdoulaye-diallo.com/Cv_back/   # Se déplacer vers le répertoire du projet&lt;br /&gt;
            git pull origin main   # Mettre à jour le code depuis la branche principale&lt;br /&gt;
            php artisan migrate   # Exécuter les migrations de base de données&lt;br /&gt;
            composer update   # Mettre à jour les dépendances Composer (si nécessaire)&lt;br /&gt;
            composer install   # Installer les dépendances Composer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;A savoir, sur Plesk il arrive souvent que la commande php n'est pas trouvée, il faut alors aller sur le terminal du domaine, lancer la commande &amp;lt;code&amp;gt;which php&amp;lt;/code&amp;gt;  pour avoir le chemin d'accès au script php, puis une fois le chemin otenu, le spécifier dans le fichier de déploiment comme par exemple : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;php artisan migrate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
devient :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/var/www/vhosts/quizzical-bassi.91-212-26-79.plesk.page/.phpenv/shims/php artisan migrate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple de workflow CI/CD pour un projet React en un seul fichier : ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
name: React CICD&lt;br /&gt;
&lt;br /&gt;
on:&lt;br /&gt;
  push:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]&lt;br /&gt;
  pull_request:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  build:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        node-version: [18.x]&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Checkout Repository&lt;br /&gt;
        uses: actions/checkout@v2&lt;br /&gt;
      - name: Use Node.js ${{ matrix.node-version }}&lt;br /&gt;
        uses: actions/setup-node@v3&lt;br /&gt;
        with:&lt;br /&gt;
          node-version: ${{ matrix.node-version }}&lt;br /&gt;
          cache: 'npm'&lt;br /&gt;
      - name: Install Dependencies&lt;br /&gt;
        run: npm ci&lt;br /&gt;
      - name: Build Project&lt;br /&gt;
        run: npm run build --if-present&lt;br /&gt;
      - name: Run Tests&lt;br /&gt;
        run: npm test --if-present&lt;br /&gt;
&lt;br /&gt;
  deploy:&lt;br /&gt;
    needs: build&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    environment:&lt;br /&gt;
      name: &amp;quot;MyPlesk&amp;quot;&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Checkout Repository&lt;br /&gt;
        uses: actions/checkout@v2&lt;br /&gt;
      - name: Deploy to Server&lt;br /&gt;
        uses: appleboy/ssh-action@master&lt;br /&gt;
        with:&lt;br /&gt;
          host: ${{ secrets.SERVER_HOST }}&lt;br /&gt;
          username: ${{ secrets.SERVER_USERNAME }}&lt;br /&gt;
          key: ${{ secrets.SSH_PRIVATE_KEY }}&lt;br /&gt;
          script: |&lt;br /&gt;
            cd /var/www/vhosts/abdoulaye-diallo.com/httpdocs/Front/&lt;br /&gt;
            git pull origin main&lt;br /&gt;
            npm ci --production&lt;br /&gt;
            npm run build&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Créer un environnement et des secrets sur Github ==&lt;br /&gt;
Comme on peut le voir dans ce code, on doit se connecter en SSH au serveur de production afin de déployer les MAJ. Pour cela et pour des raisons de sécurités, on stock les informations dans les secrets de GitHub (voir https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) . Ici en l'occurrence nous avons créés des secrets dans un environnement nommé MyPlesk sur GitHub (MAJ : les environnements Github semblent avoir disparus maintenant) :&lt;br /&gt;
[[Fichier:Github Secrets.png|centré|sans_cadre|1071x1071px]]&lt;br /&gt;
=== Création des clés ssh ===&lt;br /&gt;
[[Fichier:Plesk ssh keys.png|vignette]]&lt;br /&gt;
La connexion au serveur distant se fait via une clé ssh (d'où le secrets.SSH_PRIVATE_KEY à la ligne 25), pour cela nous allons ouvrir un terminal en local par exemple et lancer la commande de génération de clé ssh : &amp;lt;code&amp;gt;ssh-keygen -t rsa -b 4096 -C &amp;quot;monmail@email.com&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Il faudra ensuite copier la clé privée dans le secret de Github ( secrets.SSH_PRIVATE_KEY) et ajouter la clé publique parmis les clés SSH autorisés du serveur distant (sur Plesk, aller dans l'abonnement concerné et cliquer sur SSH KEYS).&lt;br /&gt;
&lt;br /&gt;
Il faut également renseigner le nom de l'utilisateur qui a accès au serveur.&lt;br /&gt;
&lt;br /&gt;
[[index.php?title=Catégorie:Github]]  &lt;br /&gt;
[[index.php?title=Catégorie:Git]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_en_place_une_CI/CD&amp;diff=53</id>
		<title>Mettre en place une CI/CD</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_en_place_une_CI/CD&amp;diff=53"/>
		<updated>2024-05-28T13:48:00Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : /* Créer un environnement et des secrets sur Github */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Prérequis ==&lt;br /&gt;
Avant de suivre ce Tuto, en particulier pour la partie déploiement, s'assurer d'avoir cloner le repo sur le serveur de déploiement.&lt;br /&gt;
&lt;br /&gt;
== Le CI/CD en développement ==&lt;br /&gt;
Le CI/CD, ou Intégration Continue/Livraison Continue, est une pratique logicielle qui vise à automatiser le processus de développement et de déploiement logiciel. Il s'agit d'une approche DevOps qui permet d'améliorer la qualité, la rapidité et la fiabilité du développement logiciel.&lt;br /&gt;
&lt;br /&gt;
== Les étapes ==&lt;br /&gt;
&lt;br /&gt;
# Intégration Continue (CI) :&lt;br /&gt;
#* La CI consiste à intégrer fréquemment les modifications de code dans un référentiel partagé.&lt;br /&gt;
#* Les développeurs fusionnent régulièrement leur code dans une branche commune, déclenchant des processus automatisés qui vérifient la qualité du code.&lt;br /&gt;
# Tests Automatisés :&lt;br /&gt;
#* Les systèmes CI exécutent des tests automatisés pour s'assurer que les nouvelles modifications n'ont pas introduit de régressions.&lt;br /&gt;
#* Les tests peuvent inclure des tests unitaires, des tests d'intégration et d'autres formes de tests automatisés.&lt;br /&gt;
# Déploiement Continu (CD) :&lt;br /&gt;
#* L'Implémentation Continue (ou Déploiement Continu) étend la CI en automatisant la livraison du logiciel.&lt;br /&gt;
#* Le déploiement continu implique la mise en œuvre automatisée des modifications validées dans l'environnement de production.&lt;br /&gt;
&lt;br /&gt;
== Créer un fichier de workflow ==&lt;br /&gt;
Un fichier de workflow est le script qui sera exécuté par Github lors d'un évènement définis commpe un push sur la branch main ou la complétion d'un autre workflow.&lt;br /&gt;
&lt;br /&gt;
C'est généralement un ou plusieurs fichies qui doivent être placés dans le dossier '''&amp;lt;code&amp;gt;.github/workflows/&amp;lt;/code&amp;gt;''' (par exemple &amp;lt;code&amp;gt;'''.github/workflows/ci.yam'''l&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Exemple commenté d'un workflow d'intégration et de test continue Laravel ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# Nom du workflow&lt;br /&gt;
name: Laravel CI&lt;br /&gt;
&lt;br /&gt;
# Déclencheurs pour le workflow&lt;br /&gt;
on:&lt;br /&gt;
  push:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]   # Déclencher lorsqu'un push est effectué sur la branche principale&lt;br /&gt;
  pull_request:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]   # Déclencher lorsqu'une pull request est ouverte sur la branche principale&lt;br /&gt;
&lt;br /&gt;
# Définition des jobs&lt;br /&gt;
jobs:&lt;br /&gt;
  laravel-tests:&lt;br /&gt;
    runs-on: ubuntu-latest   # Utiliser l'image Ubuntu la plus récente comme environnement d'exécution&lt;br /&gt;
&lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: shivammathur/setup-php@v2   # Utiliser l'action pour configurer PHP&lt;br /&gt;
        with:&lt;br /&gt;
          php-version: '8.1'   # Spécifier la version de PHP à utiliser&lt;br /&gt;
      - uses: actions/checkout@v2   # Utiliser l'action pour effectuer un checkout du code&lt;br /&gt;
&lt;br /&gt;
      - name: Copy .env   # Étape pour copier le fichier .env s'il n'existe pas&lt;br /&gt;
        run: php -r &amp;quot;file_exists('.env') || copy('.env.example', '.env');&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      - name: Install Dependencies   # Étape pour installer les dépendances Composer&lt;br /&gt;
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist&lt;br /&gt;
&lt;br /&gt;
      - name: Generate key   # Étape pour générer la clé d'application Laravel&lt;br /&gt;
        run: php artisan key:generate&lt;br /&gt;
&lt;br /&gt;
      - name: Directory Permissions   # Étape pour définir les permissions sur les répertoires&lt;br /&gt;
        run: chmod -R 777 storage bootstrap/cache&lt;br /&gt;
&lt;br /&gt;
      - name: Create Database   # Étape pour créer une base de données SQLite&lt;br /&gt;
        run: |&lt;br /&gt;
          mkdir -p database&lt;br /&gt;
          touch database/database.sqlite&lt;br /&gt;
&lt;br /&gt;
      - name: Execute tests (Unit and Feature tests) via PHPUnit   # Étape pour exécuter les tests PHPUnit&lt;br /&gt;
        env:&lt;br /&gt;
          DB_CONNECTION: sqlite&lt;br /&gt;
          DB_DATABASE: database/database.sqlite   # Configurer la base de données pour les tests&lt;br /&gt;
        run: vendor/bin/phpunit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;En incluant ce fichier dans notre système de fichiers, lors du push Github va effectuer les installations nécessaires pour lancer une version de test du projet et également exécuter tous les test unitaires et de features compris dans le projet.&lt;br /&gt;
&lt;br /&gt;
Le déploiement demande un peu plus travail :&lt;br /&gt;
&lt;br /&gt;
=== Exemple commenté d'un workflow de déploiement continue Laravel ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Nom du workflow&lt;br /&gt;
name: Laravel CD&lt;br /&gt;
&lt;br /&gt;
# Déclencheur pour le workflow : déclenche lorsqu'une exécution du workflow &amp;quot;Laravel CI&amp;quot; est terminée&lt;br /&gt;
on:&lt;br /&gt;
  workflow_run:&lt;br /&gt;
    workflows: [&amp;quot;Laravel CI&amp;quot;]&lt;br /&gt;
    types:&lt;br /&gt;
      - completed&lt;br /&gt;
&lt;br /&gt;
# Définition des jobs&lt;br /&gt;
jobs:&lt;br /&gt;
  deploy:&lt;br /&gt;
    runs-on: ubuntu-latest   # Utiliser l'image Ubuntu la plus récente comme environnement d'exécution&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      name: 'MyPlesk'   # Nom de l'environnement de déploiement&lt;br /&gt;
&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Deploy to Server   # Étape pour déployer sur le serveur&lt;br /&gt;
        uses: appleboy/ssh-action@master   # Utiliser l'action SSH pour effectuer le déploiement&lt;br /&gt;
        with:&lt;br /&gt;
          host: ${{ secrets.SERVER_HOST }}   # Adresse IP ou nom d'hôte du serveur&lt;br /&gt;
          username: ${{ secrets.SERVER_USERNAME }}   # Nom d'utilisateur pour la connexion SSH&lt;br /&gt;
          key: ${{ secrets.SSH_PRIVATE_KEY }}   # Clé privée SSH pour l'authentification&lt;br /&gt;
          script: |&lt;br /&gt;
            cd /var/www/vhosts/abdoulaye-diallo.com/api.abdoulaye-diallo.com/Cv_back/   # Se déplacer vers le répertoire du projet&lt;br /&gt;
            git pull origin main   # Mettre à jour le code depuis la branche principale&lt;br /&gt;
            php artisan migrate   # Exécuter les migrations de base de données&lt;br /&gt;
            composer update   # Mettre à jour les dépendances Composer (si nécessaire)&lt;br /&gt;
            composer install   # Installer les dépendances Composer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple de workflow CI/CD pour un projet React en un seul fichier : ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
name: React CICD&lt;br /&gt;
&lt;br /&gt;
on:&lt;br /&gt;
  push:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]&lt;br /&gt;
  pull_request:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  build:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        node-version: [18.x]&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Checkout Repository&lt;br /&gt;
        uses: actions/checkout@v2&lt;br /&gt;
      - name: Use Node.js ${{ matrix.node-version }}&lt;br /&gt;
        uses: actions/setup-node@v3&lt;br /&gt;
        with:&lt;br /&gt;
          node-version: ${{ matrix.node-version }}&lt;br /&gt;
          cache: 'npm'&lt;br /&gt;
      - name: Install Dependencies&lt;br /&gt;
        run: npm ci&lt;br /&gt;
      - name: Build Project&lt;br /&gt;
        run: npm run build --if-present&lt;br /&gt;
      - name: Run Tests&lt;br /&gt;
        run: npm test --if-present&lt;br /&gt;
&lt;br /&gt;
  deploy:&lt;br /&gt;
    needs: build&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    environment:&lt;br /&gt;
      name: &amp;quot;MyPlesk&amp;quot;&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Checkout Repository&lt;br /&gt;
        uses: actions/checkout@v2&lt;br /&gt;
      - name: Deploy to Server&lt;br /&gt;
        uses: appleboy/ssh-action@master&lt;br /&gt;
        with:&lt;br /&gt;
          host: ${{ secrets.SERVER_HOST }}&lt;br /&gt;
          username: ${{ secrets.SERVER_USERNAME }}&lt;br /&gt;
          key: ${{ secrets.SSH_PRIVATE_KEY }}&lt;br /&gt;
          script: |&lt;br /&gt;
            cd /var/www/vhosts/abdoulaye-diallo.com/httpdocs/Front/&lt;br /&gt;
            git pull origin main&lt;br /&gt;
            npm ci --production&lt;br /&gt;
            npm run build&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Créer un environnement et des secrets sur Github ==&lt;br /&gt;
Comme on peut le voir dans ce code, on doit se connecter en SSH au serveur de production afin de déployer les MAJ. Pour cela et pour des raisons de sécurités, on stock les informations dans les secrets de GitHub (voir https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) . Ici en l'occurrence nous avons créés des secrets dans un environnement nommé MyPlesk sur GitHub (MAJ : les environnements Github semblent avoir disparus maintenant) :&lt;br /&gt;
[[Fichier:Github Secrets.png|centré|sans_cadre|1071x1071px]]&lt;br /&gt;
=== Création des clés ssh ===&lt;br /&gt;
[[Fichier:Plesk ssh keys.png|vignette]]&lt;br /&gt;
La connexion au serveur distant se fait via une clé ssh (d'où le secrets.SSH_PRIVATE_KEY à la ligne 25), pour cela nous allons ouvrir un terminal en local par exemple et lancer la commande de génération de clé ssh : &amp;lt;code&amp;gt;ssh-keygen -t rsa -b 4096 -C &amp;quot;monmail@email.com&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Il faudra ensuite copier la clé privée dans le secret de Github ( secrets.SSH_PRIVATE_KEY) et ajouter la clé publique parmis les clés SSH autorisés du serveur distant (sur Plesk, aller dans l'abonnement concerné et cliquer sur SSH KEYS).&lt;br /&gt;
&lt;br /&gt;
Il faut également renseigner le nom de l'utilisateur qui a accès au serveur.&lt;br /&gt;
&lt;br /&gt;
[[index.php?title=Catégorie:Github]]  &lt;br /&gt;
[[index.php?title=Catégorie:Git]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_en_place_une_CI/CD&amp;diff=52</id>
		<title>Mettre en place une CI/CD</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Mettre_en_place_une_CI/CD&amp;diff=52"/>
		<updated>2024-05-28T13:46:44Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Prérequis ==&lt;br /&gt;
Avant de suivre ce Tuto, en particulier pour la partie déploiement, s'assurer d'avoir cloner le repo sur le serveur de déploiement.&lt;br /&gt;
&lt;br /&gt;
== Le CI/CD en développement ==&lt;br /&gt;
Le CI/CD, ou Intégration Continue/Livraison Continue, est une pratique logicielle qui vise à automatiser le processus de développement et de déploiement logiciel. Il s'agit d'une approche DevOps qui permet d'améliorer la qualité, la rapidité et la fiabilité du développement logiciel.&lt;br /&gt;
&lt;br /&gt;
== Les étapes ==&lt;br /&gt;
&lt;br /&gt;
# Intégration Continue (CI) :&lt;br /&gt;
#* La CI consiste à intégrer fréquemment les modifications de code dans un référentiel partagé.&lt;br /&gt;
#* Les développeurs fusionnent régulièrement leur code dans une branche commune, déclenchant des processus automatisés qui vérifient la qualité du code.&lt;br /&gt;
# Tests Automatisés :&lt;br /&gt;
#* Les systèmes CI exécutent des tests automatisés pour s'assurer que les nouvelles modifications n'ont pas introduit de régressions.&lt;br /&gt;
#* Les tests peuvent inclure des tests unitaires, des tests d'intégration et d'autres formes de tests automatisés.&lt;br /&gt;
# Déploiement Continu (CD) :&lt;br /&gt;
#* L'Implémentation Continue (ou Déploiement Continu) étend la CI en automatisant la livraison du logiciel.&lt;br /&gt;
#* Le déploiement continu implique la mise en œuvre automatisée des modifications validées dans l'environnement de production.&lt;br /&gt;
&lt;br /&gt;
== Créer un fichier de workflow ==&lt;br /&gt;
Un fichier de workflow est le script qui sera exécuté par Github lors d'un évènement définis commpe un push sur la branch main ou la complétion d'un autre workflow.&lt;br /&gt;
&lt;br /&gt;
C'est généralement un ou plusieurs fichies qui doivent être placés dans le dossier '''&amp;lt;code&amp;gt;.github/workflows/&amp;lt;/code&amp;gt;''' (par exemple &amp;lt;code&amp;gt;'''.github/workflows/ci.yam'''l&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Exemple commenté d'un workflow d'intégration et de test continue Laravel ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# Nom du workflow&lt;br /&gt;
name: Laravel CI&lt;br /&gt;
&lt;br /&gt;
# Déclencheurs pour le workflow&lt;br /&gt;
on:&lt;br /&gt;
  push:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]   # Déclencher lorsqu'un push est effectué sur la branche principale&lt;br /&gt;
  pull_request:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]   # Déclencher lorsqu'une pull request est ouverte sur la branche principale&lt;br /&gt;
&lt;br /&gt;
# Définition des jobs&lt;br /&gt;
jobs:&lt;br /&gt;
  laravel-tests:&lt;br /&gt;
    runs-on: ubuntu-latest   # Utiliser l'image Ubuntu la plus récente comme environnement d'exécution&lt;br /&gt;
&lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: shivammathur/setup-php@v2   # Utiliser l'action pour configurer PHP&lt;br /&gt;
        with:&lt;br /&gt;
          php-version: '8.1'   # Spécifier la version de PHP à utiliser&lt;br /&gt;
      - uses: actions/checkout@v2   # Utiliser l'action pour effectuer un checkout du code&lt;br /&gt;
&lt;br /&gt;
      - name: Copy .env   # Étape pour copier le fichier .env s'il n'existe pas&lt;br /&gt;
        run: php -r &amp;quot;file_exists('.env') || copy('.env.example', '.env');&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      - name: Install Dependencies   # Étape pour installer les dépendances Composer&lt;br /&gt;
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist&lt;br /&gt;
&lt;br /&gt;
      - name: Generate key   # Étape pour générer la clé d'application Laravel&lt;br /&gt;
        run: php artisan key:generate&lt;br /&gt;
&lt;br /&gt;
      - name: Directory Permissions   # Étape pour définir les permissions sur les répertoires&lt;br /&gt;
        run: chmod -R 777 storage bootstrap/cache&lt;br /&gt;
&lt;br /&gt;
      - name: Create Database   # Étape pour créer une base de données SQLite&lt;br /&gt;
        run: |&lt;br /&gt;
          mkdir -p database&lt;br /&gt;
          touch database/database.sqlite&lt;br /&gt;
&lt;br /&gt;
      - name: Execute tests (Unit and Feature tests) via PHPUnit   # Étape pour exécuter les tests PHPUnit&lt;br /&gt;
        env:&lt;br /&gt;
          DB_CONNECTION: sqlite&lt;br /&gt;
          DB_DATABASE: database/database.sqlite   # Configurer la base de données pour les tests&lt;br /&gt;
        run: vendor/bin/phpunit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;En incluant ce fichier dans notre système de fichiers, lors du push Github va effectuer les installations nécessaires pour lancer une version de test du projet et également exécuter tous les test unitaires et de features compris dans le projet.&lt;br /&gt;
&lt;br /&gt;
Le déploiement demande un peu plus travail :&lt;br /&gt;
&lt;br /&gt;
=== Exemple commenté d'un workflow de déploiement continue Laravel ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Nom du workflow&lt;br /&gt;
name: Laravel CD&lt;br /&gt;
&lt;br /&gt;
# Déclencheur pour le workflow : déclenche lorsqu'une exécution du workflow &amp;quot;Laravel CI&amp;quot; est terminée&lt;br /&gt;
on:&lt;br /&gt;
  workflow_run:&lt;br /&gt;
    workflows: [&amp;quot;Laravel CI&amp;quot;]&lt;br /&gt;
    types:&lt;br /&gt;
      - completed&lt;br /&gt;
&lt;br /&gt;
# Définition des jobs&lt;br /&gt;
jobs:&lt;br /&gt;
  deploy:&lt;br /&gt;
    runs-on: ubuntu-latest   # Utiliser l'image Ubuntu la plus récente comme environnement d'exécution&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      name: 'MyPlesk'   # Nom de l'environnement de déploiement&lt;br /&gt;
&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Deploy to Server   # Étape pour déployer sur le serveur&lt;br /&gt;
        uses: appleboy/ssh-action@master   # Utiliser l'action SSH pour effectuer le déploiement&lt;br /&gt;
        with:&lt;br /&gt;
          host: ${{ secrets.SERVER_HOST }}   # Adresse IP ou nom d'hôte du serveur&lt;br /&gt;
          username: ${{ secrets.SERVER_USERNAME }}   # Nom d'utilisateur pour la connexion SSH&lt;br /&gt;
          key: ${{ secrets.SSH_PRIVATE_KEY }}   # Clé privée SSH pour l'authentification&lt;br /&gt;
          script: |&lt;br /&gt;
            cd /var/www/vhosts/abdoulaye-diallo.com/api.abdoulaye-diallo.com/Cv_back/   # Se déplacer vers le répertoire du projet&lt;br /&gt;
            git pull origin main   # Mettre à jour le code depuis la branche principale&lt;br /&gt;
            php artisan migrate   # Exécuter les migrations de base de données&lt;br /&gt;
            composer update   # Mettre à jour les dépendances Composer (si nécessaire)&lt;br /&gt;
            composer install   # Installer les dépendances Composer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple de workflow CI/CD pour un projet React en un seul fichier : ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
name: React CICD&lt;br /&gt;
&lt;br /&gt;
on:&lt;br /&gt;
  push:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]&lt;br /&gt;
  pull_request:&lt;br /&gt;
    branches: [ &amp;quot;main&amp;quot; ]&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  build:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        node-version: [18.x]&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Checkout Repository&lt;br /&gt;
        uses: actions/checkout@v2&lt;br /&gt;
      - name: Use Node.js ${{ matrix.node-version }}&lt;br /&gt;
        uses: actions/setup-node@v3&lt;br /&gt;
        with:&lt;br /&gt;
          node-version: ${{ matrix.node-version }}&lt;br /&gt;
          cache: 'npm'&lt;br /&gt;
      - name: Install Dependencies&lt;br /&gt;
        run: npm ci&lt;br /&gt;
      - name: Build Project&lt;br /&gt;
        run: npm run build --if-present&lt;br /&gt;
      - name: Run Tests&lt;br /&gt;
        run: npm test --if-present&lt;br /&gt;
&lt;br /&gt;
  deploy:&lt;br /&gt;
    needs: build&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    environment:&lt;br /&gt;
      name: &amp;quot;MyPlesk&amp;quot;&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Checkout Repository&lt;br /&gt;
        uses: actions/checkout@v2&lt;br /&gt;
      - name: Deploy to Server&lt;br /&gt;
        uses: appleboy/ssh-action@master&lt;br /&gt;
        with:&lt;br /&gt;
          host: ${{ secrets.SERVER_HOST }}&lt;br /&gt;
          username: ${{ secrets.SERVER_USERNAME }}&lt;br /&gt;
          key: ${{ secrets.SSH_PRIVATE_KEY }}&lt;br /&gt;
          script: |&lt;br /&gt;
            cd /var/www/vhosts/abdoulaye-diallo.com/httpdocs/Front/&lt;br /&gt;
            git pull origin main&lt;br /&gt;
            npm ci --production&lt;br /&gt;
            npm run build&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Créer un environnement et des secrets sur Github ==&lt;br /&gt;
Comme on peut le voir dans ce code, on doit se connecter en SSH au serveur de production afin de déployer les MAJ. Pour cela et pour des raisons de sécurités, on stock les informations dans les secrets de GitHub (voir https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) . Ici en l'occurrence nous avons créés des secrets dans un environnement nommé MyPlesk sur GitHub :&lt;br /&gt;
[[Fichier:Github Secrets.png|centré|sans_cadre|1071x1071px]]&lt;br /&gt;
=== Création des clés ssh ===&lt;br /&gt;
[[Fichier:Plesk ssh keys.png|vignette]]&lt;br /&gt;
La connexion au serveur distant se fait via une clé ssh (d'où le secrets.SSH_PRIVATE_KEY à la ligne 25), pour cela nous allons ouvrir un terminal en local par exemple et lancer la commande de génération de clé ssh : &amp;lt;code&amp;gt;ssh-keygen -t rsa -b 4096 -C &amp;quot;monmail@email.com&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Il faudra ensuite copier la clé privée dans le secret de Github ( secrets.SSH_PRIVATE_KEY) et ajouter la clé publique parmis les clés SSH autorisés du serveur distant (sur Plesk, aller dans l'abonnement concerné et cliquer sur SSH KEYS).&lt;br /&gt;
&lt;br /&gt;
Il faut également renseigner le nom de l'utilisateur qui a accès au serveur.&lt;br /&gt;
&lt;br /&gt;
[[index.php?title=Catégorie:Github]]  &lt;br /&gt;
[[index.php?title=Catégorie:Git]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Fichier:Github_Secrets.png&amp;diff=51</id>
		<title>Fichier:Github Secrets.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Fichier:Github_Secrets.png&amp;diff=51"/>
		<updated>2024-05-28T13:46:09Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Github Secrets&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:MQL5&amp;diff=50</id>
		<title>Catégorie:MQL5</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Cat%C3%A9gorie:MQL5&amp;diff=50"/>
		<updated>2024-05-02T13:10:28Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec « Quelques outils et fonctions MQL5 — Gandal (abdoulaye-diallo.com) »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Quelques outils et fonctions MQL5|Quelques outils et fonctions MQL5 — Gandal (abdoulaye-diallo.com)]]&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=Quelques_outils_et_fonctions_MQL5&amp;diff=49</id>
		<title>Quelques outils et fonctions MQL5</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=Quelques_outils_et_fonctions_MQL5&amp;diff=49"/>
		<updated>2024-05-02T13:10:07Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : Page créée avec «  = Code des pays et devises pour Calendrier (P1307) = C’est un peu cru donné comme cela mais imaginons que les infos suivantes se trouvent dans un tableau bien ordonné 😉.  [id]	[nom] [code] [devise] [symbole_devise] [nom_url] [réservé]   0 	&amp;quot;Worldwide&amp;quot; &amp;quot;WW&amp;quot; &amp;quot;ALL&amp;quot; &amp;quot;&amp;quot; &amp;quot;worldwide&amp;quot; 0   999 	&amp;quot;European Union&amp;quot; &amp;quot;EU&amp;quot; &amp;quot;EUR&amp;quot; &amp;quot;€&amp;quot; &amp;quot;european-union&amp;quot; 0   840 	&amp;quot;United States&amp;quot; &amp;quot;US&amp;quot; &amp;quot;USD&amp;quot; &amp;quot;$&amp;quot; &amp;quot;united-states&amp;quot; 0   124 	&amp;quot;Canada&amp;quot; &amp;quot;CA&amp;quot; &amp;quot;CAD&amp;quot; &amp;quot;$&amp;quot; &amp;quot;canada&amp;quot; 0   36 	&amp;quot;Australia&amp;quot; &amp;quot;... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Code des pays et devises pour Calendrier (P1307) =&lt;br /&gt;
C’est un peu cru donné comme cela mais imaginons que les infos suivantes se trouvent dans un tableau bien ordonné 😉.&lt;br /&gt;
&lt;br /&gt;
[id]	[nom] [code] [devise] [symbole_devise] [nom_url] [réservé] &lt;br /&gt;
&lt;br /&gt;
0 	&amp;quot;Worldwide&amp;quot; &amp;quot;WW&amp;quot; &amp;quot;ALL&amp;quot; &amp;quot;&amp;quot; &amp;quot;worldwide&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
999 	&amp;quot;European Union&amp;quot; &amp;quot;EU&amp;quot; &amp;quot;EUR&amp;quot; &amp;quot;€&amp;quot; &amp;quot;european-union&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
840 	&amp;quot;United States&amp;quot; &amp;quot;US&amp;quot; &amp;quot;USD&amp;quot; &amp;quot;$&amp;quot; &amp;quot;united-states&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
124 	&amp;quot;Canada&amp;quot; &amp;quot;CA&amp;quot; &amp;quot;CAD&amp;quot; &amp;quot;$&amp;quot; &amp;quot;canada&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
36 	&amp;quot;Australia&amp;quot; &amp;quot;AU&amp;quot; &amp;quot;AUD&amp;quot; &amp;quot;$&amp;quot; &amp;quot;australia&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
554 	&amp;quot;New Zealand&amp;quot; &amp;quot;NZ&amp;quot; &amp;quot;NZD&amp;quot; &amp;quot;$&amp;quot; &amp;quot;new-zealand&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
392 	&amp;quot;Japan&amp;quot; &amp;quot;JP&amp;quot; &amp;quot;JPY&amp;quot; &amp;quot;Ґ&amp;quot; &amp;quot;japan&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
156 	&amp;quot;China&amp;quot; &amp;quot;CN&amp;quot; &amp;quot;CNY&amp;quot; &amp;quot;Ґ&amp;quot; &amp;quot;china&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
826	 &amp;quot;United Kingdom&amp;quot; &amp;quot;GB&amp;quot; &amp;quot;GBP&amp;quot; &amp;quot;Ј&amp;quot; &amp;quot;united-kingdom&amp;quot; &lt;br /&gt;
&lt;br /&gt;
756 	&amp;quot;Switzerland&amp;quot; &amp;quot;CH&amp;quot; &amp;quot;CHF&amp;quot; &amp;quot;₣&amp;quot; &amp;quot;switzerland&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
276 	&amp;quot;Germany&amp;quot; &amp;quot;DE&amp;quot; &amp;quot;EUR&amp;quot; &amp;quot;€&amp;quot; &amp;quot;germany&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
250 	&amp;quot;France&amp;quot; &amp;quot;FR&amp;quot; &amp;quot;EUR&amp;quot; &amp;quot;€&amp;quot; &amp;quot;france&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
380 	&amp;quot;Italy&amp;quot; &amp;quot;IT&amp;quot; &amp;quot;EUR&amp;quot; &amp;quot;€&amp;quot; &amp;quot;italy&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
724 	&amp;quot;Spain&amp;quot; &amp;quot;ES&amp;quot; &amp;quot;EUR&amp;quot; &amp;quot;€&amp;quot; &amp;quot;spain&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
76 	&amp;quot;Brazil&amp;quot; &amp;quot;BR&amp;quot; &amp;quot;BRL&amp;quot; &amp;quot;R$&amp;quot; &amp;quot;brazil&amp;quot; 0 &lt;br /&gt;
&lt;br /&gt;
410	&amp;quot;South Korea&amp;quot; &amp;quot;KR&amp;quot; &amp;quot;KRW&amp;quot; &amp;quot;₩&amp;quot; &amp;quot;south-korea&amp;quot; &lt;br /&gt;
&lt;br /&gt;
= Modifier une position =&lt;br /&gt;
Si le trade se fait par CTrade, il faut tout simplement utiliser la méthode &amp;lt;syntaxhighlight lang=&amp;quot;mql5&amp;quot;&amp;gt;&lt;br /&gt;
bool PositionModify(&lt;br /&gt;
const string symbol, // symbole&lt;br /&gt;
double sl, // prix du stop loss&lt;br /&gt;
double tp // prix du take profit )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Un exemple&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|// Importer librairie CTrade&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;include &amp;lt;Trade\Trade.mqh&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CTrade trade;&lt;br /&gt;
&lt;br /&gt;
trade.Sell(lot, _Symbol, Bid, SL, TP);&lt;br /&gt;
&lt;br /&gt;
trade.PositionModify(_Symbol,NormalizeDouble(openPrice - (SecuredSL * 0.0001), _Digits), 0);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Récupérer la date d’ouverture de la bougie actuelle =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|MqlDateTime dt;   // On crée une srtucture MqlDateTime&lt;br /&gt;
&lt;br /&gt;
datetime time=iTime(_Symbol, PERIOD_M1,0);   // On récupère l'heure d'ouverture de la bougie actuelle en M1&lt;br /&gt;
&lt;br /&gt;
TimeToStruct(time,dt);     // On place cette heure dans le MqlDateTime pour plus facilement l'exploiter&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Afficher des indicateurs dans le Testeur de stratégie =&lt;br /&gt;
Les indicateurs chargés dans le code source sont automatiquement affichés dans le Testeur de stratégie mais par pur coïncidence je me suis rendu compte que cela fonctionnait avec des modèles placés sur les graphiques. En effet il suffit de créer un modèle du même nom que l'Expert Advisor qu’on lance pour que tous les indicateurs et outils qu’on place dessus apparaissent dans le tester.&lt;br /&gt;
&lt;br /&gt;
= Obtenir la TimeFrame en chaîne de caractères =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|string TimeFrameInString()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  int tf= _Period;&lt;br /&gt;
&lt;br /&gt;
  if(tf==1){ return &amp;quot;M1&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
  if(tf==5){ return &amp;quot;M5&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
  if(tf==15){ return &amp;quot;M15&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
  if(tf==30){ return &amp;quot;M30&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
  if(tf==16385){ return &amp;quot;H1&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
  if(tf==16388){ return &amp;quot;M4&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
  if(tf==16408){ return &amp;quot;D1&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
  if(tf==32769){ return &amp;quot;W1&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
  if(tf==49153){ return &amp;quot;MN&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
  return &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Envoyer une notification =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|SendNotification(&amp;quot;Voici mon message&amp;quot;);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Trouver la somme nécessaire pour un lot (marge) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|SymbolInfoDouble(_Symbol, SYMBOL_MARGIN_HEDGED);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Afficher un message dans une message box =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|MessageBox(&amp;quot;Mon message&amp;quot;);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Utiliser les objets dans une fonction =&lt;br /&gt;
Les fonctions utilsent des pointeurs sur objets (avec *) donc voici un exemple de fonction avec un objet CArrayDouble&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|CArrayDouble *getLotsArray(double lot)&lt;br /&gt;
&lt;br /&gt;
  {&lt;br /&gt;
&lt;br /&gt;
    CArrayDouble *lots = new CArrayDouble;&lt;br /&gt;
&lt;br /&gt;
    while(lot &amp;gt;= 0.01)&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
        if(lot &amp;gt; SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX))&lt;br /&gt;
&lt;br /&gt;
          {&lt;br /&gt;
&lt;br /&gt;
            lots.Add(SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX));&lt;br /&gt;
&lt;br /&gt;
            lot -= SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);&lt;br /&gt;
&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
        else&lt;br /&gt;
&lt;br /&gt;
          {&lt;br /&gt;
&lt;br /&gt;
            lots.Add(SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX));&lt;br /&gt;
&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
    return(lots);&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Initialiser la fonction OnInit() =&lt;br /&gt;
&lt;br /&gt;
* Lancer le setprices()&lt;br /&gt;
* Mettre à jour les dates&lt;br /&gt;
* Mettre à jour le isOpen&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
= Tracer les points pivot sur le graphique =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|datetime today;&lt;br /&gt;
&lt;br /&gt;
int countDays=0;&lt;br /&gt;
&lt;br /&gt;
void tracePivot(){&lt;br /&gt;
&lt;br /&gt;
    if(iTime(_Symbol, PERIOD_D1,0) != today){&lt;br /&gt;
&lt;br /&gt;
        today = iTime(_Symbol, PERIOD_D1,0);&lt;br /&gt;
&lt;br /&gt;
        // début du tracé&lt;br /&gt;
&lt;br /&gt;
        datetime Time1 = iTime(_Symbol,PERIOD_D1,0);&lt;br /&gt;
&lt;br /&gt;
        //Calcul de l'eure de fin du tracé (à 23:30)&lt;br /&gt;
&lt;br /&gt;
        MqlDateTime dEnd;&lt;br /&gt;
&lt;br /&gt;
        TimeToStruct( iTime(_Symbol,PERIOD_D1,0),dEnd);&lt;br /&gt;
&lt;br /&gt;
        dEnd.hour = 23; dEnd.min = 30;&lt;br /&gt;
&lt;br /&gt;
        datetime Time2 = StructToTime(dEnd);&lt;br /&gt;
&lt;br /&gt;
        // Tracé des lignes&lt;br /&gt;
&lt;br /&gt;
        TrendCreate(0,&amp;quot;PP&amp;quot;+IntegerToString(countDays),0,Time1,PP(),Time2,PP(),clrBlue);&lt;br /&gt;
&lt;br /&gt;
        TrendCreate(0,&amp;quot;S1&amp;quot;+IntegerToString(countDays),0,Time1,S1(),Time2,S1(),clrCyan);&lt;br /&gt;
&lt;br /&gt;
        TrendCreate(0,&amp;quot;S2&amp;quot;+IntegerToString(countDays),0,Time1,S2(),Time2,S2(),clrYellow);&lt;br /&gt;
&lt;br /&gt;
        TrendCreate(0,&amp;quot;S3&amp;quot;+IntegerToString(countDays),0,Time1,S3(),Time2,S3(),clrDarkGray);&lt;br /&gt;
&lt;br /&gt;
        TrendCreate(0,&amp;quot;R1&amp;quot;+IntegerToString(countDays),0,Time1,R1(),Time2,R1(),clrBeige);&lt;br /&gt;
&lt;br /&gt;
        TrendCreate(0,&amp;quot;R2&amp;quot;+IntegerToString(countDays),0,Time1,R2(),Time2,R2(),clrRosyBrown);&lt;br /&gt;
&lt;br /&gt;
        TrendCreate(0,&amp;quot;R3&amp;quot;+IntegerToString(countDays),0,Time1,R3(),Time2,R3(),clrDarkOrange);&lt;br /&gt;
&lt;br /&gt;
        countDays++;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool TrendCreate(const long chart_ID = 0, // identifiant du graphique&lt;br /&gt;
&lt;br /&gt;
                const string name = &amp;quot;TrendLine&amp;quot;, // nom de la ligne&lt;br /&gt;
&lt;br /&gt;
                const int sub_window = 0, // indice de sous-fenêtre&lt;br /&gt;
&lt;br /&gt;
                datetime time1 = 0, // heure du premier point&lt;br /&gt;
&lt;br /&gt;
                double price1 = 0, // prix du premier point&lt;br /&gt;
&lt;br /&gt;
                datetime time2 = 0, // heure du deuxième point&lt;br /&gt;
&lt;br /&gt;
                double price2 = 0, // prix du deuxième point&lt;br /&gt;
&lt;br /&gt;
                const color clr = clrRed, // couleur de la ligne&lt;br /&gt;
&lt;br /&gt;
                const ENUM_LINE_STYLE style = STYLE_SOLID, // style de la ligne&lt;br /&gt;
&lt;br /&gt;
                const int width = 3, // largeur de la ligne&lt;br /&gt;
&lt;br /&gt;
                const bool back = false, // en arrière plan&lt;br /&gt;
&lt;br /&gt;
                const bool selection = true, // mise en surbrillance pour le déplacement&lt;br /&gt;
&lt;br /&gt;
                const bool ray_left = false, // Prolongement de la ligne vers la gauche&lt;br /&gt;
&lt;br /&gt;
                const bool ray_right = false, // Prolongement de la ligne vers la droite&lt;br /&gt;
&lt;br /&gt;
                const bool hidden = true, // caché dans la liste des objets&lt;br /&gt;
&lt;br /&gt;
                const long z_order = 0) // priorité pour le clic de souris&lt;br /&gt;
&lt;br /&gt;
  {&lt;br /&gt;
&lt;br /&gt;
//--- réinitialise la valeur d'erreur&lt;br /&gt;
&lt;br /&gt;
    ResetLastError();&lt;br /&gt;
&lt;br /&gt;
//--- crée une ligne de tendance par les coordonnées données&lt;br /&gt;
&lt;br /&gt;
    if(!ObjectCreate(chart_ID,name,OBJ_TREND,sub_window,time1,price1,time2,price2))&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
        Print(__FUNCTION__,&lt;br /&gt;
&lt;br /&gt;
              &amp;quot; : impossible de créer une ligne de tendance ! Code d'erreur = &amp;quot;,GetLastError());&lt;br /&gt;
&lt;br /&gt;
        return(false);&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
//--- définit la couleur de la ligne&lt;br /&gt;
&lt;br /&gt;
    ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);&lt;br /&gt;
&lt;br /&gt;
//--- définit le style d'affichage de la ligne&lt;br /&gt;
&lt;br /&gt;
    ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);&lt;br /&gt;
&lt;br /&gt;
//--- définit la largeur de la ligne&lt;br /&gt;
&lt;br /&gt;
    ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);&lt;br /&gt;
&lt;br /&gt;
//--- affiche en premier plan (false) ou en arrière-plan (true)&lt;br /&gt;
&lt;br /&gt;
    ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);&lt;br /&gt;
&lt;br /&gt;
//--- active (true) ou désactive (false) le mode de déplacement de la ligne à la souris&lt;br /&gt;
&lt;br /&gt;
//--- lors de la création d'un objet graphique utilisant la fonction ObjectCreate, l'o&lt;br /&gt;
&lt;br /&gt;
//--- mis en surbrillance et déplacé par défaut. Dans cette méthode, le paramètre de sélection&lt;br /&gt;
&lt;br /&gt;
//--- est vrai par défaut, permettant de mettre en surbrillance et de déplacer l'objet&lt;br /&gt;
&lt;br /&gt;
    ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);&lt;br /&gt;
&lt;br /&gt;
    ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);&lt;br /&gt;
&lt;br /&gt;
//--- active (true) ou désactive(false) le mode de prolongation de l'affichage de la ligne vers la gauche&lt;br /&gt;
&lt;br /&gt;
    ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);&lt;br /&gt;
&lt;br /&gt;
//--- active (true) ou désactive(false) le mode de prolongation de l'affichage de la ligne vers la droite&lt;br /&gt;
&lt;br /&gt;
    ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);&lt;br /&gt;
&lt;br /&gt;
//--- masque (true) ou affiche (false) le nom de l'objet graphique dans la liste des objets&lt;br /&gt;
&lt;br /&gt;
    ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);&lt;br /&gt;
&lt;br /&gt;
//--- définit la priorité pour recevoir l'événement d'un clic de souris dans le graphique&lt;br /&gt;
&lt;br /&gt;
    ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);&lt;br /&gt;
&lt;br /&gt;
//--- exécution réussie&lt;br /&gt;
&lt;br /&gt;
    return(true);&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Formater un fichier historique d’un Event depuis investing.com =&lt;br /&gt;
&lt;br /&gt;
# Se rendre sur la page de l’event sur investing.com&lt;br /&gt;
# Copier le tableau historique de l’event&lt;br /&gt;
# Coller le tableau dans Translater Investing - Google Sheets dans la première feuille à gauche&lt;br /&gt;
# Formater les heures (généralement on ajoute 1heure) dans la colonne tout à droit (pour cela &amp;lt;&amp;lt; =CelluleDesHeures+ “1:00” &amp;gt;&amp;gt;&lt;br /&gt;
# Formater la colonne des heures en heure pour la modification puis en texte brut quand le formatge est terminé&lt;br /&gt;
# Se rendre sur la feuille Résultat pour valider le rendu puis le copier et coller uniquement les valeurs dans la feuille ToDownload&lt;br /&gt;
# Télécharger la feuille ToDownload en csv&lt;br /&gt;
# Ouvir le fichier téléchargé et enregistrer sous un csv en UTF-16 LE en le renommant comme il faut&lt;br /&gt;
# Charger le fichier dans l’EA Event et tester&lt;br /&gt;
&lt;br /&gt;
= Obtenir les données des inscriptions hebdomadaire au chômage de US =&lt;br /&gt;
Ces données sont fournis par le “US Department of Labor” dont le site est &amp;lt;nowiki&amp;gt;https://www.dol.gov/&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Le site dédié aux devs est Beginner's Guide - United States Department of Labor Developer Portal (dol.gov)&lt;br /&gt;
&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
On commence par créer un compte : Account Registered (dol.gov)&lt;br /&gt;
&lt;br /&gt;
Se connecter ensuite et générer une clé  de connexion API .&lt;br /&gt;
&lt;br /&gt;
'''Le Secret utilisé pour la première est mon mot de passe de toujours et la clé est 656af577-8bd6-4bd8-b3dd-b84a1890249c'''&lt;br /&gt;
&lt;br /&gt;
LE liens vers la page spécial de l’api concernant Initial Jobless claims : OUI Initial Claims - United States Department of Labor Developer Portal (dol.gov)&lt;br /&gt;
&lt;br /&gt;
Requête début : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;http://api.dol.gov/V1/Statistics/OUI_InitialClaims/unemploymentInsuranceInitialClaims?$orderby=week&amp;lt;/nowiki&amp;gt; desc&amp;amp;KEY=656af577-8bd6-4bd8-b3dd-b84a1890249c&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
	<entry>
		<id>https://wiki.abdoulaye-diallo.com/index.php?title=MediaWiki:Sidebar&amp;diff=48</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.abdoulaye-diallo.com/index.php?title=MediaWiki:Sidebar&amp;diff=48"/>
		<updated>2024-05-02T13:06:31Z</updated>

		<summary type="html">&lt;p&gt;Abdoulaye : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* Catégories&lt;br /&gt;
** :Catégorie:Apache|Apache&lt;br /&gt;
** :Catégorie:Bootstrap|Bootstrap&lt;br /&gt;
** :Catégorie:Centos|Centos&lt;br /&gt;
** :Catégorie:Drupal|Drupal&lt;br /&gt;
** :Catégorie:Git|Git&lt;br /&gt;
** :Catégorie:Github|Github&lt;br /&gt;
** :Catégorie:Laravel|Laravel&lt;br /&gt;
** :Catégorie:Linux|Linux&lt;br /&gt;
** :Catégorie:Mediawiki|Mediawiki&lt;br /&gt;
** :Catégorie:MQL5|MQL5&lt;br /&gt;
** :Catégorie:MySQL|MySQL&lt;br /&gt;
** :Catégorie:NextJs|NextJS&lt;br /&gt;
** :Catégorie:Nodejs|Nodejs&lt;br /&gt;
** :Catégorie:Plesk|Plesk&lt;br /&gt;
** :Catégorie:React|React&lt;br /&gt;
** :Catégorie:Rsync|Rsync&lt;br /&gt;
** :Catégorie:Symfony|Symfony&lt;br /&gt;
** :Catégorie:Twig|Twig&lt;br /&gt;
** :Catégorie:Wordpress|Wordpress&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Abdoulaye</name></author>
	</entry>
</feed>