Bien débuter avec le Framework Silex – Les contraintes de routes ou routes avec paramètres

11 décembre 2017 - : Pas de commentaire

Bien débuter avec le Framework Silex – Les contraintes de routes ou routes avec paramètres

Dans les articles précédents, nous avons traité de divers sujets comme la création de routes, l’accès à la base de données ou encore les sessions utilisateurs.

Il nous manque cependant un aspect primordial du MVC à savoir les contraintes de routes, souvent appelées routes avec paramètres.

En effet, il arrive très souvent que certaines parties de nos routes soient variables en fonction du contexte.

Si nous prenons l’exemple d’une route qui afficherait le contenu des articles d’un blog, il serait contraignant de devoir manuellement créer une route pour chacun d’entre eux.

Afin de simplifier les choses, les frameworks MVC proposent de passer une variable dans la route afin de pouvoir gérer cette contrainte.

Ainsi, si on devait appeler les articles par des routes

  • /blog/1
  • /blog/2
  • /blog/1234

Nous n’aurions qu’à insérer l’ID de l’article comme variable d’entrée (contrainte) de notre route. Le contrôleur récupèrera cette valeur et traitera les données.

Dans l’exemple ci-dessus, le code de notre contrôleur serait le suivant

// Nous attribuons la variable {id} à notre route
// Celle-ci est utilisée en entrée de notre contrôleur sous le nom $id
$app->get('/blog/{id}', function ($id) use ($app){
	// On instancie le modèle
    $articlesModel = new articlesModels();
	// On récupère l'article sur la base de son id
	$article = $articlesModel->getArticle($app , $id);
    // Si on a une correspondance
	if($article){
		// On affiche le résultat
        return $app['twig']->render('article.html.twig', array('article' => $article, 'message' => '', 'user' => $app['session']->get('user')));
    }else{
		// Sinon on transmet un message d'erreur
        return $app['twig']->render('article.html.twig', array('article' => '', 'message' => 'Pas d\'article correspondant', 'user' => $app['session']->get('user')));
    }
})
->bind('article')
;
Langage : PHP - Fichier src/articlesControllers.php

Pour que ceci fonctionne, nous devons ajouter la fonction getArticle à notre modèle

public function getArticle($app, $id){
	// Préparation de la requête avec filtrage sur l'id
	$sql = "SELECT articles.*, utilisateurs.pseudo FROM articles LEFT JOIN utilisateurs ON articles.utilisateurs_userid = utilisateurs.userid WHERE id = :id";
	$query = $app['db']->prepare($sql);
	$query->bindValue(':id', $id, PDO::PARAM_INT);
	$query->execute();
	return $query->fetch();
}
Langage : PHP - Fichier src/articlesModels.php

Enfin, nous devons créer notre vue qui sera contenue dans le fichier article.html.twig

{% extends "layout.html.twig" %}

{% block content %}
	<!-- Si le message n'est pas vide -->
	<% if message != "" %>
		<p>{{ message }}</p>
	<% endif %>
	<!-- Si l'article n'est pas vide -->
	<% if article != "" %>
		<!-- Pas de boucle étant donné que nous n'avons qu'un article -->
		<h2>{{ article.titre }}</h2>
		<!-- Le champ date_article est mis en forme par la fonction date() -->
		<p>Publié le {{ article.date_article|date('d/m/Y') }} par {{ article.pseudo }}</p>
		<p>{{ article.contenu }}</p>
	<% endif %>
	<p><a href="{{ path('monblog') }}">Liste des articles</a></p>
{% endblock %}
Langage : HTML/Twig - Fichier templates/article.html.twig

Afficher les commentaires

Si nous mettons en œuvre un système de commentaires, il serait judicieux de les afficher sur la même page que l’article auquel ils correspondent.

Nous allons pouvoir facilement les extraire de la base de données, ceux-ci étant liés à leur article par son id.

Ainsi, nous allons modifier notre contrôleur comme suit

// Nous attribuons la variable {id} à notre route
// Celle-ci est utilisée en entrée de notre contrôleur sous le nom $id
$app->get('/blog/{id}', function ($id) use ($app){
	// On instancie le modèle articles
    $articlesModel = new articlesModels();
	// On récupère l'article sur la base de son id
	$article = $articlesModel->getArticle($app , $id);
	// Si on a un article
	if($article){
		// On instancie le modèle comments
		$commentsModel = new commentsModels();
		// On récupère les commentaires sur la base de l'id de l'article
		$comments = $commentsModel->getComments($app, $id);
		// On affiche le résultat en passant également les commentaires éventuels
		return $app['twig']->render('article.html.twig', array('article' => $article, 'comments'=>$comments, 'message' => '', 'user' => $app['session']->get('user')));
    }else{
		// Sinon on transmet un message d'erreur
        return $app['twig']->render('article.html.twig', array('article' => '', 'comments'=>'', 'message' => 'Pas d\'article correspondant', 'user' => $app['session']->get('user')));
    }
})
->bind('article')
;
Langage : PHP - Fichier src/articlesControllers.php

Bien sûr, vous aurez remarqué que nous allons instancier un nouveau modèle (commentsModels), que nous allons donc créer

use Doctrine\DBAL\Connection;

class commentsModels {
    public function getComments($app, $article_id){
		// Préparation de la requête avec jointure gauche pour gérer la relation entre l'article et ses commentaires par l'id de l'article
        $sql = "SELECT commentaires.*, utilisateurs.pseudo FROM commentaires LEFT JOIN utilisateurs ON commentaires.utilisateurs_userid = utilisateurs.userid WHERE articles_id = :articleid";
        $query = $app['db']->prepare($sql);
        $query->bindValue(':articleid', $article_id, PDO::PARAM_INT);
        $query->execute();
        return $query->fetchAll();
    }
}
Langage : PHP - Fichier src/commentsModels.php

Et enfin, nous allons devoir modifier notre vue pour qu’elle affiche les commentaires éventuels

{% extends "layout.html.twig" %}

{% block content %}
	<!-- Si le message n'est pas vide -->
	<% if message != "" %>
		<p>{{ message }}</p>
	<% endif %>
	<!-- Si l'article n'est pas vide -->
	<% if article != "" %>
		<!-- Pas de boucle étant donné que nous n'avons qu'un article -->
		<h2>{{ article.titre }}</h2>
		<!-- Le champ date_article est mis en forme par la fonction date() -->
		<p>Publié le {{ article.date_article|date('d/m/Y') }} par {{ article.pseudo }}</p>
		<p>{{ article.contenu }}</p>
		<h3>Voici les commentaires</h3>
		<!-- Nous allons boucler sur les commentaires -->
		{% for comment in comments %}
			<p>{{comment.pseudo}} a écrit : {{comment.contenu}}</p>
		<!-- Twig nous permet d'ajouter une clause "else" à une boucle
			 Celle-ci permet de gérer l'absence de contenu dans la variable -->
		{% else %}
			<p>Pas de commentaires</p>
		{% endfor %}
	<% endif %>
	<p><a href="{{ path('monblog') }}">Liste des articles</a></p>
{% endblock %}
Langage : HTML/Twig - Fichier templates/article.html.twig

Voilà, cet article est le 5ème d’une série permettant d’apprendre pas à pas l’utilisation de Silex.

Nous verrons dans un prochain article comment ajouter le formulaire permettant de publier un commentaire et un article en fonction des permissions de l’utilisateur.

Commentaires

Ecrire un commentaire

Pas encore de commentaire

Laisser un commentaire