In meiner Symfony 2 App habe ich 3 verschiedene Benutzerrollen, die Zugriff auf einen Backend-Verwaltungsteil haben können:
%Vor% Für eine Route wie http://example.org/admin/post/
möchte ich, dass meine App abhängig von der Benutzerrolle unterschiedliche Informationen anzeigt, dh 3 Controller binden an eine einzige Route .
Was ist der beste Weg, damit umzugehen?
Ich habe über einige Lösungen nachgedacht, aber keine scheint mir gut zu sein:
Ein Controller, und in jeder Aktion test ich nur die Benutzerrolle:
%Vor%Selbst wenn das den Job macht, IMO ist das offensichtlich kein gutes Design.
Ein BackendController, der an 3 verschiedene Controller versendet:
%Vor%Wie Nummer eins.
Ich habe versucht, Controller dazu zu bringen, sich gegenseitig zu erweitern:
%Vor%IMO, es ist ein besseres Design, aber ich kann es nicht schaffen. Das Routing-System stoppt auf dem ersten Controller, mit dem es übereinstimmt. Ich würde es gerne König der Cascading-Stil automatisch handeln (d. H. Wenn Benutzer Mitarbeiter ist dann gehen Sie zu PostStaffController, andernfalls, wenn Benutzer Moderator ist, gehen Sie zu PostModeratorController, sonst gehen Sie zu PostAdminController).
Fügen Sie in meinem BlogBundle einen Listener zu kernel.controller hinzu, der den gleichen Job wie Nummer 2 macht?
Ich suche nach der am besten entwickelten und flexibleren Lösung. Es besteht die Möglichkeit, dass wir in Zukunft weitere Rollen hinzufügen.
IMHO, Sie sollten nicht verschiedene Controller für dieselbe Route basierend auf Rollen abfeuern. Es sind nur unterschiedliche Verantwortlichkeiten. Routen sind für ausgewählte Controller, Rollen sind für Privilegien. Nach einem Jahr wirst du dich nicht mehr an den Trick erinnern, dh. Wenn Sie versuchen, fügen Sie eine neue Rolle hinzu.
Natürlich ist das Problem der verschiedenen Inhalte für verschiedene Rollen ziemlich oft, so dass meine Lieblingslösungen in diesem Fall sind:
in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php
Es gibt eine Option zum Ersetzen der matcher_class
, die in config.yml
möglich sein sollte.
Wenn Sie die Unterklassen UrlMatcher
und overRide matchRequest
erstellen, die Vorrang vor der Pfadübereinstimmung haben (nur URL).
matchRequest
nimmt eine Parameter $ Anfrage (Request Objekt)
Das Request-Objekt sollte die Benutzerinformationen enthalten, vorausgesetzt, der Security-Provider-Listener wird vor dem Router-Listener ausgeführt, und Sie können die Route auswählen, indem Sie die URL und die Benutzerrolle kombinieren. Die Routen werden in einem Array gespeichert, das mit dem Namen indiziert wird, sodass die Namen unterschiedlich sein müssen.
Sie könnten möglicherweise Namen wie post_index[USER]
post_index[STAFF]
post_index[MODERATOR]
Um die URLs mit {{ path('post_index', {...}) }}
zu generieren, müssen Sie auch die Unterklasse URLGenerator
ersetzen und diese mit der Option generator_class
in den Router injizieren.
Tags und Links symfony