Bonjour !

J'ai finis le tutoriel de Grafikart sur Laravel et histoire de passer tout de suite aux choses sérieuses, j'ai décidé de reprendre un vieux site que j'avais fais en procédural et de le refactoriser car, soyons clair, le code était vraiment dégueulasse.

Seulement, je suis face à un problème. J'ai vraiment du mal à concevoir la manière dont je pourrais organiser mes fichiers. Je débute avec l'architecture MVC et je pense que c'est ça qui me bloque.

En fait, sur le site en question, il y a 4 types de comptes, et pour chacun d'entre eux, l'inscription, la modification de profil, les autorisations à certaines fonctionnalités et certaines pages sont vraiments différents, ce qui fait que les fonctionnalités d'inscriptions et les middleware de base ne conviennent pas à mes souhaits.

J'ai vraiment bien pratiqué tout au long du tutoriel et je pensais être en mesure de faire ce que je souhaite mais visiblement, ça s'avère plus compliqué que prévu. Aurais-je manqué quelque chose ? Est-ce normal de se retrouver bloqué à ce point là ?

Je ne viens pas ici forcément pour vous demander une solution toute faite mais pour avoir quelques astuces sur la marche à suivre car au final, je suis en mesure de mettre en place un système d'espace membre pour un type de compte mais pour les quatre, j'ai vraiment peur de me retrouver avec un code aussi sale qu'en procédural :)

Je vous remercie.
Boris :)

6 réponses


AlexJM
Réponse acceptée

Bonjour,

Tout d'abord, désolé je n'avais pas vu le post

Ensuite, pour ton problème, j'irai de cette manière :
1) Utilisation des policies afin de gérer les permissions
2) Utilisation des policies dans des formrequests afin de gérer le droit d'affichage d'une page
3) Utilisation des : @can afin de masquer/d'afficher les liens vers les pages

Si tu as d'autres questions, n'hésite pas !

AlexJM
Réponse acceptée

Pas de prob,

Ah oui en effet, j'aurais plutôt fait un champs dans la table du type "catégorie d'utilisateur" (en trouvant un meilleur nom ^^)

Sinon pour le merge, tu peux aussi faire:

$user->create(['type' => $type, 'confirmed' => 0, 'confirmation_token' => str_random(60)] + $request->except(['password_confirm']));

Normalement ça devrait fonctionner

/!\ dans ton merge avant tu changeais l'object request, ici tu ne changes plus request

Sinon pourquoi ne souhaites-tu pas qu'ils soient dans l'attribut fillable ?

En tous cas, s'ils ne sont pas dans fillable, tu n'as que le code que tu as écris qui est possible

AlexJM
Réponse acceptée

En faite le fillable n'apporte qu'une sécurité pour le développeur, il permet de spécifier quels champs ont le droit d'être assignés en mass (par exemple via le tableau quand tu fais Model::create($tab))
Mais sinon, tout est protégé via eloquent (notamment des requêtes préparées si je dis pas de bêtise) donc même si tu mets tout en fillable, y'a pas de soucis de sécurité ;)

Donc si tu veux être sûr que l'utilsiateur ne modifie pas le nom des champs, t'a deux choix :
1) réassocier les clés du tableau :

Model::create([
    'key1' => $request->input('key1'),...
]);

2) utiliser $request->only (regarde das la doc):

Model::create($request->only(['key1', ...]));

Pas de pb :)

Salut AlexJM !

Merci pour ta réponse et désolé pour la mienne qui se fait tardivement ! :)

Je pense que je galère un peu avec la documentation de Laravel car, bien que je l'ai parcouru, je ne connaissais pas les policies ni les @can. Ou alors je suis passé dessus mais mon niveau d'anglais étant très moyen, je ne l'ai pas remarqué.

En tout cas, tu as déjà éclairci un point assez important. Je ne comptais pas du tout faire la gestion des permissions de cette manière et je me rend compte que ma méthode était beaucoup plus bordélique.

Pour ce qui est de l'organisation de mes classes (controller et models), je suis actuellement parti là-dessus concernant l'inscription :

  • Un model différent pour les 4 types de compte.
  • Un controller Register avec les fonctions suivantes (je ne mets pas les vrais noms des comptes histoire de ne pas t'embrouiller) :

    • user1 qui permet d'afficher la vue du formulaire d'inscription pour ce compte

    • createUser1 qui permet de stocker l'utilisateur

    • user2 qui permet d'afficher la vue du formulaire d'inscription pour ce compte

    • createUser2 qui permet de stocker l'utilisateur

Et ainsi de suite pour les 4 comptes. Au niveau des routes, j'appelle user1 (ou 2 ou 3 ou 4) en GET et createUser1 (ou 2 ou 3 ou 4) en POST. Le tout dans un route::group avec comme prefix : register.

J'espère que c'est correct. Je tiens à le répéter, je débute vraiment avec Laravel et la structure MVC ainsi que les routes.

J'ai tout de même un problème. Lorsque l'utilisateur s'inscrit, toutes les informations indiquées dans le formulaire sont bien contenue dans l'objet Request ou Input. Seulement, j'ai une autre information à insérer à la base de donnée, c'est le type de compte car c'est une table unique que se partagent les 4 comptes avec une colonne "type" qui permet de savoir de quel type de compte il s'agit. Je dois également insérer le token de confirmation de compte (colonne "confirmation_token") ainsi que "confirmed" qui est un booléan et qui permet de savoir si oui ou non le compte est confirmé.

Du coup, je procède comme suit dans les fonctions createUserX :

public function createUser1(RegisterUser1Request $request, User $user) {
    $type = 1 // variable en fonction du compte
    $request->merge(['type' => $type, 'confirmed' => 0, 'confirmation_token' => str_random(60)]);
    $user->create($request->except(['password_confirm']));
}

Pour ce qui est du $request->except(), je l'ai trouvé sur la documentation afin d'ignorer le champ password_confirm qui au final, ne sert qu'à la vérification.

Je me suis un peu informé pour trouver la méthode merge() mais j'ai trouvé un topic sur stackoverflow où deux personnes précisait qu'il était préférable de ne pas modifier l'objet Request de cette façon là. Seulement, ils ne donnaient pas de solutions alternatives.

L'autre problème est que du coup, les colonnes type, confirmed et confirmation_token sont indiqués dans l'attribut fillable et je ne le souhaite pas.

Du coup, cette façon de faire semble-t-elle plus judicieuse ?

public function createUser1(RegisterUser1Request $request, User $user) {
    $type = 1 // variable en fonction du compte
    $user->create($request->except(['password_confirm']));

    $user->type = $type;
    $user->confirmed = 0;
    $user->confirmation_token = str_random(60);
    $user->save();
}

Ca me semble tout de même plus long comme code.

Enfin voilà. Je sais bien que je semble débarquer ici en ayant aucune notion concernant Laravel ou la POO mais c'est juste que je suis un peu perdu x)

Je vous souhaite une bonne soirée et merci encore pour ta réponse AlexJM :)

Boris

Salut !

Effectivement, le code que tu m'as indiqué fonctionne parfaitement et le request n'est plus modifié. Je n'avais pas pensé à faire une union entre les deux tableaux...

Pour ce qui est des attributs fillable, je pensais qu'un utilisateur pouvait alors facilement modifier la requête SQL en changeant le nom d'un des inputs. J'ai essayé et ça ne fonctionne pas. Je vais aller m'informer un peu plus sur cet attribut fillable car j'ai visiblement pas mal de lacunes (bien que je comprenne à quoi il serve, enfin je pense) :(

En tout cas, je te remercie beaucoup du temps que tu as pris à m'aider ! C'est vraiment très sympa de ta part !! :)

Problème résolu. Je reviendrai surement plus tard avec d'autres questions bien sur :D

Merci encore !
Boris

Je te remercie de ta réponse ! J'ai vu que pour l'authentification, ils fonctionnent de la première façon. :)