Hi,
mir ist beim Testen mit einigen eigenen Plugins und dem SwagPromotion Plugin (in Version 1.x und 2.x) von @Shopware aufgefallen, dass die Arten und Weisen Service Decorator zu definieren in der Legacy Plugin Struktur und der neuen nicht miteinander kompatibel sind.
tl;dr;
Die Service-Decorator welche über die services.xml in der neuen Plugin-Struktur definiert werden, überschreiben die alte Service ID, und somit können sich die Legacy Plugins nicht mehr auf diesen registrieren.
tl;dr;
Szenario 1
Plugin A (ein Legacy Plugin unter engine/Shopware/Plugins) registriert einen Service Decorator wie folgt
public function install()
{
$this->subscribeEvent(
'Enlight_Bootstrap_AfterInitResource_shopware_storefront.list_product_service',
'decorateService'
);
return true;
}
public function afterInit()
{
$this->get('Loader')->registerNamespace('LegacyDecoratorOne', $this->Path());
}
public function decorateService()
{
$coreService = Shopware()->Container()->get('shopware_storefront.list_product_service');
$listProductService = new \LegacyDecoratorOne\StoreFrontBundle\ListProductService($coreService);
Shopware()->Container()->set('shopware_storefront.list_product_service', $listProductService);
}
Plugin B (neues Plugin unter custom/plugins mit services.xml) registriert einen Service Decorator wie folgt
So auch geschehen bei einem alten Plugin welches schon länger existiert als Shopware 5.2 und dem SwagPromotion Plugin in Version 2.x.
Resultat: Mit der Registrierung von Plugin B wird der Enlight_Bootstrap_AfterInitResource_shopware_storefront.list_product_service Event nicht mehr getriggert, da jetzt nur noch die Service ID custom.one.list_product_service_decorator initialisiert wird. Plugin A muss hier jetzt also hingehen und statt den shopware_storefront.list_product_service zu erweitern, sich auf Enlight_Bootstrap_AfterInitResource_custom.one.list_product_service_decorator registrieren, damit es weiterhin ausgeführt wird. Kann im Einzelfall gehen, aber im Falle eines Community Plugins ist das nicht tragbar.
Szenario 2
Plugin A (altes Plugin)
Plugin B (ebenfalls altes Plugin)
so geschehen mit dem selben Plugin A aus Szenario 1 und dem SwagPromotion Plugin Version 1.x. Hier wird der Service Decorator von SwagPromotion, da alte Plugin Struktur, ebenfalls über die Bootstrap registriert wie bei Plugin A.
Resultat: Beide harmonieren wie gewünscht und werden nacheinander ausgeführt.
Szenario 3
Plugin A (neues Plugin)
Plugin B (neues Plugin)
so geschehen mit einem neuen Testplugin und dem SwagPromotion Plugin Version 2.x. Beide Decorator werden über die services.xml registriert
Resultat: Beide werden wie gewünscht nacheinander ausgeführt. Einzige Problematik welche ich hier feststellen konnte, ist eine extrem hohe Speicherauslastung, wenn beiden Decorators noch diverse andere Services via Dependency Injection übergeben werden.
Hier wäre eine Lösung wünschenswert, da es doch jede Menge Plugins gibt welche noch auf der alten Plugin Struktur beruhen aber für Shopware 5.2+ freigegeben sind, und sich so mit Plugins der neuen Plugin Struktur in die Quere kommen. Sollte es hierfür keine Lösung geben, müssten theoretisch sämmtliche Plugins ab 5.3 (Stichwort AjaxListing) auf der neuen Plugin Struktur aufbauen um diesem Problem aus dem Weg zu gehen.
Wer sich davon gerne selbst ein Bild machen möchte, ich habe auf github mal 4 Dummy Plugins erstellt, welche die Szenarien 1-3 aufzeigen (mit Ausnahme der Speicheraufwendung)
Für Vorschläge oder Lösungen bin ich jederzeit offen und würde mich darüber freuen.
Beste Grüße
Daniel