[GELÖST] Replace-Hook, wie komme ich an protected Variablen?

Hallo & ein gutes neues Jahr! Ich habe für einen Hook ein Plugin geschrieben, um eine bestimmte Methode zu ersetzen. So wie es aussieht, komme ich auch zur Ausführung der neuen Methode, jedoch weiß ich nicht, wie ich mir eine protected Variable der alten Methode holen kann Ich habe es über $subject = $args-\>getSubject(); versucht. Was vorher $this->_elements lautete, funktioniert mit $subject->_elements nicht. getSubject() sollte mir die Elternklasse der ersetzten Methode liefern, richtig? Ist das dann nicht die instanziierte Klasse? Vielen Dank für Eure Hilfe und Grüße schisch EDIT: Hab den Thread-Titel verändert, weil es weniger um $this ging, als ich dachte.

Liegt es vielleicht daran, dass die Variable _elements protected ist, und kein Zugriff aus der statischen Hook-Methode heraus erlaubt wird? Mein Vorhaben dreht sich um das Ersetzen der commitForm()-Methode aus dem Frontend-Controller “engine/Shopware/Controllers/Frontend/Forms.php” Wie könnte ich das Problem umgehen?

post46902.html#p46902 Hier gibt es jemanden, der schon einmal eine ähnliche Frage gestellt hat. Das ist mir erst jetzt aufgefallen. Wäre sehr froh, falls jemand mir einen Tipp geben kann.

1 Like

Meine Antwort bezieht sich eigentlich auf Version 3.5, aber ich vermute, dass sich das im Großen und Ganzen nicht geändert hat: Du kannst das Template für die Proxyklassen ändern und dann z.B. eine __get Methode implementieren. Das ganze findest du für Version 3.5 unter folgendem Pfad: engine/Enlight/Enlight/Hook/ProxyFactory.php ($proxyClassTemplate). In Version 3.5 kann man dann auch gleich noch den Defaultwert für $args in excuteParent korrigieren $args=array(), statt $args=null, das wurde vermutlich/hoffentlich in v4 korrigiert. Danach die Neugenerierung der Proxyklassen nicht vergessen.

1 Like

Hallo ovi, vielen Dank für Deine inspirierende Antwort. Version 4 übergibt übrigens neue Arrays als Parameter. Daran musste ich also nichts mehr verändern. Ich habe nun Folgendes zur Template-Variable $proxyClassTemplate hinzugefügt: public function \_\_get($name) { if(isset($this-\>$name)) { return $this-\>$name; } return null; } Das scheint soweit zu funktionieren. Somit musste ich fremden Code verändern, was bei Updates natürlich nicht so vorteilhaft ist. Gut wäre es vielleicht, wenn man solche erweiterten Rechte direkt im Backend individuell für ein Plugin freiklicken könnte. Ist diese ziemlich „liberale“ Modifikation aus Sicherheitsaspekten überhaupt ratsam, wenn fortan quasi jedes Plugin auf geschützte, bzw. private „Eltern“-Variablen zugreifen kann? Ich kann im Moment nicht absehen, ob so eine Maßnahme nicht ggf. Nachteile mit sich bringt.

Generell sehe ich da keine Sicherheitsrisiken. Es gibt allerdings aus meiner Sicht sehr wohl ein konzeptionelles Problem. Es wäre besser, wenn der jeweilige Hook bzw. die Klasse, die den Hook implementiert, in direkter Vererbungsreihenfolge stünde, oder vermutlich noch besser, eben solche Abhängigkeiten direkt aufgelöst werden über jeweilige Getter und Setter Methoden, denn du kannst dich bei einem Update auch nicht darauf verlassen, dass die protected Variable immer noch den selben Namen trägt. Über Getter und Setter Methoden kann man das relativ flexibel abfangen. Allerdings ist manchmal schwierig vorherzusehen für welche Variablen dies benötigt wird, oder man erkauft sich das halt durch viel Boilerplatecode. Alternativ zur Veränderung des Proxytemplates und dem damit einhergehenden Updatekonflik, kannst du natürlich über die Reflection API die Accessibility der Variablen ändern. Ist zwar auch nicht schön, und dazu auch noch relativ langsam, aber immerhin könntest du damit die Updatefähigkeit erhalten, so lange sich der Name der Variablen nicht ändert. Nochmal zur Klarstellung: Das ist bitte alles nur als Workaround, und nicht als Best-Practice, zu betrachten.

Mit der oben genannten Änderung in $proxyClassTemplate kommt es zu Fehlern bei der PDF-Dokumentenerstellung: [quote] Fatal error: Call to a member function setCurrency() on a non-object in engine/Shopware/Components/Document.php on line 477 [/quote] Der Bösewicht in der Klasse Document lautet: $shop-\>setCurrency($repository-\>find($this-\>\_order-\>order-\>currencyID)); Durch die Schaffung dieser allgemeinen Methode kommt es anscheinend zu Problemen, wenn null zurückgegeben wird. Schade, die Lösung kann ich also so nicht verwenden.

Ich hab leider momentan keine Zeit mir das im Detail anzusehen, aber dann versuch’s doch mal über die Reflection Variante.

1 Like

Hallo ovi, ja, damit habe ich das Problem nun gelöst. Ich hole mir reflektiv das notwendige Array Objekt, und es scheint zu klappen, womit das Problem nun vorerst behoben scheint. Für die Idee vielen Dank!

Hi, ich habe das gleiche Problem. Die Lösung funktioniert nur wenn ich die Core Datei ProxyFactory.php anpassen, oder? Eine Lösung direkt im Plugin scheint derzeit nicht möglich? Wie ist das mit dem “refelktiv” gemeint? Hat ihr mir ein Beispiel? Bin da leider nicht so tief drin. Danke