2016-06-26 12 views
1

Ich brauche hier einige Ratschläge. Ich bin in einem ZF2 Projekt mit Doctrine 2 mit dem Doctrine Orm Modul. Ich kümmere mich um die Authentifizierung mit den vom Lehrmodul bereitgestellten Diensten. Das Ergebnis ist, dass ich nach der Authentifizierung in meinem Authentifizierungsdienst die Identität (die von der getIdentity() -Methode zurückgegeben wird), die eine Instanz meiner Benutzerentität ist.Verwenden von Doctrine Modul Hydrator und Formular Anmerkungen in ZF2

Ich habe zwei Einheiten: Benutzer und Gruppe. In der Benutzer-Entität mit der Gruppe ist eine Viele-zu-Eins-Beziehung definiert (ein Benutzer gehört zu einer Gruppe, eine Gruppe hat viele Benutzer). Grundlegende Sachen.

Mein Problem kommt, wenn ein verbundener Benutzer gehen muss, um seine eigene Gruppe in der CRUD zu bearbeiten.

Die Art, wie ich die CRUD handhabe, ist einfach: Ich habe mein Formular in den Anmerkungen meiner Entitäten definiert und ich habe den Doctrine Hydrator spezifiziert und verwende Doctrine Object Select. Alles funktioniert perfekt, außer wenn die eigene Gruppe bearbeitet wird.

Was ich verstanden habe ist: wie meine viele zu eins Beziehung ist im Lazy Loading Fetch-Modus, nach der Authentifizierung, die Identitätskarte der Lehre enthält die Benutzergruppe als eine Instanz des Proxy. Wenn der Benutzer auf der Bearbeitungsaktion kommen, hier ist was passiert:

/* 
Code that get the goup id to edit from request 
*/ 
if (!empty($id)) { 
    $entity = $groupRepository->find($id); 
} 

$builder = new AnnotationBuilder(); 
$this->form = $builder->createForm($entity); 

Das Ergebnis ist, dass, wenn jede Gruppe bearbeiten, die nicht in der Lehre Identitätskarte als Proxy-Instanz ist, ok alles ist. Aber wenn die Entität, die ich bearbeiten muss, bereits in der Identitätsübersicht als Proxy-Instanz vorhanden ist, kann die Formularfactory die in meinen Entitäten definierten Anmerkungen nicht finden und bricht. Vielleicht ist mein Weg eine schlechte Übung? Ich wollte die Anmerkungen verwenden, um mein Formular zu erstellen.

Die einzige fix ich (das ist eine schreckliche Art, wie ich denke) finden könnte, ist mein Code wie folgt zu ändern:

/* 
Code that get the goup id to edit from request 
*/ 
if (!empty($id)) { 
    $em->clear(); <== NEW LINE HERE 
    $entity = $groupRepository->find($id); 
} 

$builder = new AnnotationBuilder(); 
$this->form = $builder->createForm($entity); 

In der Theorie der Aufruf zu löschen() alle Stellen sollten abzulösen nicht sein ein Problem in meinem Anwendungsfall, weil ich weiß, dass ich nur die Gruppenentität bearbeiten möchte, aber ich denke, das ist vielleicht nicht das Richtige.

Eine andere Lösung (aber noch nicht versucht): Erstellen Sie eine benutzerdefinierte FormFactory, die ich an meine AnnotationBuilder übergeben. Diese benutzerdefinierte FormFactory würde dann den Typ der Entität vor dem Starten der Formularerstellung aus Anmerkungen ermitteln. Wenn es ein Proxy ist, sollte es stattdessen die Anmerkungen der "echten" Klasse bekommen?

Oder vielleicht habe ich etwas einfacheres verpasst?

Antwort

2

Ich bin ein wenig überrascht, dass dies nicht richtig funktioniert, wenn Sie einen Proxy übergeben, aber ich stimme zu, dass Ihre aktuelle Lösung ist schrecklich :). Sie könnten es anders lösen:

// collect the class from the entity or proxy 
$className = \Doctrine\Common\Util\ClassUtils::getClass($entity); 

$builder = new AnnotationBuilder(); 
$this->form = $builder->createForm($className); 

Der Annotationsersteller funktioniert gut, wenn der Klassenname übergeben wird. Der obige Code sammelt den echten Klassennamen sowohl von Proxy-Objekten als auch von Entitäten, so dass dies für beide Fälle funktioniert.

Aber ich würde immer noch vorschlagen, Ihre Konfiguration zu überprüfen, weil ich fast sicher bin, dass es auch mit Proxies korrekt funktionieren sollte.

+0

Ich wusste nichts über die ClassUtils-Methode. Das ist großartig. Ich wollte meine Lösung mit etwas wie get_parent_class() schreiben, aber das ist ok.Und während ich den Prozess der Formularerstellung innerhalb einer verantwortlichen Klasse gekapselt habe, um den AnnotationBuilder zu instantiieren, lege ich ihn einfach hinein und muss ihn nicht in allen meinen Aktionen ändern. – Bruce

+0

Übrigens habe ich meine Konfiguration bereits überprüft. Ich musste im Zend Annotation Builder var_dump, um zu sehen, dass, wenn es eine Instanz der Proxy-Klasse (die noch nicht initialisiert ist) empfängt, konnte es meine Anmerkungen nicht erhalten. Tatsächlich macht der AnnotationBuilder eine "$ reflection = new ClassReflection ($ entity);" Ich habe es nicht überprüft, aber es erhält nicht die Eigenschaften der Elternklasse (vielleicht eine Frage des öffentlichen/privaten Zugriffs?). Da die Proxy-Klasse ein Kind der Entity-Klasse ist, kann sie vielleicht mein Problem erklären? – Bruce

+0

@Bruce, danke für die Frage, dass ich keine Ahnung hatte, wie ich die gleiche Situation erklären sollte, in der ich war. Und Wilt, danke für die Problemumgehung. Bruce, ich habe meine Entitätseigenschaften geändert, um geschützt zu sein, und es hat auch so funktioniert. Wow, danke für die Frage und die Antworten. – smozgur

Verwandte Themen