4 juillet 2020 - : Tutoriel Symfony Live-Coding - Tutoriel Controllers Framework Routes Symfony Live-Coding Formulaires

Visualisez les fichiers de cette série sur GitHub

Nous allons traiter dans cet article de la création d'une interface d'administration de notre site, mais sans aucun bundle.

Nous allons utiliser notre contrôleur "AdminController" créé précédemment, et y apporter des modifications, tout comme à la structure générale du dossier "src/Controller".

Structure des dossiers

Dans le dossier "src/Controller", nous allons créer un nouveau dossier appelé "Admin". Ce dossier contiendra tous les contrôleurs relatifs à l'administration.

Nous allons également déplacer le fichier AdminController.php dans le dossier Admin.

Suite à ce déplacement, nous allons devoir modifier le namespace dans ce fichier

namespace App\Controller\Admin;

Sécurité

Nous allons ensuite protéger l'accès à toutes les routes d'administration (commençant par /admin) en modifiant le fichier "config/packages/security.yaml" comme ceci

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: ^/users, roles: ROLE_USER }

Avec ce changement, seuls les utilisateurs ayant le "ROLE_ADMIN" pourront accéder à ces routes. Un utilisateur non connecté arrivera sur la page de connexion.

Séparer les contrôleurs

Afin d'avoir une structure logique dans le dossier Admin, nous allons séparer les méthodes dans des contrôleurs différents. J'ai réalisé cette action en utilisant l'option "Enregistrer sous" de mon éditeur mais on peut également créer les contrôleurs manuellement.

Il faudra s'assurer que le namespace de chaque contrôleur soit bien dans le bon namespace et ensuite dans la route principale /admin.

Le contrôleur des catégories contiendra donc le code suivant

<?php

namespace App\Controller\Admin;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

/**
 * @Route("/admin/categories", name="admin_categories_")
 * @package App\Controller\Admin
 */
class CategoriesController extends AbstractController
{
    /**
     * @Route("/", name="home")
     */
    public function index()
    {
        return $this->render('admin/categories/index.html.twig', [
            'controller_name' => 'CategoriesController'
        ]);
    }
}

A compter de ce moment, vous avez accès à la route "/admin/categories".

Afficher les données

Nous souhaitons avoir un tableau affichant la liste des catégories sous forme de tableau.

Dans un premier temps, nous allons modifier la méthode "index" du contrôleur pour transmettre les données à notre vue. Nous intégrerons le repository à notre contrôleur et ajouterons un "findAll".

/**
 * @Route("/", name="home")
 */
public function index(CategoriesRepository $catsRepo)
{
    return $this->render('admin/categories/index.html.twig', [
        'categories' => $catsRepo->findAll()
    ]);
}

On créera également les méthodes pour les routes "/ajout" et "/modifier"

/**
 * @Route("/ajout", name="ajout")
 */
public function ajoutCategorie(Request $request)
{
    $categorie = new Categories;

    $form = $this->createForm(CategoriesType::class, $categorie);

    $form->handleRequest($request);

    if($form->isSubmitted() && $form->isValid()){
        $em = $this->getDoctrine()->getManager();
        $em->persist($categorie);
        $em->flush();

        return $this->redirectToRoute('admin_categories_home');
    }

    return $this->render('admin/categories/ajout.html.twig', [
        'form' => $form->createView()
    ]);
}

/**
 * @Route("/modifier/{id}", name="modifier")
 */
public function ModifCategorie(Categories $categorie, Request $request)
{
    $form = $this->createForm(CategoriesType::class, $categorie);

    $form->handleRequest($request);

    if($form->isSubmitted() && $form->isValid()){
        $em = $this->getDoctrine()->getManager();
        $em->persist($categorie);
        $em->flush();

        return $this->redirectToRoute('admin_categories_home');
    }

    return $this->render('admin/categories/ajout.html.twig', [
        'form' => $form->createView()
    ]);
}

Nous allons ensuite modifier le fichier twig "/templates/admin/categories/index.html.twig" afin d'y intégrer le tableau, un bouton d'ajout et un bouton de modification, ce qui donnera le code ci-dessous.

{% extends 'base.html.twig' %}

{% block title %}Gérer les catégories{% endblock %}

{% block body %}
	<h1>Gérer les catégories</h1>
    <a href="{{ path("admin_categories_ajout") }}" class="btn blue">Ajouter une catégorie</a>
	<table class="table striped">
		<thead>
			<tr>
				<th>ID</th>
				<th>Nom</th>
				<th>Parent</th>
				<th>Actions</th>
			</tr>
		</thead>
		<tbody>
        {% for categorie in categories %}            
			<tr>
				<td>{{categorie.id}}</td>
				<td>{{categorie.name}}</td>
				<td>{{categorie.parent}}</td>
				<td class="text-center">
                    <a href="{{ path("admin_categories_modifier", {id: categorie.id}) }}" class="btn blue">Modifier</a>
                </td>
			</tr>
        {% endfor %}
		</tbody>
	</table>
{% endblock %}

Ajouter les données

Nous créerons enfin le formulaire permettant de gérer l'ajout et la modification de catégories (créé dans une vidéo précédente)

<?php

namespace App\Form;

use App\Entity\Categories;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ColorType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class CategoriesType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class)
            ->add('color', ColorType::class)
            ->add('parent')
            ->add('Valider', SubmitType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Categories::class,
        ]);
    }
}

La méthode sera similaire pour toute entité et toute page d'administration (avec adaptation aux propriétés)

Obtenir de l'aide

Pour obtenir de l'aide, vous pouvez accéder au serveur Discord pour une entraide par chat.

Visualisez les fichiers de cette série sur GitHub

Partager

Partager sur Facebook Partager sur Twitter Partager sur LinkedIn