Bonjour,

J'ai longuement échangé sur le sujet sur le channel (sous un autre pseudo, certes), mais je souhaite revenir sur ce point qui reste pour moi problématique.

Pour faire simple...

J'ai souhaite développer une nouvelle fonctionnalité "feedback" pour un module qui existe déjà dans mon application (tickets). Cette fonctionnalité a pour but d'envoyer automatiquement - 24h après la clôture d'un ticket - un mail aux utilisateurs liés au ticket en question. Un lien sera présent dans le mail et redirigera l'utilisateur vers une page spécifique de l'application. L'utilisateur pourra alors noter l'échange (système d'étoile + textarea pour laisser un commentaire).

La question que je me pose est simple... faut-il développer cette fonctionnalité directement dans le contrôleur Tickets, en créant une nouvelle action de type Feedback... ou faut-il développer un contrôleur Feedbacks spécialement pour cette fonctionnalité ?

@Grafikart m'a répondu qu'il était conseillé de créer un contrôleur spécialement pour ça (la seconde solution).

Le soucis là dedans, c'est que l'url sera de ce type : site.fr/feedbacks/ticket/3709ADS7289EJZA38ZAW83 ! C'est ce lien qui sera envoyé dans le mail. En sachant que ce lien ne servira qu'à donner une note et à laisser un commentaire.

Pour moi avoir un retour sur cette note et ce commentaire (en plus du fait qu'un mail me sera envoyé automatiquement dès qu'un utilisateur aura posté les informations), j'irai sur l'url suivante : site.fr/tickets/view/3709ADS7289EJZA38ZAW83... ce qui aura pour but de me donner les informations sur le ticket, la note et le commentaire.

Le truc, c'est que si je souhaite modifier ou supprimer cette note et ce commentaire (je souhaite avoir cette possibilité, je souhaite avoir la main sur ces informations)... je passe par quel contrôleur et par quelle action pour faire ça ? Je ne vois pas du tout !

J'attends vos retours.

PS : Même s'il s'agit d'une question plus ou moins en lien avec les framework, je me suis permis de la poster dans la section PHP... car elle ne dépend pas d'un framework particulier. Si ça pose un problème, merci de déplacer le sujet.

11 réponses


betaWeb
Réponse acceptée

Salut,

Je pense que le mieux est de prévoir un controller spécifique avec toute la logique. Pars du principe que tu pourrais éventuellement réutiliser ce module ailleurs que pour les tickets ;)
Et puis il suffira d'inclure la classe dans ton ticketsController et de créer une méthode feedback dans laquelle on imagine instancier une nouvelle instance de ta classe feekback (le controller), si tu préfères faire ainsi.
Il y a pleins de façons de faire, mais séparer la logique dans une classe distincte me paraît être la meilleure chose à faire point de vue scalabilité et maintenabilité.

salut,

La logique est plutôt simple cela devrait être le controller Feedbacks, l'action ticket et en paramètre le hash "3709ADS7289EJZA38ZAW83".

oez
Auteur

@fital, je ne pense pas... l'url site.fr/feedbacks/ticket/3709ADS7289EJZA38ZAW83, sera l'url qui sera utilisée par l'utilisateur pour laisser une note et un commentaire (lien envoyé par mail). mis à part en passant un paramètre en plus (site.fr/feedbacks/ticket/3709ADS7289EJZA38ZAW83/update ou site.fr/feedbacks/ticket/3709ADS7289EJZA38ZAW83/delete)... je ne vois pas trop comment une même action pourrait gérer aussi bien l'ajout, la modification et la suppression. je ne suis même pas sûr que cette façon de faire respecte le modèle mvc.

@betaWeb, ok... imaginons que je souhaite avoir la même fonctionnalité pour un autre de mes modules... disons le module discussions... je vais avoir une url du genre site.fr/feedbacks/discussion/4509ADS7289EJZA38ZAB19, l'utilisateur sera redirigé vers une page spécifique de l'application (url donnée précédemment) et tout le tralala... le fonctionnement sera donc exactement le même que ce qui a été précisé dans mon premier message. le soucis de l'url update / delete reste donc le même. l'autre point négatif, c'est que cela veut dire que je vais avoir deux actions dans le contrôleur Feedbacks qui feront la même chose... c'est pas très DRY tout ça ?!

<?php

class FeedbacksController extends AppController {

   public function ticket($hash) {
        // code pour le système de note + commentaire du module Tickets
   }

   public function discussion($hash) {
        // code pour le système de note + commentaire du module Discussions
   }

}

?>

je cherche à comprendre et à trouver la meilleure solution.

Tu n'as pas compris où je voulais en venir ^^
Je pensais tout simplement à ton controller feedBackController dans lequel tu places toute la logique (communication avec la BD, validation etc), et vu que tu voulais absolument que ton URL contienne le nom du controller pour lequel tu souhaites avoir un feedback je te donnais une piste. Après, pour moi, le mieux ext vraiment de TOUT faire dans le feedBackController et avoir une URL qui redirige vers celui-ci. Et dans ta BDD suffit d'avoir ton type de feedback (ex. ticket, discussion etc).
Tu me suis ?

Tu utilises un framework au fait ?

oez
Auteur

@betaWeb, concrètement :

<?php

class FeedbacksController extends AppController {

   public function create($module, $hash) {
        // code pour ajouter un enregistrement (== lien envoyé par mail ?)
        // ce qui donnerait site.fr/feedbacks/create/ticket/3709ADS7289EJZA38ZAW83 
        // ou site.fr/feedbacks/create/discussion/4509ADS7289EJZA38ZAB19
   }

   public function read($module, $hash) {
        // code pour lire un enregistrement
        // pour moi cela n'a pas vraiment de sens ici, la lecture sera possible que pour un administateur ou un superviseur... 
        // un client ne pourra pas lire un feedback... surtout que je souhaite que le feedback soit affiché 
        // en même temps (même vue) que l'affichage d'un ticket ou d'une discussion par un administrateur ou superviseur... 
        // cela veut dire qu'il faudra charger ça dans le contrôleur Tickets ou Discussions, non ? 
        // ou faut-il déclarer quand même l'action Read et la charger dynamiquement dans les contrôleurs 
        // des modules Tickets ou Discussions ?
   }

   public function update($module, $hash) {
        // code pour mettre à jour un enregistrement
   }

   public function delete($module, $hash) {
        // code pour mettre à jour un enregistrement
   }

}

?>

n'y-a-t-il pas un risque dans le fait que le type de module soit précisé dans l'url ? l'utilisateur peut éventuellement changer "ticket" par "discussion" ou autre... il faut donc procéder à une vérification au préalable (si un ticket ou une discussion ayant ce hash existe ou non dans la base de données).

y-a-t-il éventuellement une autre solution ?

TABLE FEEDBACKS

id, module, hash, note, comment, author, created, updated

c'est là où tu voulais en venir ?

Après, pour moi, le mieux ext vraiment de TOUT faire dans le feedBackController et avoir une URL qui redirige vers celui-ci

je ne vois pas, techniquement parlant, comment gérer cette possibilité quand tu dis "avoir une URL qui redirige vers celui-ci"... c'est à dire ? à quel niveau : routeur, dans le contrôleur des modules (tickets, disscussions, ...).

j'attends ton retour.

En gros, tu as une page dédiée sur laquelle tu as ton formulaire, et toutes les actions se font dans ton feedBackController. Tout simplement.
Après pour ce qui est du nom du module dans l'URL, tu peux éventuellement le chiffrer. Pour le hash, il faudrait générer, par ticket (par ex.) un uniqueId (hash quoi) à la création et le stocker en bdd. Et lorsque tu store ton feedback, tu peux comparer les hash. De cette façon tu peux vérifier qu'il s'agit bien du bon ticket (cela implique un SELECT supplémentaire mais point de vue sécurité c'est un peu mieux).

oez
Auteur

ok, je vois.

Après, pour moi, le mieux ext vraiment de TOUT faire dans le feedBackController et avoir une URL qui redirige vers celui-ci

en fait, quand tu parles d'avoir "une URL qui redirige vers celui-ci", tu parles de rediriger l'utilisateur vers une page dédiée et non de rediriger une action du contrôleur Ticket ou Discussion vers une action spécifique du contrôleur Feedbacks.

c'est ça ?

Oui c'est ça, je me suis mal exprimé sorry ;)

oez
Auteur

donc, si j'ai bien compris, dès qu'une fonctionnalité peut éventuellement être utilisée dans plusieurs autres modules, il vaut mieux créer un contrôleur spécifique ?

par exemple, pour mon module Tickets, je compte mettre en place une fonctionnalité de réponses prédéfinies. c'est-à-dire que des réponses types seraient stockées en base de données et seraient utilisées pour répondre plus rapidement aux tickets. il vaut mieux que je fasse un contrôleur, étant donné que cette fonctionnalité risque elle aussi d'être ajoutée dans d'autres modules (ex : discussions).

idem si je veux mettre en place une fonctionnalité de génération de pdf ?

oez
Auteur

donc, si j'ai bien compris, dès qu'une fonctionnalité peut éventuellement être utilisée dans plusieurs autres modules, il vaut mieux créer un contrôleur spécifique ?

par exemple, pour mon module Tickets, je compte mettre en place une fonctionnalité de réponses prédéfinies. c'est-à-dire que des réponses types seraient stockées en base de données et seraient utilisées pour répondre plus rapidement aux tickets. il vaut mieux que je fasse un contrôleur, étant donné que cette fonctionnalité risque elle aussi d'être ajoutée dans d'autres modules (ex : discussions).

idem si je veux mettre en place une fonctionnalité de génération de pdf ?

Oui c'est tout à fait ça : pour les réponses rapides, tu mets en base les modèles, un ref (ticket, discusson, etc ou NULL si tu veux les utiliser partout) et tu fais un controller qui gère le CRUD par exemple. De cette façon, tu n'as plus qu'à importer ta classe là où tu en as besoin (via le mot clé 'use') et par exemple récupérer la liste des réponses rapides pour les tickets :)
Pour les PDF c'est pareil, tu as une classe générique qui se charge de rendre ton PDF, et tu l'utilise là où tu en as besoin (après pour les PDF y'a pleins de packages PHP sur packagist.org).