



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)
symfony new TutoSymfony
cd TutoSymfony
composer require webapp (edited)
symfony new TutoSymfony --webappsymfony php -v
symfony local:php:list
echo 8.*.* > .php-version (edited)
symfony server:start
symfony server:start -d
(ou le raccourci symfony serve -d)
symfony open:local (edited)
symfony server:stop (Si ça ne fonctionne pas faites Ctrl+C dans votre terminal)symfony server:listsymfony server:ca:install (accepter le certificat)

symfony console 
symfony console make:controller Home
#[Route(path : "/", name : "home")]
public function index(): Response{
return new Response("Hello World !!!");
} (edited)home:
path: /
controller: App\Controller\HomeController::index
#[Route(path :"/", name : "home")]
public function index(): Response{
return new Response("Hello ".$_GET['nom']);
}use Symfony\Component\HttpFoundation\Request;
#[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"));
}
#[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"));
}



#[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);
}
//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
]);
}symfony console debug:router

#[Route(path : "/recette", name : "app_recipe_index")]
public function index(): Response{
return $this->render('recipe/index.html.twig');
}

<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)
#[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');
}

#[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)<p>Auteur : {{ user.firstname}}</p> (edited)
<h4>Comment faire un/une {{ slug | title }}</h4>
<a class="navbar-brand" href={{ url('home') }}>Acceuil</a> (edited)
"emmet.includeLanguages": {
"twig": "html",
},
<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>


<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">© 2026 Cfitech, Inc</p>
</footer>
</div>


<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>

symfony console doctrine:database:create
symfony console doctrine:database:drop --force (edited)
symfony console make:entity
symfony console make:entity NomDeVotreEntité (edited)






symfony console make:migration 
symfony console doctrine:migrations:migrate 



#[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"
]
]);
}
{% 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 %}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
]);
}





{% 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 %}
{% block title %}#{{ recipe.id ~" "~ recipe.slug }}{% endblock %} (edited)

$em->persist($recipe);
$em->flush(); (edited)




#[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)
symfony console make:form Recipe









#[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
]);
}

#[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
]);
}




{% 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 %}{% 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)

<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>
{% 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 %}
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>

{% set nbRecipe = recipes|length %}
<h1 align="center">Bienvenue dans la liste des Recettes ({{ nbRecipe }})</h1>{{ recipe.title |u.truncate(15,'...',false) }} (edited)composer require twig/string-extra
composer require knplabs/knp-time-bundle (edited)
<p>Submitted {{ recipe.createdAt |date('d/m/Y') }}</p>
<p>Updated {{ recipe.updatedAt |date('d/m/Y H:i') }}</p>µ

symfony console make:crud


'constraints' => new Length(min: 10, minMessage: "Valeur trop petite, 10 minimum")

use Symfony\Component\Validator\Constraints as Assert;



#[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)

#[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)

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();
}
}
}
}





<img src = {{ recipe.imageName }} width="150" height="200">
private ?string $imageName =
"https://upload.wikimedia.org/wikipedia/commons/a/ac/No_image_available.svg";
symfony console make:user

<?php
namespace App\Entity\Traits;
use Doctrine\ORM\Mapping as ORM;
trait Timestampable
{
}



symfony console security:hash-password 




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)


<p>By {{ recipe.user.firstname ~" "~ recipe.user.lastname }}</p>symfony console cache:clear







{% 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 %}`
symfony console make:security:form-login

if ($this->getUser()) {
$this->addFlash("error", "Already Connected");
return $this->redirectToRoute("home");
}










composer require symfonycasts/verify-email-bundle
symfony console make:registration-form (edited)

symfony console doctrine:migrations:diff
ensuite pas oublier d'aller commenter
symfony console doctrine:migrations:execute "DoctrineMigrations\votreVersion" (edited)

symfony console translation:extract --force fr --format=yaml










if ($this->getUser()) {
/**
* @var User $user
*/
$user = $this->getUser();
if (!$user->isVerified()) {
$this->addFlash("info", "Your email address is not verified !");
}
}


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)





{% 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 %}`

composer req symfonycasts/reset-password-bundle
symfony console make:reset-password (edited)




symfony console translation:extract --force fr --format=yaml (edited)
<?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,
]);
}
}
#[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()
]);
}

{% 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 %}
href={{ path('app_account_edit') }}






composer require knplabs/knp-paginator-bundle


@KnpPaginator/Pagination/bootstrap_v5_pagination.html.twig

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)
app:
resource: '../src/Controller/'
type: attribute
prefix: /{_locale}
requirements:
_locale: en|fr
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
<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>

composer require api





{
"email" : "zidane@cfitech.be",
"password" : "VOTRE MDP HACHÉ",
"firstname" : "Zinedine",
"lastname" : "Zidane",
"isVerified" : true
} (edited)



composer req lexik/jwt-authentication-bundle --ignore-platform-req=ext-sodium
symfony console lexik:jwt:generate-keypair (edited)

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: ~

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)








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)
})




pm.test("Status Connecté", function() {
if (pm.response.to.have.status(200)){
pm.environment.set("token", pm.response.json().token);
}
})
pm.test("Status code is 200", function () {
pm.response.to.have.status(200) && pm.environment.set("token", pm.response.json().token)
});
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)

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);
}
})

