# Pluginübergreifend Klassen referenzieren

**URL:** <https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814>\
**Category:** Shopware 3.5\
**Tags:** programming\
**Created:** [3. März 2014 um 11:55 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814 "2014-03-03T11:55:26Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![tbl](https://avatars.discourse-cdn.com/v4/letter/t/57b2e6/32.png) [@tbl](https://forum.shopware.com/u/tbl)\
**Post date:** [3. März 2014 um 11:55 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/1 "2014-03-03T11:55:26Z")

</div>

Hallo Zusammen Ich entwickle eine Extension, die Preisregeln abbildet (PriceRules). Diese Preisregeln referenzieren Shopware Categorien sowie Unternehmen von einer zweiten eigenen Extension (CorporateStructure). [code]\<?php namespace Shopware\CustomModels\PriceRules;  
use Shopware\Components\Model\ModelEntity,  
Doctrine\Common\Collections\ArrayCollection,  
Doctrine\ORM\Mapping AS ORM;

/\*\*

- @ORM\Entity
- @ORM\Table(name=„s\_pricerules\_rule“)  
\*/  
class Rule extends ModelEntity {

…

/\*\*

- @var \Doctrine\Common\Collections\ArrayCollection
- @ORM\ManyToMany(targetEntity=„Shopware\Models\Category\Category“)
- @ORM\JoinTable(name=„s\_pricerules\_rules\_categories“,
- joinColumns={@ORM\JoinColumn(name=„rule\_id“, referencedColumnName=„id“)},
- inverseJoinColumns={@ORM\JoinColumn(name=„category\_id“, referencedColumnName=„id“)}
- )  
\*/  
protected $categories;  
public function setCategories(\Doctrine\Common\Collections\ArrayCollection $categories) { $this-\>categories = $categories; } public function getCategories() { return $this-\>categories; } public function addCategory(\Shopware\Models\Category\Category $category) { $this-\>categories-\>add($category); } public function removeCategory(Shopware\Models\Category\Category $category) { $this-\>categories-\>removeElement($category); } /\*\* \* @var \Shopware\CustomModels\CorporateStructure\Corporation \* @ORM\ManyToOne(targetEntity="\Shopware\CustomModels\CorporateStructure\Corporation") \* @ORM\JoinColumn(name=„corporation\_id“, referencedColumnName=„id“) \*\*/ private $corporation; public function setCorporation(\Shopware\CustomModels\CorporateStructure\Corporation $corporation) { $this-\>corporation = $corporation; } public function getCorporation() { return $this-\>corporation; } } [/code] Sowohl die Referenz zu den Kategorien wie auch weitere Referenzen innerhalb des Namespaces funktionieren bereits. Nur das Anlegen einer Referenz zu einer Klasse im andern Plugin (CorporateStructure) macht Probleme. Die Installation bricht mit der folgenden Fehlermeldung ab: Plugin Price Rules could not be installed The target-entity Shopware\CustomModels\CorporateStructure\Corporation cannot be found in ‚Shopware\CustomModels\PriceRules\Rule#corporation‘. Im Bootstrap hab ich registerCustomModels() drin im afterInit. Ich hab zwar herausgefunden, das ich durch Anlegen einer Instanz des andern Plugins im Bootstrap das Problem lösen kann doch es taucht dann einfach beim Controller wieder auf. Wie kann ich Shopware sagen, das er das CorporateStructure-Plugin immer laden soll, wenn das PriceRules Plugin aktiv ist, damit deren Models verfügbar sind? Gruss aus der Schweiz

---

<div class="post-metadata">

**Author:** ![tbl](https://avatars.discourse-cdn.com/v4/letter/t/57b2e6/32.png) [@tbl](https://forum.shopware.com/u/tbl)\
**Post date:** [28. April 2014 um 10:03 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/2 "2014-04-28T10:03:53Z")

</div>

Ich antworte mir mal selbst: Scheinbar ist es nicht möglich, zentral zu definieren, welche andern Plugins referenziert und geladen werden müssen. Entsprechend muss für jede Klasse das externe Plugin registriert und instanziiert werden. Um diese Logik nicht über die ganze Extension zu verstreuen, habe ich dafür Events eingesetzt: Beliebige Model Klasse: [code]\<?php namespace Shopware\CustomModels\MyExtension;  
use Shopware\Components\Model\ModelEntity,  
Doctrine\Common\Collections\ArrayCollection,  
Doctrine\ORM\Mapping AS ORM;

/\*\*

- @ORM\Entity
- @ORM\Table(name=“s\_myextension\_rule”)  
\*/  
class Rule extends ModelEntity {   
…  
public function \_\_construct() {  
// Class path used as event name → unique identifiable Enlight()-\>Events()-\>notify(‘Shopware\CustomModels\MyExtension\Rule::onConstruct’, array()); } … } [/code] Bootstrap ` class Shopware\_Plugins\_Backend\_MyExtension\_Bootstrap extends Shopware\_Components\_Plugin\_Bootstrap { ... private function registerEventsAndHooks() { // controller predispatch event $this-\>subscribeEvent('Enlight\_Controller\_Action\_PreDispatch\_Backend\_MyExtension', 'loadNamespaces'); // model class rule instantiation event $this-\>subscribeEvent('Shopware\\CustomModels\\MyExtension\\Rule::onConstruct','loadNamespaces'); // service class instantiation event $this-\>subscribeEvent('Shopware\\Plugins\\Backend\\MyExtension\\Service\\DiscountCalculator::onConstruct', 'loadNamespaces'); } ... public function loadNamespaces() { // load service namespace $this-\>Application()-\>Loader()-\>registerNamespace('Shopware\\Plugins\\Backend\\MyExtension\\Service', $this-\>Path().'Service/'); // load foreign plugin namespace $this-\>Application()-\>Loader()-\>registerNamespace('Shopware\\CustomModels\\CorporateStructure', $this-\>Path()); // instantiate foreign plugin -\> without instance shopware won't find the referenced classes $corporateStructure = Shopware()-\>Plugins()-\>Backend()-\>CorporateStructure(); } ... private function createDatabaseSchema() { // load classes befor creating db tables -\> doctrine needs foreign models to create foreign key columns $this-\>loadNamespaces(); $this-\>registerCustomModels(); $modelManager = $this-\>Application()-\>Models(); $schemaTool = new \Doctrine\ORM\Tools\SchemaTool($modelManager); try { $schemaTool-\>createSchema($this-\>getModelMetadata($modelManager)); } catch (\Doctrine\ORM\Tools\ToolsException $e) { Shopware()-\>Debuglogger()-\>info(json\_encode($e-\>getMessage())); } } ... public function removeDatabaseTables() { $this-\>loadNamespaces(); $modelManager = $this-\>Application()-\>Models(); $schemaTool = new \Doctrine\ORM\Tools\SchemaTool($modelManager); ... } ... public function afterInit() { // Shopware -\> load models $this-\>registerCustomModels(); // load namespaces every time bootstrap is instantiated $this-\>loadNamespaces(); } ... } ` Kennt jemand noch eine einfachere Lösung?

---

<div class="post-metadata">

**Author:** ![mac](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/mac/32/7855_2.png) [@mac](https://forum.shopware.com/u/mac)\
**Post date:** [26. Juni 2014 um 13:15 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/3 "2014-06-26T13:15:01Z")

</div>

Ich hänge gerade an der gleichen Sache. Gibt es keine einfachere Lösung? Vielleicht könnte sich ja jemand von Shopware dazu äußern. 🕶 Gruß Marco

---

<div class="post-metadata">

**Author:** ![DanielNogel](https://avatars.discourse-cdn.com/v4/letter/d/96bed5/32.png) [@DanielNogel](https://forum.shopware.com/u/DanielNogel)\
**Post date:** [26. Juni 2014 um 13:31 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/4 "2014-06-26T13:31:07Z")

</div>

Hi, grundsätzlich gibt es dazu keine fertige Lösung. Der registerNamespace-Ansatz ist aber schon richtig: `&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; $this-\>Application()-\>Loader()-\>registerNamespace('Shopware\\CustomModels\\CorporateStructure', $this-\>Path()); ` Um auf diese Weise die CustomModels eines anderen Moduls zu registrieren, müsst ihr statt $this-\>Path() aber den Pfad des anderen Plugins angeben. Dafür gibt es noch keinen schönen Helfer - in der s\_core\_plugins findet ihr aber die Spalten `namespace` für die Unterscheidung Frontend / Core / Backend und die Spalte `source` für die Unterscheidung Local / Default / Community. Mit den Informationen solltet ihr euch einen validen Pfad erzeugen und registrieren können. Damit sollten die Models abgefrühstückt sein. Für das „Teilen“ von Ressourcen / Services unter verschiedenen Plugins würde ich das Shopware Resource-System verwenden - d.h. wenn ihr euren Service „MyFancyService“ global verfügbar machen wollt, registriert ihr euch das Event ` $this-\>subscribeEvent( 'Enlight\_Bootstrap\_InitResource\_MyFancyService', 'onInitMyComponent' );` und gibt im Callback eine Instanz eurer Klasse zurück. Dann können alle Plugins über Shopware()-\>MyFancyResource oder über den Container Shopware()-\>Container()-\>get(‚myfancyservice‘) darauf zugreifen. lG Daniel

---

<div class="post-metadata">

**Author:** ![mac](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/mac/32/7855_2.png) [@mac](https://forum.shopware.com/u/mac)\
**Post date:** [26. Juni 2014 um 14:48 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/5 "2014-06-26T14:48:13Z")

</div>

Hallo Daniel, vielen Dank für die Antwort. Leider stehe ich etwas auf dem Schlauch wie du das meinst. Sagen wir, das eine Plugin heißt MyPluginVideo und das andere MyPluginAudio. In MyPluginAudio möchte ich das CustomModel Video von MyPluginVideo nutzen. Muss ich jetzt beide Plugins anpassen, oder nur MyPluginAudio wo ich das fremde CustomModel nutzen möchte? Ein fertiges Beispiel wäre super. Das subscribeEvent verstehe ich noch, aber beim Inhalt der Methode und anschließenden Verwendung im CustomModel von MyPluginAudio hört es auf. Danke und Gruß Marco

---

<div class="post-metadata">

**Author:** ![Kestu](https://avatars.discourse-cdn.com/v4/letter/k/3ab097/32.png) [@Kestu](https://forum.shopware.com/u/Kestu)\
**Post date:** [26. Juni 2014 um 17:10 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/6 "2014-06-26T17:10:05Z")

</div>

Hallo, Du musst soweit ich jetzt weiß nur ein [[color=black]Addon[/color]](http://www.gutscheinaffe.de/blog/addon-loeschen-entfernen-anleitung) abändern. Ich wüsste jetzt nicht gegenteiliges. Dann sollte es auch klappen. Vielleicht kann dir ja jemand ein fertiges Beispiel senden. Grüße

---

<div class="post-metadata">

**Author:** ![EikeBrandtWarneke](https://avatars.discourse-cdn.com/v4/letter/e/cdc98d/32.png) [@EikeBrandtWarneke](https://forum.shopware.com/u/EikeBrandtWarneke)\
**Post date:** [26. Juni 2014 um 19:57 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/7 "2014-06-26T19:57:46Z")

</div>

Du musst quasi nur dafür sorgen, dass die init() Methode innerhalb der bootstrap des zweiten Plugins geladen wird. Du kannst zb einfach eine fake Komponente laden, die das zweite Plugin bereit stellt. Viele Grüße

---

<div class="post-metadata">

**Author:** ![mac](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/mac/32/7855_2.png) [@mac](https://forum.shopware.com/u/mac)\
**Post date:** [27. Juni 2014 um 08:03 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/8 "2014-06-27T08:03:49Z")

</div>

Vielen Dank für die Antworten :thumbup: [quote=“Aquatuning GmbH”]Du kannst zb einfach eine fake Komponente laden, die das zweite Plugin bereit stellt.[/quote] Kannst du mir hierfür einen Codeschnipsel geben? Ich weiß nicht, was du mit einer fake Komponente meinst. Danke und Gruß Marco

---

<div class="post-metadata">

**Author:** ![EikeBrandtWarneke](https://avatars.discourse-cdn.com/v4/letter/e/cdc98d/32.png) [@EikeBrandtWarneke](https://forum.shopware.com/u/EikeBrandtWarneke)\
**Post date:** [27. Juni 2014 um 19:41 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/9 "2014-06-27T19:41:51Z")

</div>

Ungetestet: ` public function onInitResource( Enlight\_Event\_EventArgs $arguments ) { $component = new stdClass(); return $component; } ` Nichts besonders sinnvoll - aber sollte funktionieren. Viele Grüße

---

<div class="post-metadata">

**Author:** ![DanielNogel](https://avatars.discourse-cdn.com/v4/letter/d/96bed5/32.png) [@DanielNogel](https://forum.shopware.com/u/DanielNogel)\
**Post date:** [28. Juni 2014 um 02:27 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/10 "2014-06-28T02:27:55Z")

</div>

[quote=“Aquatuning GmbH”]Du musst quasi nur dafür sorgen, dass die init() Methode innerhalb der bootstrap des zweiten Plugins geladen wird. Viele Grüße[/quote] Hi, wie oben beschrieben sollte es in der Regel reichen, über den Loader den Namespace des Models des anderen Plugins zu registrieren. Da nicht sichergestellt ist, dass das andere Plugin die Models in der init Methode registriert, ist es nicht zielführend, einfach nur dessen init-Methode aufzurufen. lG Daniel

---

<div class="post-metadata">

**Author:** ![mac](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/mac/32/7855_2.png) [@mac](https://forum.shopware.com/u/mac)\
**Post date:** [1. Juli 2014 um 07:32 UTC](https://forum.shopware.com/t/pluginubergreifend-klassen-referenzieren/18814/11 "2014-07-01T07:32:56Z")

</div>

Hallo, vielen Dank die Antworten. Ich habe das Problem mal mit phpStorm und Xdebug angesehen. Es lag an der Annotation für Doctrine. Xdebug ist hier wirklich Gold wert. Ich habe die vorheriege Initialisierung wieder gelöscht und es geht auch ohne bei mir. Wollte nur mal Feedback geben. Danke und Gruß Marco
