Guild icon
CFITECH
Web 2025-2026 / 🤯︱symfony
Avatar
Julien (Prof) 08-04-26 09:15
www.symfony.com
Avatar
Julien (Prof) 08-04-26 09:23
A Dependency Manager for PHP
Avatar
Julien (Prof) 08-04-26 09:35
composer -v Pour installer scoop sur powersheel Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression Ensuite sur cmd scoop install symfony-cli (edited)
Avatar
Julien (Prof) 08-04-26 09:51
symfony new TutoSymfony cd TutoSymfony composer require webapp (edited)
Avatar
Julien (Prof) 08-04-26 10:37
symfony new TutoSymfony --webapp
10:40
symfony php -v symfony local:php:list echo 8.*.* > .php-version (edited)
Avatar
Julien (Prof) 08-04-26 11:04
symfony server:start
Avatar
Julien (Prof) 08-04-26 11:18
symfony server:start -d (ou le raccourci symfony serve -d) symfony open:local (edited)
11:34
symfony server:stop (Si ça ne fonctionne pas faites Ctrl+C dans votre terminal)
11:35
symfony server:list
11:40
symfony server:ca:install (accepter le certificat)
Avatar
Julien (Prof) 08-04-26 12:03
@Web Débutant Mettez vous a jour, les absents
🙏 1
Avatar
Julien (Prof) 14-04-26 09:05
symfony console
Avatar
Julien (Prof) 14-04-26 09:17
symfony console make:controller Home
Avatar
Julien (Prof) 14-04-26 09:46
#[Route(path : "/", name : "home")] public function index(): Response{ return new Response("Hello World !!!"); } (edited)
09:51
home: path: / controller: App\Controller\HomeController::index
Avatar
Julien (Prof) 14-04-26 10:27
extends AbstractController (edited)
10:31
?nom=Dunia
10:32
#[Route(path :"/", name : "home")] public function index(): Response{ return new Response("Hello ".$_GET['nom']); }
10:37
use Symfony\Component\HttpFoundation\Request;
10:41
Avatar
Julien (Prof) 14-04-26 11:00
11:03
/recette/poulet-dg-13
11:04
Avatar
Julien (Prof) 14-04-26 11:41
#[Route(path : "/recette", name : "app_recipe_show")] public function show(Request $request): Response{ return new Response("Bienvenue dans la page ". $request->query->get("recette", "des recettes")); }
11:46
11:52
11:55
Avatar
Julien (Prof) 14-04-26 12:06
#[Route(path : "/recette/{slug}-{id}", name : "app_recipe_show", requirements: ['id'=> '\d+', 'slug' => '[a-z0-9-]+'])] public function show(Request $request): Response{ dd($request->attributes->get('slug') , $request->attributes->get('id')); return new Response("Bienvenue dans la page ". $request->query->get("recette", "des recettes")); }
Avatar
Julien (Prof) 14-04-26 12:14
Cours du jours @Web Débutant mettez vous à jour ceux qui n'étaient pas la. Refaite pour vous entrainer, ceux qui étaient la 😉 (edited)
👌 2
Avatar
Julien (Prof) 15-04-26 09:20
Avatar
Julien (Prof) 15-04-26 09:27
Avatar
Julien (Prof) 15-04-26 09:36
#[Route(path : "/recette", name : "app_recipe_index")] public function index(): Response{ return new Response("Bienvenue dans la page des recettes !!!"); } #[Route(path : "/recette/{slug}-{id}", name : "app_recipe_show", requirements: ['id'=> '\d+', 'slug' => '[a-z0-9-]+'])] public function show(string $slug, int $id): Response{ // dd($request->attributes->get('slug') , $request->attributes->getInt('id')); // dd($slug, $id); return new Response("Recette numéro ". $id . " : " .$slug); }
Avatar
Julien (Prof) 15-04-26 09:43
//retourner un json #[Route(path : "/recette2/{slug}-{id}", name : "app_recipe_show2", requirements: ['id'=> '\d+', 'slug' => '[a-z0-9-]+'])] public function show2(string $slug, int $id): JsonResponse{ return new JsonResponse([ 'id' => $id, 'slug' => $slug ]); }
09:44
09:47
symfony console debug:router
Avatar
Julien (Prof) 15-04-26 10:19
Twig - The flexible, fast, and secure template engine for PHP
Avatar
Julien (Prof) 15-04-26 10:36
10:42
10:48
#[Route(path : "/recette", name : "app_recipe_index")] public function index(): Response{ return $this->render('recipe/index.html.twig'); }
Avatar
Julien (Prof) 15-04-26 11:00
11:02
Powerful, extensible, and feature-packed frontend toolkit. Build and customize with Sass, utilize prebuilt grid system and components, and bring projects to life with powerful JavaScript plugins.
Avatar
Julien (Prof) 15-04-26 11:12
<nav class="navbar navbar-expand-md navbar-dark bg-dark"> <div class="container-fluid"> <a class="navbar-brand" href="#">RecetteVie</a> </div> </nav> <div class = "container my-4"> {% block body %}{% endblock %} </div> (edited)
11:17
Avatar
Julien (Prof) 15-04-26 11:36
11:40
#[Route(path : "/recette/{slug}-{id}", name : "app_recipe_show", requirements: ['id'=> '\d+', 'slug' => '[a-z0-9-]+'])] public function show(string $slug, int $id): Response{ return $this->render('recipe/show.html.twig'); }
11:43
11:47
Avatar
Julien (Prof) 15-04-26 12:05
@Web Débutant
12:05
mettez vous a jour
12:06
refaite le cours pour vous entrainez
Avatar
Julien (Prof) 17-04-26 14:37
#[Route(path : "/recette/{slug}-{id}", name : "app_recipe_show", requirements: ['id'=> '\d+', 'slug' => '[a-z0-9-]+'])] public function show(string $slug, int $id): Response{ return $this->render('recipe/show.html.twig', [ "slug" => $slug, "id" => $id, "user" => [ "firstname" => "Julien", "lastname" => "Dunia" ] ]); } (edited)
14:43
<p>Auteur : {{ user.firstname}}</p> (edited)
14:46
Avatar
Julien (Prof) 17-04-26 15:06
<h4>Comment faire un/une {{ slug | title }}</h4>
Avatar
Julien (Prof) 17-04-26 15:15
15:20
15:27
Avatar
Julien (Prof) 17-04-26 15:37
<a class="navbar-brand" href={{ url('home') }}>Acceuil</a> (edited)
Avatar
Julien (Prof) 17-04-26 15:55
De la part d'Isamail pour les plus faineant "emmet.includeLanguages": { "twig": "html", },
Avatar
Julien (Prof) 17-04-26 16:03
<body> <nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4 "> {# <div class = "container-fluid"> #} <div class="collapse navbar-collapse" id="navbarsExampleDefault"> <a class="navbar-brand" href={{ url('home') }}>RecetteVie</a> <a class="navbar-brand" href={{ url('home') }}>Acceuil</a> <a class="navbar-brand" href={{ url('app_recipe_index') }}>Liste des Recettes</a> </div> </nav> <div class = "container my-4"> {% block body %}{% endblock %} </div> </body>
Avatar
Julien (Prof) 17-04-26 16:11
@Web Débutant
16:11
absent mettez vous à jour !!!
Avatar
Julien (Prof) 23-04-26 10:25
layouts
10:26
partials
10:27
_nav.html.twig
10:32
Avatar
Julien (Prof) 23-04-26 10:40
Avatar
Julien (Prof) 23-04-26 11:05
<div class="container"> <footer class="py-3 my-4"> <ul class="nav justify-content-center border-bottom pb-3 mb-3"> <li class="nav-item"> <a href={{ path('home') }} class="nav-link px-2 text-body-secondary">Accueil</a> </li> <li class="nav-item"> <a href={{ path('app_recipe_index') }} class="nav-link px-2 text-body-secondary">Recettes</a> </li> {# <li class="nav-item"> <a href="#" class="nav-link px-2 text-body-secondary">Contact</a> </li> #} </ul> <p class="text-center text-body-secondary">&copy; 2026 Cfitech, Inc</p> </footer> </div>
11:09
Avatar
Julien (Prof) 23-04-26 11:20
Avatar
Julien (Prof) 23-04-26 11:35
11:41
Avatar
Julien (Prof) 23-04-26 11:52
<nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4 "> {# <div class = "container-fluid"> #} <div class="collapse navbar-collapse" id="navbarsExampleDefault"> <ul class="navbar-nav me-auto mb-2 mb-sm-0"> <li class="nav-item"> <a class="nav-link {{ app.current_route == 'home' ? 'active' : '' }}" href={{ path('home') }}>RecetteVie</a> </li> <li class="nav-item"> <a class="nav-link {{ app.current_route == 'home' ? 'active' : '' }}" href={{ path('home') }}>Acceuil</a> </li> <li class="nav-item"> <a class="nav-link {{ app.current_route == 'app_recipe_index' ? 'active' : '' }}" href={{ path('app_recipe_index') }}>Liste des Recettes</a> </li> <ul> </div> </nav>
11:54
12:00
@Web Débutant Mettez vous à jour, nous avons finit le chapitre 4 Je vous recommande pendant les vacances de recommencer un projet symfony jusqu'a la
🙏 2
Avatar
Julien (Prof) 11-05-26 15:11
Avatar
Julien (Prof) 11-05-26 15:24
symfony console doctrine:database:create symfony console doctrine:database:drop --force (edited)
Avatar
Julien (Prof) 11-05-26 15:37
symfony console make:entity symfony console make:entity NomDeVotreEntité (edited)
Avatar
Julien (Prof) 11-05-26 15:49
Avatar
Julien (Prof) 11-05-26 16:06
@Web Débutant mettez vous à jour
👍 1
Avatar
Julien (Prof) 12-05-26 09:46
09:46
@Web Débutant
Avatar
Julien (Prof) 13-05-26 09:02
Avatar
Julien (Prof) 13-05-26 09:26
Avatar
Julien (Prof) 13-05-26 09:34
09:38
Avatar
Julien (Prof) 13-05-26 09:54
symfony console make:migration
Avatar
Julien (Prof) 13-05-26 10:29
symfony console doctrine:migrations:migrate
Avatar
Julien (Prof) 13-05-26 10:43
11:08
Avatar
Julien (Prof) 13-05-26 11:23
11:28
Avatar
Julien (Prof) 13-05-26 11:50
#[Route(path : "/recette", name : "app_recipe_index")] public function index(RecipeRepository $repository): Response{ $recipes = $repository->findAll(); dd($recipes); return $this->render('recipe/index.html.twig'); } #[Route(path : "/recette/{slug}-{id}", name : "app_recipe_show", requirements: ['id'=> '\d+', 'slug' => '[a-z0-9-]+'])] public function show(string $slug, int $id): Response{ // dd($request->attributes->get('slug') , $request->attributes->getInt('id')); // dd($slug, $id); // return new Response("Recette numéro ". $id . " : " .$slug); return $this->render('recipe/show.html.twig', [ "slug" => $slug, "id" => $id, "user" => [ "firstname" => "Julien", "lastname" => "Dunia" ] ]); }
11:56
@Web Débutant Voici le cours du jours. Les absents mettez vous à jour
👍 1
11:57
@Web Débutant Un petit projet pour s'entrainer, attention semaine prochaine on commence les choses serieuses
Avatar
Julien (Prof) 18-05-26 15:20
page recipe/index.html.twig {% extends 'base.html.twig' %} {# {% block title %}Liste des Recettes{% endblock %} #} {% block title "Liste des Recettes" %} {% block body %} <h1>Voici la liste des Recettes</h1> <ul> {# {{ dump(recipes) }} #} {% for recipe in recipes %} <li> <a href={{ path('app_recipe_show', {id: recipe.id, slug: recipe.slug}) }}>{{ recipe.title }}</a> </li> {% endfor %} </ul> {% endblock %}
15:21
dans recipecontroller #[Route(path : "/recette", name : "app_recipe_index")] public function index(RecipeRepository $repository): Response{ $recipes = $repository->findAll(); return $this->render('recipe/index.html.twig', [ "recipes" => $recipes ]); }
Avatar
Julien (Prof) 18-05-26 15:40
Avatar
Julien (Prof) 18-05-26 15:48
Avatar
Julien (Prof) 18-05-26 16:03
@Web Débutant mettez vous à jour
👍 1
Avatar
Julien (Prof) 19-05-26 09:08
Avatar
Julien (Prof) 19-05-26 09:37
Avatar
Julien (Prof) 19-05-26 10:07
recipe/show.html.twig {% extends 'base.html.twig' %} {% block title %}{{ recipe.slug }}{% endblock %} {% block body %} <h1>Bienvenu sur la recette numéro {{ recipe.id }}</h1> <h4>Comment faire un/une {{ recipe.title | title }}</h4> <p>Temps de préparation : {{ recipe.duration }} min</p> <p>{{ recipe.content }} </p> {# <p>Créé le {{ recipe.createdAt }} </p> <p>Modifié le {{ recipe.updatedAt }} </p> #} {# <p>Recette crée par {{ user.firstname }} {{ user.lastname }}</p> #} {# {{ dump(app.current_route) }} #} {# <p>Recette crée par {{ user.firstname ~" "~ user.lastname }}</p> #} {% endblock %}
10:10
Avatar
Julien (Prof) 19-05-26 10:18
{% block title %}#{{ recipe.id ~" "~ recipe.slug }}{% endblock %} (edited)
10:23
Avatar
Julien (Prof) 19-05-26 10:35
10:37
10:43
10:44
Avatar
Julien (Prof) 19-05-26 10:57
11:01
@Web Débutant mettez vous a jour
Avatar
Julien (Prof) 20-05-26 08:44
$em->persist($recipe); $em->flush(); (edited)
Avatar
Julien (Prof) 20-05-26 08:58
Avatar
Julien (Prof) 20-05-26 09:11
Avatar
Julien (Prof) 20-05-26 09:19
Avatar
Julien (Prof) 20-05-26 09:28
Avatar
Julien (Prof) 20-05-26 09:55
#[Route(path: "/recette", name: "app_recipe_index")] public function index(RecipeRepository $repository, EntityManagerInterface $em): Response { //va recuperer toutes les recettes (equivalent Select *) //en utilisant RecipeRepository $recipes = $repository->findAll(); //va recuperer toutes les recettes (equivalent Select *) //en utilisant RecipeRepository // $recipes = $em->getRepository(Recipe::class)->findAll(); //retrouver toutes les recettes en fonction d'une durée maximum // $recipes = $repository->findRecipeDurationLowerThan(60); //comment créer une recette et l'envoyer en base de données // $recipe = new Recipe; // // $recipe = new Recipe(); // $recipe->setTitle('Bruschette aux Tomates') // ->setSlug('bruschette-aux-tomates') // ->setContent(' // Prenez une tranche de pain, prenez des tomates, coupez-les, mettez-les sur le pain, ajoutez de l\'huile d\olive.') // ->setDuration(5) // ->setCreatedAt(new DateTimeImmutable()) // ->setUpdatedAt(new DateTimeImmutable()); // $em->persist($recipe); // $em->flush(); //Modifier une recette existante en prenant toutes les recettes dans un premier tant (findall) //Je modifie le nom de la 2eme recette // $recipes[1]->setTitle('Pondu (Saka Saka)'); // $em->flush(); //Suppression de la 5eme recette // $em->remove($recipes[4]); // $em->flush(); return $this->render('recipe/index.html.twig', [ "recipes" => $recipes ]); } (edited)
Avatar
Julien (Prof) 20-05-26 10:17
symfony console make:form Recipe
Avatar
Julien (Prof) 20-05-26 10:26
Avatar
Julien (Prof) 20-05-26 10:36
Avatar
Julien (Prof) 20-05-26 10:48
Avatar
Julien (Prof) 20-05-26 10:55
form themes symfony
10:58
bootstrap_5_layout.html.twig
10:59
bootstrap_5_horizontal_layout.html.twig
11:00
Avatar
Julien (Prof) 20-05-26 11:09
11:13
This article explains how to use in your app any of the form themes provided by Symfony and how to create your own custom form theme. Symfony Built-In Form Themes Symfony comes with several built-in…
11:15
11:18
11:21
11:24
A form is composed of fields, each of which are built with the help of a field type (e.g. TextType, ChoiceType, etc). Symfony comes standard with a large list of field types that can be used in your a…
11:25
Avatar
Avatar
Julien (Prof)
@Web Débutant Un petit projet pour s'entrainer, attention semaine prochaine on commence les choses serieuses
Julien (Prof) 20-05-26 11:30
ici
11:35
@Web Débutant Les absents Mettez vous a jour
11:35
@Web Débutant Faites le projet pour demain !!!
🤡 1
Avatar
Julien (Prof) 21-05-26 13:43
Avatar
Julien (Prof) 21-05-26 13:50
Avatar
#[Route(path: '/recette/{id}/edit', name: 'app_recipe_edit')] public function edit(Recipe $recipe, Request $request, EntityManagerInterface $em): Response { // dd($recipe); //cette methode prend en premier paramètre le formulaire que l'on souhaite utiliser //en second paramètre elle prend les données $form = $this->createForm(RecipeType::class, $recipe); $form->handleRequest($request); // dd($recipe); if ($form->isSubmitted() && $form->isValid()) { $em->flush(); return $this->redirectToRoute('app_recipe_index'); } return $this->render('recipe/edit.html.twig', [ 'recipe' => $recipe, 'monForm' => $form ]); }
Avatar
Julien (Prof) 21-05-26 13:58
Avatar
Julien (Prof) 21-05-26 14:10
#[Route(path: '/recette/{id}/edit', name: 'app_recipe_edit')] public function edit(Recipe $recipe, Request $request, EntityManagerInterface $em): Response { // dd($recipe); //cette methode prend en premier paramètre le formulaire que l'on souhaite utiliser //en second paramètre elle prend les données $form = $this->createForm(RecipeType::class, $recipe); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em->flush(); return $this->redirectToRoute('app_recipe_show', ['slug' => $recipe->getSlug(), 'id' => $recipe->getId()]); } return $this->render('recipe/edit.html.twig', [ 'recipe' => $recipe, 'monForm' => $form ]); }
14:12
14:16
14:21
_flash.html.twig
14:23
14:27
Avatar
Julien (Prof) 21-05-26 14:48
Avatar
Julien (Prof) 21-05-26 14:58
Avatar
Julien (Prof) 21-05-26 15:08
Avatar
Julien (Prof) 21-05-26 15:21
Avatar
Julien (Prof) 21-05-26 15:36
{% block body %} <h1 align="center">Bienvenu dans la liste des Recettes</h1> <div class = "container text-center"> <div class = "row"> {% for recipe in recipes %} <div class="card max-w-sm col-4 bg-white rounded-lg border border-gray-200 shadow-md dark:bg-gray-800 dark:border-gray-700 my-8 mr-4" data-type="post"> <h2><a href={{ path('app_recipe_show', {id : recipe.id, slug : recipe.slug})}}>{{ recipe.title }} </a></h2> <img src = "https://pbs.twimg.com/media/EdDUBw0WkAAQLJ1?format=jpg&name=large" width="150" height="200"> <p>Submitted {{ recipe.createdAt |date }}</p> </div> {% else %} <p>Pas encore de recette</p> {% endfor %} </div> </div> {% endblock %}
15:41
recipe/create.html.twig {% extends 'base.html.twig' %} {% block title 'Add Recipe'%} {% block body %} <div class = "row"> <div class= "col-md-6 mx-auto"> <h1 align="center">Créer une nouvelle Recette</h1> {{form(monForm)}} </div> </div> {% endblock %} (edited)
15:43
Avatar
Julien (Prof) 21-05-26 16:05
@Web Avancé Mettez vous à jour !!!
Avatar
Julien (Prof) 26-05-26 08:59
<nav class="navbar navbar-expand-sm navbar-dark bg-dark"> <div class="container-fluid"> <a class="navbar-brand" href={{ path('home') }}>RecetteVie</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarsExample03" aria-controls="navbarsExample03" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarsExample03"> <ul class="navbar-nav me-auto mb-2 mb-sm-0"> <li class="nav-item "> <a class="nav-link {{ app.current_route == 'home' ? 'active' : '' }}" href={{ path('home') }}>Accueil</a> </li> <li class="nav-item "> <a class="nav-link {{ app.current_route == 'app_recipe_show' or app.current_route == 'app_recipe_index' ? 'active' : '' }}" href={{ path('app_recipe_index') }}>Liste Recettes</a> </li> <li class="nav-item "> <a class="nav-link {{ app.current_route == 'app_recipe_create' ? 'active' : '' }}" href={{ path('app_recipe_create') }}>Ajouter une Recette</a> </li> </ul> </div> </div> </nav>
09:01
Avatar
Julien (Prof) 26-05-26 09:54
{% extends 'base.html.twig' %} {% block title %}#{{ recipe.id ~" "~ recipe.slug }}{% endblock %} {% block body %} <div class = "row"> <div align = "center" class= "col-md-6 mx-auto"> <article> <h1>{{ recipe.title | title }}</h1> <p>Temps de préparation : {{ recipe.duration }} min</p> <img src="https://kelianfood.com/wp-content/uploads/2022/11/IMG_3695.jpg" width="500" height="400"> <p>{{ recipe.content | nl2br}} </p> <small> <p>Submitted {{ recipe.createdAt |date }}</p> </small> </article> <div> <a class = "btn btn-primary" href={{ path('app_recipe_edit', {id: recipe.id}) }}>Edit Recipe</a> <a class = "btn btn-danger" href={{ path('app_recipe_delete', {id: recipe.id}) }}>Delete</a> <a class = "btn btn-secondary" href={{ path('app_recipe_index') }}>Go Back</a> </div> </div> </div> {# <p>Créé le {{ recipe.createdAt }} </p> <p>Modifié le {{ recipe.updatedAt }} </p> #} {# <p>Recette crée par {{ user.firstname }} {{ user.lastname }}</p> #} {# {{ dump(app.current_route) }} #} {# <p>Recette crée par {{ user.firstname ~" "~ user.lastname }}</p> #} {% endblock %}
Avatar
Julien (Prof) 26-05-26 10:03
le nouveau bouton delete avec confirmation <a class= "btn btn-danger btn-sm" href={{ path('app_recipe_delete', {id: recipe.id}) }} onclick="return confirm('Are you sure you want to delete this recipe?')">Delete</a>
Avatar
Julien (Prof) 26-05-26 10:22
Avatar
Julien (Prof) 26-05-26 10:36
{% set nbRecipe = recipes|length %} <h1 align="center">Bienvenue dans la liste des Recettes ({{ nbRecipe }})</h1>
10:40
10:42
{{ recipe.title |u.truncate(15,'...',false) }} (edited)
10:45
composer require twig/string-extra composer require knplabs/knp-time-bundle (edited)
Avatar
Julien (Prof) 26-05-26 11:08
11:13
<p>Submitted {{ recipe.createdAt |date('d/m/Y') }}</p> <p>Updated {{ recipe.updatedAt |date('d/m/Y H:i') }}</p>µ
11:14
Avatar
Julien (Prof) 26-05-26 11:22
Avatar
Julien (Prof) 26-05-26 11:34
symfony console make:crud
11:37
@Web Avancé mettez vous à jour
👍 1
Avatar
Julien (Prof) 02-06-26 10:10
Contribute to mafiafricaine/TutoSymfony2026 development by creating an account on GitHub.
Avatar
Julien (Prof) 03-06-26 09:29
Avatar
Julien (Prof) 03-06-26 09:41
'constraints' => new Length(min: 10, minMessage: "Valeur trop petite, 10 minimum")
Avatar
Julien (Prof) 03-06-26 09:50
Avatar
use Symfony\Component\Validator\Constraints as Assert;
Avatar
Julien (Prof) 03-06-26 09:54
Avatar
Julien (Prof) 03-06-26 10:13
Avatar
The Validator is designed to validate objects against constraints. In real life, a constraint could be: The cake must not be burned. In Symfony, constraints are similar: They are assertions that a con…
Avatar
Julien (Prof) 03-06-26 10:54
#[ORM\Column(length: 255)] #[Assert\NotBlank()] #[Assert\Length(min: 10,max: 50)] private ?string $title = null; #[ORM\Column(length: 255)] private ?string $slug = null; #[ORM\Column(type: Types::TEXT)] #[Assert\NotBlank()] #[Assert\Length(min: 20)] private ?string $content = null; #[ORM\Column] private ?\DateTimeImmutable $createdAt = null; #[ORM\Column] private ?\DateTimeImmutable $updatedAt = null; #[ORM\Column(nullable: true)] #[Assert\NotBlank()] #[Assert\Positive()] #[Assert\LessThan(1440)] private ?int $duration = null; (edited)
Avatar
Julien (Prof) 03-06-26 11:03
Avatar
Julien (Prof) 03-06-26 11:21
11:23
#[ORM\Column(length: 255)] #[Assert\NotBlank(message: "Le champ ne peut pas être vide !")] #[Assert\Length(min: 10,max: 50,minMessage: "Le champ doit contenir minimum 10 caractères !", maxMessage: "Le champ doit contenir maximum 50 caractères !")] private ?string $title = null; #[ORM\Column(length: 255)] private ?string $slug = null; #[ORM\Column(type: Types::TEXT)] #[Assert\NotBlank(message: "Oups !! Le champ ne peut pas être vide !")] #[Assert\Length(min: 20,minMessage: "Le champ doit contenir minimum 20 caractères !")] private ?string $content = null; #[ORM\Column] private ?\DateTimeImmutable $createdAt = null; #[ORM\Column] private ?\DateTimeImmutable $updatedAt = null; #[ORM\Column(nullable: true)] #[Assert\NotBlank(message: "Le champ ne peut pas être vide !")] #[Assert\Positive(message: "Le champ doit être positif !")] #[Assert\LessThanOrEqual(1440,message: "Le champ ne doit pas dépasser 24h !")] private ?int $duration = null; (edited)
Avatar
Julien (Prof) 03-06-26 11:40
symfony console make:validator
11:41
InappropriateWords
11:45
Avatar
Julien (Prof) 03-06-26 11:52
Avatar
class InappropriateWordsValidator extends ConstraintValidator { public function validate($value, Constraint $constraint) { /* @var InappropriateWords $constraint */ if (null === $value || '' === $value) { return; } //on met d'abord le mot introduit dans le formulaire en minuscule //on fait ensuite une boucle pour verifié que le mot introduit n'est pas dans notre liste //si il est dans notre liste, il envoi une violation avec notre message définit dans InappropriateWords.php $value = strtolower($value); foreach ($constraint->listWords as $inappropriateWord) { if (str_contains($value, $inappropriateWord)) { $this->context->buildViolation($constraint->message) ->setParameter('{{ inappropriateWord }}', $inappropriateWord) ->addViolation(); } } } }
Avatar
Julien (Prof) 03-06-26 11:56
Avatar
Julien (Prof) 03-06-26 12:05
@Web Avancé mettez vous à jour !!!
Avatar
Julien (Prof) 04-06-26 13:40
Avatar
Julien (Prof) 04-06-26 13:48
Avatar
Julien (Prof) 04-06-26 14:20
<img src = {{ recipe.imageName }} width="150" height="200">
Avatar
Julien (Prof) 04-06-26 14:50
private ?string $imageName = "https://upload.wikimedia.org/wikipedia/commons/a/ac/No_image_available.svg";
14:55
14:58
@Web Avancé Mettez vous à jour 😉
Avatar
Julien (Prof) 04-06-26 15:34
symfony console make:user
Avatar
Julien (Prof) 04-06-26 15:47
Avatar
Julien (Prof) 08-06-26 08:57
Traits
08:58
Timestampable.php
09:00
<?php namespace App\Entity\Traits; use Doctrine\ORM\Mapping as ORM; trait Timestampable { }
Avatar
Julien (Prof) 08-06-26 09:09
09:11
Avatar
Julien (Prof) 08-06-26 09:32
Avatar
Julien (Prof) 08-06-26 09:57
Contribute to mafiafricaine/TutoSymfony2026 development by creating an account on GitHub.
10:15
symfony console security:hash-password
Avatar
Julien (Prof) 08-06-26 10:43
Avatar
symfony console doctrine:query:sql
Avatar
symfony console doctrine:query:sql "SELECT id, title, slug, duration, created_At, updated_At FROM recipes"
Avatar
Julien (Prof) 08-06-26 10:48
Avatar
Julien (Prof) 08-06-26 11:28
symfony console doctrine:query:sql "INSERT INTO users (email, roles, password, firstname, lastname, created_at, updated_at) VALUES ('jamesbond@cfitech.be','[]','mettezMDP hachez','James','Bond',NOW(),NOW())" (edited)
Avatar
Julien (Prof) 08-06-26 11:43
@Web Avancé mettez vous à jour !!
Avatar
Julien (Prof) 10-06-26 08:40
08:41
Avatar
Julien (Prof) 10-06-26 09:18
<p>By {{ recipe.user.firstname ~" "~ recipe.user.lastname }}</p>
09:22
symfony console cache:clear
Avatar
Julien (Prof) 10-06-26 09:48
@Web Avancé mettez vous à jour !!!
Avatar
git add . git commit -m "Premier commit" git branch -M main git remote add origin https://github.com/PSEUDOGITHUB/EXEMPLE.git git push -u origin main
Avatar
ssh-keygen -t ed25519 -C "email@emeil.com"
10:31
cat ~/.ssh/id_ed25519.pub (edited)
10:34
ssh -T git@github.com
Avatar
php -r "echo bin2hex(random_bytes(16));"
10:43
nano .env.local
10:44
composer install --no-dev --optimize-autoloader
10:48
APP_ENV=prod APP_SECRET=une-chaine-aleatoire-de-32-caracteres DATABASE_URL="mysql://PSEUDO:MDP@mysql-PSEUDO.alwaysdata.net/NOM_BDD?serverVersion=8.0&charset=utf8mb4"
10:53
php bin/console cache:clear --env=prod
10:53
php bin/console cache:warmup --env=prod
Avatar
php bin/console doctrine:migrations:migrate --env=prod
11:05
chmod -R 777 var/
11:11
composer require symfony/apache-pack
11:15
git pull composer install --no-dev --optimize-autoloader php bin/console asset-map:compile --env=prod php bin/console cache:clear --env=prod chmod -R 777 var/
Avatar
Julien (Prof) 12-06-26 08:56
@Web Avancé tp symfony
09:07
Avatar
Julien (Prof) 15-06-26 09:22
Avatar
{% if app.user %} <li class="nav-item"> <a class="nav-link {{ app.current_route == 'app_recipe_create' ? 'active' : '' }}" href="{{ path('app_recipe_create') }}" > Add Recipe </a> </li> <li class="nav-item"> <a class="nav-link {{ app.current_route == 'app_account' ? 'active' : '' }}" href="{{ path('app_account') }}" > Account </a> </li> <li class="nav-item"> <a class="nav-link" href="{{ path('app_logout') }}"> Logout </a> </li> {% else %} <li class="nav-item"> <a class="nav-link {{ app.current_route == 'app_register' ? 'active' : '' }}" href="{{ path('app_register') }}" > Sign Up </a> </li> <li class="nav-item"> <a class="nav-link {{ app.current_route == 'app_login' ? 'active' : '' }}" href="{{ path('app_login') }}" > Login </a> </li> {% endif %}`
Avatar
Julien (Prof) 15-06-26 09:33
symfony console make:security:form-login
Avatar
Julien (Prof) 15-06-26 10:17
Avatar
if ($this->getUser()) { $this->addFlash("error", "Already Connected"); return $this->redirectToRoute("home"); }
Avatar
Julien (Prof) 15-06-26 10:21
10:22
Avatar
Julien (Prof) 15-06-26 10:55
config/packages/security.yaml (edited)
Avatar
Julien (Prof) 15-06-26 11:04
Avatar
Julien (Prof) 15-06-26 11:23
11:29
Avatar
Julien (Prof) 15-06-26 11:49
Avatar
Julien (Prof) 15-06-26 12:02
12:02
@Web Avancé mettez vous à jour
Avatar
Julien (Prof) 16-06-26 08:55
09:02
Avatar
Julien (Prof) 16-06-26 09:21
@Web Avancé mettez vous à jour
Avatar
Julien (Prof) 16-06-26 11:36
Modern Email Delivery Platform for developer & product teams. Fast delivery. High inboxing rates. 24/7 expert support. Email API/SMTP for reliable email sending
Avatar
Julien (Prof) 17-06-26 08:47
Avatar
Julien (Prof) 17-06-26 09:02
09:07
composer require symfonycasts/verify-email-bundle symfony console make:registration-form (edited)
Avatar
Julien (Prof) 17-06-26 09:16
noreply@recettevie.be
Avatar
Julien (Prof) 17-06-26 09:32
symfony console doctrine:migrations:diff ensuite pas oublier d'aller commenter symfony console doctrine:migrations:execute "DoctrineMigrations\votreVersion" (edited)
Avatar
Julien (Prof) 17-06-26 10:19
symfony console translation:extract --dump-messages fr (edited)
👍 1
Avatar
Julien (Prof) 17-06-26 10:33
symfony console translation:extract --force fr --format=yaml
Avatar
'There is already an account with this email': 'Il existe déjà un compte avec cet email' 'You should agree to our terms.': 'Vous devez accepter nos conditions.' 'Please enter a password': 'Veuillez entrer un mot de passe' 'Your password should be at least {{ limit }} characters': 'Votre mot de passe doit contenir au moins {{ limit }} caractères'
Avatar
Julien (Prof) 17-06-26 10:57
Avatar
Julien (Prof) 17-06-26 11:32
11:36
@Web Avancé mettez vous à jour Devoir, terminer les exercices
Avatar
Julien (Prof) 22-06-26 15:25
verify_email.yaml
15:28
Avatar
symfonycasts_verify_email: lifetime: 86400
Avatar
Julien (Prof) 22-06-26 15:44
Avatar
Julien (Prof) 23-06-26 08:59
Avatar
if ($this->getUser()) { $this->addFlash('error', 'Already Connected !'); return $this->redirectToRoute('app_account'); }
Avatar
Julien (Prof) 23-06-26 09:24
Avatar
if ($this->getUser()) { /** * @var User $user */ $user = $this->getUser(); if (!$user->isVerified()) { $this->addFlash("info", "Your email address is not verified !"); } }
Avatar
Julien (Prof) 23-06-26 09:44
Avatar
Julien (Prof) 23-06-26 09:59
Avatar
if ($this->getUser()) { if (!$this->getUser()->isVerified()) { $this->addFlash('error', 'You must confirm your email to create Recipe !'); return $this->redirectToRoute('app_recipe_index'); } } else { $this->addFlash('error', 'You must login to create Recipe !'); return $this->redirectToRoute('app_login'); }` (edited)
Avatar
Julien (Prof) 23-06-26 10:43
Avatar
Julien (Prof) 23-06-26 10:54
Avatar
Julien (Prof) 23-06-26 11:21
Avatar
Julien (Prof) 23-06-26 11:34
Avatar
Julien (Prof) 23-06-26 12:04
@Web Avancé mettez vous à jour !!! Cours du 22 et 23 juin !!! (edited)
Avatar
Julien (Prof) 26-06-26 09:04
{% if app.user and app.user.email is same as (recipe.user.email) %} <a class="btn btn-primary btn-sm" href={{ path('app_recipe_edit', {id: recipe.id}) }}>Edit Recipe</a> <a class= "btn btn-danger btn-sm" href={{ path('app_recipe_delete', {id: recipe.id}) }} onclick="return confirm('Are you sure you want to delete this recipe?')">Delete</a> {% endif %}`
09:06
Avatar
Julien (Prof) 26-06-26 09:14
Avatar
Julien (Prof) 26-06-26 10:14
composer req symfonycasts/reset-password-bundle symfony console make:reset-password (edited)
10:19
noreplypasswordreset@recettevie.be
10:20
RecetteVie Reset PW
Avatar
Julien (Prof) 26-06-26 10:38
Avatar
Julien (Prof) 26-06-26 10:50
Avatar
Julien (Prof) 26-06-26 11:55
Projet perso symfony -------------------- Stefania : formule 1 Mariam : basket Cédric : quiz Ceyhun : specialisation Stick arcade Nisrine : newsletter Mouhcine : pinterest Trinitas : agence de voyage Paul : immobilier Komlan : vinted Ibrahima : centre de formation Ismail : basket Hajar : bibliotheque Login, register, gerer autorisation, mailtrap, reset password, traduction (dans une langue autre que l'anglais). @Web Avancé A faire pour le 6 Juillet !! (edited)
11:59
@Web Avancé @Hajar @ismadmh mettez vous à jour
🙏 1
Avatar
Julien (Prof) 30-06-26 09:34
Avatar
Julien (Prof) 30-06-26 09:46
symfony console translation:extract --force fr --format=yaml (edited)
09:47
09:49
Avatar
<?php namespace App\Form; use App\Entity\User; use Doctrine\DBAL\Types\TextType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class UserFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('firstname', TextType::class, ["label" => "userForm.firstname"]) ->add('lastname', TextType::class, ["label" => "userForm.lastname"]) ; } public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => User::class, ]); } }
Avatar
Julien (Prof) 30-06-26 09:55
#[Route('/account/edit', name: "app_account_edit")] public function edit(Request $request, EntityManagerInterface $em, TranslatorInterface $translator): Response{ $user=$this->getUser(); $form = $this->createForm(UserFormType::class, $user); $form->handleRequest($request); if($form->isSubmitted() && $form->isValid()){ $user->setUpdatedAt(new DateTimeImmutable()); $em->flush(); $this->addFlash('success', $translator->trans('Account successfuly updated !')); return $this->redirectToRoute('app_account'); } return $this->render('account/edit.html.twig', [ 'user' => $user, 'usermonForm' => $form->createView() ]); }
Avatar
Julien (Prof) 01-07-26 08:49
Avatar
{% extends 'base.html.twig' %} {% block title 'Update Profile' %} {% block body %} <div class="row"> <div class="col-md-6 mx-auto text-center"> <h1 class="text-center my-5">{{ 'Update Profile'|trans }}</h1> {{ form_start(userForm) }} {{ form_row(userForm.firstname) }} {{ form_row(userForm.lastname) }} <br> <p> <button type="submit" class="btn btn-primary"> {{ 'Apply changes'|trans }} </button> </p> {{ form_end(userForm) }} </div> </div> {% endblock %}
Avatar
Julien (Prof) 01-07-26 08:59
href={{ path('app_account_edit') }}
Avatar
Julien (Prof) 01-07-26 09:12
Avatar
Julien (Prof) 01-07-26 09:48
The PHP Package Repository
09:49
A simple Symfony bundle to ease file uploads with ORM entities and ODM documents. - dustin10/VichUploaderBundle
09:56
mettez vous à jour les absents
Avatar
Avatar
Julien (Prof)
Projet perso symfony -------------------- Stefania : formule 1 Mariam : basket Cédric : quiz Ceyhun : specialisation Stick arcade Nisrine : newsletter Mouhcine : pinterest Trinitas : agence de voyage Paul : immobilier Komlan : vinted Ibrahima : centre de formation Ismail : basket Hajar : bibliotheque Login, register, gerer autorisation, mailtrap, reset password, traduction (dans une langue autre que l'anglais). @Web Avancé A faire pour le 6 Juillet !! (edited)
Julien (Prof) 06-07-26 12:15
C'est aujourd'hui la présentation projet @Web Avancé Je rappel que pour passer l'UAA final il faudra avoir passé, l'UAA Symfony qui pour la passer, il faudra avoir fait le projet durant les vacances (aout), qui pour pouvoir le faire il faudra faire tous les projets demandé dont celui d'aujourd'hui. En gros ce charabia pour dire, ceux qui ne présenteront/feront pas leur projets, ne passeront pas les UAA qui concernent mes cours 😉 (edited)
👌 1
Avatar
Julien (Prof) 06-07-26 14:15
@Web Avancé Attention la présentation BIS ce sera mercredi !!! après plus de présentation possible. Je vous impose de rajouter vichUpload pour vos images. (edited)
Avatar
composer require knplabs/knp-paginator-bundle
Avatar
Julien (Prof) 06-07-26 15:58
terminer le TP pour demain
👍 1
Avatar
Julien (Prof) 07-07-26 10:47
@KnpPaginator/Pagination/bootstrap_v5_pagination.html.twig
10:47
Avatar
Julien (Prof) 07-07-26 10:59
Contribute to mafiafricaine/TutoSymfony2026 development by creating an account on GitHub.
11:00
base de données avec images correspondant à mon projet
11:05
dans RecipeRepository les imports use App\Model\SearchData; ... /** *@param SearchData $searchData *@return PaginationInterface */ public function findBySearch(SearchData $searchData): PaginationInterface { $data = $this->createQueryBuilder('r'); if (!empty($searchData->q)) { $data = $data ->andWhere("r.title LIKE :q") ->setParameter("q", "%{$searchData->q}%"); } $data = $data ->getQuery() ->getResult(); $recipes = $this->paginatorInterface->paginate($data, $searchData->page, 6); return $recipes; } (edited)
11:09
Avatar
app: resource: '../src/Controller/' type: attribute prefix: /{_locale} requirements: _locale: en|fr
Avatar
Julien (Prof) 08-07-26 11:15
Pour que la redirection fonctionne quand vous lancer votre site. Rajouter ceci au dessus de app et ajouter dans app le defaults... root_redirect: path: / defaults: _controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction path: /en permanent: false app: resource: '../src/Controller/' type: attribute prefix: /{_locale} requirements: _locale: en|fr defaults: _locale: en
👍 1
Avatar
Julien (Prof) 08-07-26 11:28
<div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> {% if app.request.locale == 'en' %} <span class="flag">🇬🇧</span> English {% else %} <span class="flag">🇫🇷</span> Français {% endif %} </button> <ul class="dropdown-menu"> <li> <a class="dropdown-item" href="{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge({'_locale': 'en'})) }}"> <span class="flag">🇬🇧</span> English </a> </li> <li> <a class="dropdown-item" href="{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge({'_locale': 'fr'})) }}"> <span class="flag">🇫🇷</span> Français </a> </li> </ul> </div>
Avatar
Julien (Prof) 08-07-26 12:05
@Web Avancé Pour le prochain cours continuer les projets rajouter pagination + recherche (edited)
👌 1
12:06
Pour gagner un V
Avatar
Julien (Prof) 15-07-26 08:53
Create REST and GraphQL APIs, scaffold Jamstack webapps, stream changes in real-time.
08:55
composer require api
Avatar
Julien (Prof) 15-07-26 09:14
Avatar
Try Postman for free! Join 40 million users who rely on Postman, the collaboration platform for API development. Create better APIs—faster.
Avatar
Julien (Prof) 15-07-26 11:07
application/ld+json
Avatar
{ "title" : "Recette Postamn", "slug" : "recette-postman", "content" : "Voici la rectte que j'ai créé avec postman", "duration" : 150, "user" : "/api/users/2" }
Avatar
Julien (Prof) 15-07-26 11:31
{ "email" : "zidane@cfitech.be", "password" : "VOTRE MDP HACHÉ", "firstname" : "Zinedine", "lastname" : "Zidane", "isVerified" : true } (edited)
Avatar
zidane
Avatar
Julien (Prof) 15-07-26 11:50
application/merge-patch+json
Avatar
Julien (Prof) 15-07-26 12:03
@Web Avancé mettez vous à jour !!!
Avatar
Julien (Prof) 16-07-26 09:04
lexik jwt
09:07
composer req lexik/jwt-authentication-bundle --ignore-platform-req=ext-sodium symfony console lexik:jwt:generate-keypair (edited)
Avatar
Julien (Prof) 16-07-26 09:34
Avatar
login: pattern: ^/api/login stateless: true json_login: check_path: /api/login_check success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure api: pattern: ^/api stateless: true jwt: ~
Avatar
Julien (Prof) 16-07-26 09:42
Avatar
access_control: # - { path: ^/admin, roles: ROLE_ADMIN } # - { path: ^/profile, roles: ROLE_USER } - { path: ^/api/login, roles: PUBLIC_ACCESS } - { path: ^/api/users, roles: PUBLIC_ACCESS, methods: [POST] } - { path: ^/api/recipes, roles: PUBLIC_ACCESS, methods: [GET] } - { path: ^/api/, roles: IS_AUTHENTICATED_FULLY } (edited)
Avatar
Julien (Prof) 16-07-26 09:57
api_login_check: path: /api/login_check
Avatar
Julien (Prof) 16-07-26 10:24
Test_Api_Jwt
10:27
Environnement_Test_Api_Jwt
Avatar
Julien (Prof) 16-07-26 10:54
251.23 KB
Avatar
Julien (Prof) 16-07-26 11:34
JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).
Avatar
Julien (Prof) 16-07-26 12:03
@Web Avancé mettez vous à jour
Avatar
Julien (Prof) 22-07-26 09:05
What do you want for me, Michael ?
Tuto déploiement site alwaysdata
6 votes 55 % Selected
Parlementé du projet d'été
5 votes 45 %
09:06
@Web Avancé
Julien (Prof) 's poll What do you want for me, Michael ? has closed. 22-07-26 10:06
Tuto déploiement site alwaysdata Winning answer
Winning answer 55 %
View Poll
Avatar
Julien (Prof) 22-07-26 10:58
Voici le projet à faire durant votre période de non cours. Suivez les consignes pour la remise et la présentation du projet. A remettre au maximum pour le 30 Aout 23h59. Attention je rappel que vous n'êtes pas en vacances réellement donc pour pouvoir être rémunérer il faut faire les projets demandé !!! Pas de projet => pas de paiement, pas de projet symfony => pas d'UAA symfony @Web Avancé (edited)
Avatar
Julien (Prof) 27-08-26 13:45
Avatar
Julien (Prof) 27-08-26 14:21
pm.environment.set("id", pm.response.json().id) pm.environment.set("userIdentifier", pm.response.json().userIdentifier) pm.test("Status test", function() { pm.response.to.have.status(201) })
Avatar
Julien (Prof) 27-08-26 14:53
Avatar
Julien (Prof) 28-08-26 08:38
@Web Avancé Le cours du 27 aout Les absents, mettez vous à jour !!! Je rappel que lundi présentation de vos projets de vacances 😉
Avatar
Julien (Prof) 31-08-26 07:52
@Web Avancé vous avez jusqu'à midi pour m'envoyer le projet
07:55
Je rappel pas de projet, pas d'uaa, pas de paiement !
Avatar
Julien (Prof) 31-08-26 08:44
@Web Avancé Vous pouvez m'envoyer juste le github si vous n'arrivez pas à deployer !!!
08:46
attention n'oubliez pas la base de données
Avatar
Julien (Prof) 31-08-26 10:40
exo1 pm.test("Status Connecté", function() { if (pm.response.to.have.status(200)){ pm.environment.set("token", pm.response.json().token); } })
Avatar
ou pm.test("Status code is 200", function () { pm.response.to.have.status(200) && pm.environment.set("token", pm.response.json().token) });
Avatar
Julien (Prof) 31-08-26 11:00
exo3 pm.test("Status create recipe + save id last recipe", function() { if (pm.response.to.have.status(201)){ pm.environment.set("idLastRecipe", pm.response.json().id); } }) (edited)
11:02
11:03
Avatar
Julien (Prof) 31-08-26 11:22
❤️ 1
11:23
Avatar
Julien (Prof) 31-08-26 11:30
pm.test("Status creation admin + save ENV id and userIdentifier", function() { if(pm.response.to.have.status(201)){ pm.environment.set("idAdmin", pm.response.json().id); pm.environment.set("admin", pm.response.json().userIdentifier); } })
11:33
@Web Avancé Absent mettez vous à jour
Avatar
Julien (Prof) 02-09-26 10:47
Avatar
Julien (Prof) 02-09-26 11:25
Avatar
Julien (Prof) 02-09-26 12:02
@Web Avancé Voici le dernier pdf de mon cours
🎉 1
👍 1
🙏 1
Exported 379 message(s)
Timezone: UTC+1