Dokumentation
API-Dokumentation
Unter einer API-Dokumentation verstehen wir in diesem Artikel die automatisch generierte Dokumentation auf Basis des Quellcodes. Manchmal wird diese auch Klassendokumentation genannt. Bei Shopware besteht hier Verwechslungsgefahr zur sogenannten „Rest API“ welches eine technische Schnittstelle zum Shopsystem darstellt.
OXID besitzt die bessere API-Dokumentation (OXID API-Dokumentation), weil die Dokumentation für jede Version vorhanden ist und sich bei jeder Methode mit einem Klick die entsprechende Quellcode-Passage anzeigen lässt. Die Shopware API-Dokumentation hat dies alles nicht.
Artikel, Anleitungen und Bücher
Die besseren Artikel/Anleitungen für Entwickler bietet Shopware. Sie sind qualitativ hochwertiger.
Bei OXID findet man die Artikel hauptsächlich unter: http://wiki.oxidforge.org , daneben existiert ein Entwickler-Cookbook: OXID eShop Kochbuch
Bei Shopware unter findet man die Artikel unter: http://wiki.shopware.de/Labs_cat_444.html
Templating
Allgemein
Shopware und OXID eShop setzen beide Smarty ( http://www.smarty.net/ ) ein. Shopware Smarty in der Version 3. OXID Smarty in einer stark modifizierten Version 2.
Wenngleich beide Shopsysteme Smarty einsetzen, so unterscheiden sie sich grundsätzlich in ihrer Arbeitsweise.
Arbeitweise Shopware
Bei Shopware wird der Ansatz verfolgt, dass das Template in erster Linie vom Web-Designer bearbeitet wird, und dort nur die Präsentation enthalten ist. Businesslogik (= die Funktion der Seite) hat hier nichts zu suchen (die gehört in den Controller). Deshalb sind die Template-Konstrukte einfach gehalten. Auch sind während der Ausführung alle Variablen vorhanden.
Dies entspricht den „Best Practices“ für den Umgang mit Templates (http://www.smarty.net/best_practices).
Arbeitweise OXID eShop
OXID eShop auf der anderen Seite tritt diese Best Practices mit den Füßen. Entsprechend wurde die eingesetzte Smarty version 2 stark modifiziert, so dass diese sehr komplexe Sprachkonstrukte zulässt (siehe Screenshot), die auch massenhaft Anwendung finden. Auch ist es so, dass das Template selber die benötigten Werte anfordert, in dem es Methoden im Controller aufruft. Innerhalb des Templates wird oft mit Objekten gearbeitet, von denen wieder Methoden aufgerufen werden. Dadurch kann ein Chaos entstehen, weil sich die zu bearbeitende Businesslogik sowohl im Controller als auch im Template verbergen kann. Zudem ist es deutlich schwerer, den Programmfluss zu verfolgen, da man durch das alleinige Betrachten des Controllers nicht weiß, welche Methoden von einem bestimmten Template aufgerufen werden und ob überhaupt. Damit ist es schwieriger, OXID Templates an nicht PHP-versierte Frontendentwickler bzw. Designer zu übergeben. Das bedeutet, dass Backend-Entwickler gefordert sind, die Aufgaben des Webdesigners zu beherrschen und entsprechend gute Kenntnisse in Webstandards benötigen. Auch ist durch die vielen OXID-eigenen Erweiterungen ein höherer Lernaufwand vorhanden.
Vor- und Nachteile
Vorteil der OXID Templates ist, dass Entwickler hier viel Freiheit finden. Das nützt in erster Linie Ein-Mann-Teams, die sowieso alles selbst machen (Design und Programmierung). Auch können durch den von OXID gewählten Weg kleinere Änderungen direkt im Template vorgenommen werden, was oft Zeit spart, da kein separates Modul angelegt werden muss. Dies deckt natürlich nur Fälle ab, in denen ansonsten kein Modul benötigt wird.
Ein weiterer Vorteil der OXID Templates ist, dass im Template auskommentierte und somit nicht benötigte Elemente keine Aufrufe an den Controller stellen. Auf diese Weise ist sichergestellt, das im Template nicht verwendete Elemente auch nicht im Controller geladen werden. Dies spart System-Ressourcen. Bei Shopware dagegen muss um den selben Effekt zu erzielen der Controller umgeschrieben werden. Dies verursacht zusätzliche Kosten.
Gemeinsam ist beiden Shopsystemen neben dem Template-System, dass zwischen den Themen eine Vererbungsreihenfolge existiert. D.h. existiert ein Template nicht in Thema A, so wird im darüber liegenden Thema nachgeschaut, ob dort sich das Template befindet.
Shopware geht hier einen Schritt weiter als OXID und ermöglicht es, dass die in Plugins hinzugefügte Templates update-sicher für das vom Shop verwendete Thema angepasst werden können. Mit Updates sind hier Plugin-Updates gemeint. Dies ist insbesondere bei Plugins von Drittanbietern der Fall, wo man nicht selbst der Autor des Updates ist.
Hierfür ist der unter dem jeweiligen Thema liegende „[bereich]/plugin“-Ordner angedacht.
Fazit
Was das Template-Block-System angeht, so hat eindeutig Shopware die Nase vorn. Das Template-Block-System von OXID wirkt unausgereift.
Was den Umgang mit Templates allgemein betrifft, so gehen OXID und Shopware in diesem Punkt völlig unterschiedliche Wege. Shopware hält sich stark an die Standards und sorgt für eine klare Trennung von Businesslogik und Präsentation. OXID dagegen geht den komplett umgekehrten Weg. Shopware ist hier professionell und ordentlich für Teams aus mehreren Programmierern und Designern. OXID ist hier chaotisch aber dafür flexibel für den Guru, der weiß was er macht und alleine arbeitet.
Technische Ausstattung
Sprache
Beide Shopsysteme setzen auf die Sprache PHP in Verbindung mit einer Datenbank.
Verwendete Bibliotheken
OXID eShop wie Shopware setzen auf eine Reihe kleinerer Bibliotheken für diverse Zwecke (z.B. E-Mail), auf die an dieser Stelle nicht eingegangen wird.
Shopware setzt die großen Bibliotheken Zend, Symfony und Doctrine ein.
OXID dagegen auf Eigenentwicklungen und eigene Konzepte.
Beide Shopsysteme nutzen Smarty. Shopware nutzt Smarty in Version 3. OXID nutzt ein stark modifiziertes Smarty in Version 2.
Grundsätzlich lässt sich hier festhalten, dass wenn der Entwickler in den von Shopware genutzten Bibliotheken Erfahrung hat, entsprechend schnell mit Shopware zurecht kommt. Fehlen ihm diese Kenntnisse, so ist es für ihn entsprechend schwieriger sich in Shopware einzuarbeiten, da jedes dieser Frameworks Einarbeitung erfordert.
Backend / Administrationsbereich
OXID eShop setzt auf eine Kombination aus normalen via PHP generierten Seiten und etwas AJAX hier und da.
Shopware setzt dagegen voll auf AJAX unter der Verwendung des JavaScript Frameworks ExtJS.
AJAX-Anwendungen sind grundsätzlich schwerer zu debuggen, da bei Fehlern auf JavaScript-Seite die komplette Anwendung jedesmal neugestartet wird.
Um für Shopware Anwendungen zu schreiben, ist es erforderlich das sich der Entwickler in ExtJS eingearbeitet hat, denn ExtJS ist weit mehr als nur eine simple Bibliothek.
Unterm Strich können wir hier festhalten, das die Entwicklung von Backend-Oberflächen für Shopware schwieriger und aufwendiger ist. Selbst ein erfahrener Entwickler hat es mit OXID einfacher.
Einkaufswelten
Ein tolles Alleinstellungsmerkmal von Shopware sind die Einkaufswelten. So nennt Shopware Seiten, auf denen per „Drag&Drop“ Elemente wie Slideshows und Artikel platziert werden können und so ganz einfach schicke Shop-Seiten zusammengebaut werden können.
Und als Entwickler kann man beliebig neue Elemente entwerfen und hinzufügen.
Dadurch hat Shopware ein CMS-ähnliches System, dass sich vielfältig nutzen lässt.
Weitere Informationen zu den Shopware Einkaufswelten finden Sie hier:
Datenbank
Unterstützte Datenbanken
Shopware nutzt MySQL > 5.1.0.
OXID eShop MySQL 5.0.33 oder höher
Datenbank-Anbindung
Shopware verbindet sich mit der Datenbank über den sogenannten Zend_Db_Adapter welcher eine einheitliche Schnittstelle zu verschiedenen Datenbanken bietet. Zend_Db_Adapter entstammt aus dem Zend Framework, dem offiziellen Framework von PHP.
OXID eShop setzt dagegen auf den Datenbank Abstraction Layer ADOdb.
ADOdb ist im Vergleich zu Zend_Db_Adapter der Dinosaurier, denn ADOdb gibt es bereits seit dem Jahr 2000. Zend_Db_Adapter gibt es dagegen erst seit 2006. Shopware nutzt aktuell (Shop-Version 4.2.1) Zend-Framework in der Version 1.12.
Zend_Db_Adapter unterstützt im Gegensatz zu ADOdb auch die PHP Data Objectrs (PDO), die von PHP in der Version 5 eingeführte hauseigene Datenbank-Abstraktion.
Tabellenstruktur
Ein weiterer Unterschied zwischen Shopware und OXID findet sich in der Tabellenstruktur wieder. Betrachtet sei an dieser Stelle die MySQL-Variante der beiden Shopsysteme.
Shopware setzt voll auf den InnoDB-Tabellen-Typ. Bei OXID sind viele Tabellen MyISAM Tabellen. Dementsprechend nutzt Shopware auch Foreign-Keys inkl. deren Fähigkeit Beschränkungen/Verhaltensweisen zu definieren, wie etwa, dass alle Kind-Einträge in der Kindtabelle automatisch mitgelöscht werden, wenn in der Elterntabelle der zugehörige Eltern-Eintrag gelöscht wurde.
OXID setzt auf Views. Für jede Sprache gibt es eine View der selben Tabelle. Das liegt daran, dass die mehrsprachigen Tabelleninhalte auch in mehreren Spalten in ein und derselben Tabelle liegen. So gibt es beispielsweise in der Tabelle „oxarticles“ die Spalten „OXTITLE_1“, „OXTITLE_2“ und „OXTITLE_3“ für den Titel in unterschiedlichen Sprachen. In der View wird dann die für die jeweilige Sprache genutzte Spalte als „OXTITLE“ selektiert. Dies macht OXID um weniger Tabellenverknüpfungen zu benötigen und dadurch eine höhere Performance zu erzielen.
Eine weitere Eigenheit von OXID sind MD5-Hashes als eindeutige Schlüsselnummern zu verwenden. Nachteil dieser Methode ist der Aufwand diese überall mitgenerieren zu müssen und dabei eigenverantwortlich darauf zu achten, dass diese eindeutig sind. Vorteil dieser Methode ist, dass über diese Hashes leicht geprüft werden kann ob ein Eintrag bereits vorhanden ist. Weiterführend können diese Hashes sogar dazu verwendet werden um zu unterscheiden ob der Eintrag von Methode A hinzugefügt wurde oder nicht (vorausgesetzt, dass Methode A ihre Hashsummen anders bildet als Methode B und natürlich mit einer leicht erhöhten Gefahr dass zufällig ungewollt identische Hashsummen auftreten).
Shopware Tabellennamen sind kleingeschrieben und durch „_“-Zeichen sinnvoll in Wortbestandteile getrennt. OXID Tabellennamen sind klein und zusammengeschrieben. Verknüpfungstabellen bei OXID tragen eine „2“ im Namen. Z.B. „oxobject2category“ (hier werden Artikel mit Kategorien verknüpft). Bei Shopware erkennt man indirekt anhand dem Namen das eine Tabelle einer anderen Tabelle untergeordnet ist. So ist dies der Fall bei der Tabelle „s_articles_categories“ welche „s_articles“ untergeordnet ist. Shopware 4.2.0 hat 226 Tabellen. OXID 4.8 hat ca. 69 Tabellen und 66 Views.
Unterm Strich lässt sich festhalten, dass Shopware und OXID eShop von ihrer Datenbank-Anbindung hier so gut wie ebenbürtig sind, mit gefühlt leichten Vorteilen auf Shopware-Seite.
OXID hat nur ein drittel der Tabellen wie Shopware sie hat. Diese sind dafür teils sehr umfangreich, aber es ist einfacher damit zu arbeiten, weil seltener Tabellenjoins notwendig sind. Bei OXID muss dafür öfter zusätzliche Queries geschrieben werden um die Kind-Einträge in Kindtabellen zu löschen, wenn die zugehörigen Eltern gelöscht werden sollen. Wird dies nicht gemacht, so bläht sich mit der Zeit immer mehr die Datenbank auf. Die Shopware-Tabellennamen sind besser lesbar, dafür sind die OXID Verknüpfungstabellen besser erkennbar.
Coding Style
Der Speicherort der Klassen ist aus dem Klassennamen oft ersichtlich. So liegt beispielsweise die Klasse Shopware_Controllers_Widgets_Emotion in Shopware/Controllers/Widgets/Emotion.php
In welcher Datei OXID Klasse liegt, kann man aus dem Klassennamen allein nicht ableiten. Hierfür ist es notwendig, sich die Funktion der Klasse anzuschauen. Beispielsweise liegt die Klasse „oxarticle“ welche einen Artikel darstellt unter /application/models/oxarticle.php.
Auch gibt es neben den Hauptordnern (models, controllers, translations, usw.) kaum Unterordner in diesen. Die Dateien liegen hauptsächlich in den Hauptordnern.
Bei OXID eShop gibt es weitaus weniger, dafür aber sehr lange Dateien. Die oben genannte oxarticle-Klasse ist beispielsweise (OXID Version 4.8) über 5000 Zeilen lang. Bei Shopware ist das Äquivalent hierzu nur gut 1200 Zeilen lang. Dafür gibt es bei Shopware einige Nebenklassen zu den verschiedenen Artikelbestandteilen.
Deutlicher wird es bei den Controllern. Der Controller für die Detailseite bei OXID ist über 1500 Zeilen schwer. Bei Shopware hingegen sind es nur 225 Zeilen. Das ist ein sechstel der Größe des OXID Controllers.
Die Methoden von OXID sind in ihrer Länge durchschnittlich etwas kürzer.
Sowohl Shopware als auch OXID benutzen CamelCase-Schreibweise bei Methoden, Klassenvariablen und Variablen. OXID setzt den privaten noch ein „_“ voran.
OXID hat außerdem die Eigenheit, dass der Variablentyp aus der Benennung ersichtlich ist. So steht die Variable $iArticleNum für einen Zahlenwert, während $sArticleNum auf eine Zeichenkette hinweist.
Shopware benutzt für seine Controller den ORM von Doctrine.
OXID hat hier eine kleine Eigenentwicklung bemüht, die sich insbesondere dadurch bemerkbar macht, dass auf die hinter einem Model stehenden Tabellenwerte über die Schreibweise $model->tabellenname__spalte->value zugegriffen werden kann, was sich in der Praxis als sehr nützlich erweist.
Bei Shopware kann man dabei über die Funktion „Shopware()“ auf die verschiedenen Bereiche wie Datenbank, Konfiguration, Templates, usw. direkt zugreifen, was sehr praktisch ist.
Bei OXID lässt sich u.a. die Datenbank und die Registry statisch ansprechen. Bei OXID sind die Klassen sehr tief vererbt, so das in der jeweiligen Klasse auf vieles intern direkt zugegriffen werden kann.
Es sei jedoch angemerkt, das innerhalb der Module die Code-Completion einer IDE nicht greift, da für diese nicht ersichtlich ist, welche Klasse gerade überschrieben wird.
Unterm Strich lässt sich festhalten, dass Shopware mehr auf große bekannte Frameworks und deren Arbeitsweise setzt, während OXID eigene Wege geht. Hier muss im Detail abgewägt werden, welches Shopsystem den eigenen Anforderungen besser entspricht. Schlussendlich ist es einfach auch geschmacksache ob man via Volltextsuche sich durch eine lange Datei hangeln möchte, oder lieber mehrere, dafür kurze Dateien nebeneinander offen hat. Und Vorkenntnisse, etwa in Doctrine spielen sicher auch eine Rolle.
Erweiterbarkeit
Bei OXID eShop nennen sich die Erweiterungen „Module“. Bei Shopware „Plugins“.
Die metadata.php
Bei OXID werden die Module über eine Datei metadata.php konfiguriert, in welcher hauptsächlich niedergeschrieben ist:
- Welche existierenden OXID-Klassen durch welche neuen Klassen überschrieben werden sollen. Es wird grundsätzlich das Konzept der Objekt-Vererbung angewendet ( http://www.php.net/manual/de/language.oop5.inheritance.php ) wobei OXID hier noch einen Schritt weitergeht. (Siehe unten.)
- Welche neuen Klassen hinzugefügt werden.
- Welche neuen Templates hinzugefügt werden.
- Welche Template Blöcke durch welche Template-Dateien überschrieben werden sollen.
- Definition einer Methode, die bei Installation aufgerufen wird und Definition einer Methode, die bei Deinstallation aufgerufen wird.
Die bootstrap.php
Bei Shopware werden die Plugins über eine Datei bootstrap.php konfiguriert. Neben der Konfiguration enthält diese Datei auch funktionalen Quelltext.
- Welche neuen Controller hinzugefügt werden.
- Welche neuen Template-Verzeichnisse hinzugefügt werden (die eigentlichen Templates werden dann im entsprechenden Unterverzeichnis abgelegt; Die Verzeichnisstruktur muss mit der Verzeichnisstruktur der Themen insofern übereinstimmen, dass die überschriebenen Templates den selben relativen Dateipfad aufweisen;).
Neue Templates müssen über einen zusätzlichen Befehl registriert werden. - Installations-Routine.
- Deinstallations-Routine.
- Events & Hooks (dazu später mehr). Es ist das Konzept, das Shopware anstelle der Objekt-Vererbung wie sie OXID anwendet, verwendet.
metadata.php vs bootstrap.php
Unterm Strich ist die bootstrap.php mächtiger als die metadata.php. Dies verleitet jedoch auch dazu den funktionalen Quelltext in der bootstrap.php abzulegen, der eigentlich in eine separate Controller-Datei gehört (Es ist technisch sehr wohl möglich diesen auch bei Shopware auszulagern).
Wenngleich es in der metadata.php möglich ist, eine Installations- und eine Deinstallations-Routine anzugeben, so muss man konstatieren, dass das Feature – wohl weil es noch relativ jung ist – bisher sehr selten genutzt wird.
Bestehende Template-Blöcke erweitern
Anders als bei Shopware ist bei OXID eine Registrierung der erweiternden/überschreibenden Template-Blöcke erforderlich. Jeder zu überschreibende Block muss in der metadata.php registriert werden. Auch ist bei OXID für jeden dieser Template-Blöcke eine separate Template-Datei notwendig. Dies erfordert beim Entwickler Disziplin das Template-Block-System von OXID überhaupt zu verwenden (weil es aufwendig ist) und die Template-Block-Dateien so zu benennen, das nicht nur der Blockname ersichtlich ist, sondern auch aus welcher Datei der Block entstammt.
Bei Shopware wird hier ein anderes Konzept angewendet. Für die Datei, in der sich ein oder mehrere zu erweiternde Template-Blöcke befinden wird nur eine Datei mit den erweiternden Blöcken angelegt.
Bestehenden Quellcode erweitern
Der größte Unterschied zwischen OXID eShop und Shopware hinsichtlich der Erweiterbarkeit findet sich in den verschiedenen Konzepten zur Erweiterung bestehenden PHP-Quellcodes.
OXID macht sich hier das Konzept der Objekt-Vererbung zu nutze. Shopware setzt dagegen auf Events und Hooks.
Bei OXID funktioniert das so, dass in der metadata.php zuerst dem Onlineshop mitgeteilt wird welche Klasse erweitert wird:
/** * Module information */ $aModule = array( (...) 'extend' => array( 'oxarticle' => 'cm/cmsetsystem/models/cmsetsystem_oxarticle', ) (...) );
In diesem Beispiel wird der Webshop angewiesen die Klasse „oxarticle“ durch eine Klasse „ cmsetsystem_oxarticle“ zu erweitern, welche sich in der Datei modules/cm/ cmsetsystem/models/cmsetsystem_oxarticle.php befindet.
Die neue Klasse muss dann in der besagten Datei wie folgt definiert sein:
class cmsetsystem_oxarticle extends cmsetsystem_oxarticle_parent { // Methoden }
Jede OXID Klasse kann auf diese Weise beliebig oft erweitert werden.
Instanziert werden derart erweiterte Klassen über die Funktion „oxNew(‚klassenname‘)“. Auf dieses Beispiel bezogen oxNew(‚oxarticle‘). Diese Funktion gibt eine Instanz des jüngsten Kindes zurück, da diese alle über Vererbung hinzugefügten Erweiterungen und Überschreibungen enthält.
Die Reihenfolge in welcher die Überladungen greifen sind in der Administrationsoberfläche unter Erweiterungen->Module frei sortierbar.
Die allermeisten Methoden von OXID-Klassen sind, wenn sie nicht public sind, protected. D.h. es können alle Methoden überschrieben werden. Und natürlich können genauso neue Methoden hinzugefügt werden. Dasselbe gilt grundsätzlich auch für die Klassenvariablen.
Bei Shopware gibt es auf der anderen Seite Events und Hooks.
Events sind Ereignisse, die von Shopware an wichtigen Stellen im Quellcode ausgelöst werden. Nun kann man Shopware mitteilen, dass wenn ein Ereignis auftritt, eine bestimmte Methode aufgerufen werden soll. Der Methode wird dann ein Objekt von Typ Enlight_Event_EventArgs übergeben über welches u.a. auf die Klasse zugegriffen werden kann in der sich das Event befindet.
Hooks funktionieren ähnlich. Hooks sind dazu da, existierende Methoden entweder gänzlich durch eigene zu ersetzen oder die Ausführung einer eigenen Methode dem Aufruf der einer bestehenden Methode vor- oder nachzuschalten. Die eigene Methode wird ein Objekt vom Typ Enlight_Hook_HookArgs übergeben, das analog zu Enlight_Event_EventArgs funktioniert.
Nachteil der Lösung von Shopware ist, dass die eigene Methode nicht Bestandteil derselben Klasse ist wie die, die sie ersetzen soll. Deshalb kann sie nur auf public-Methoden zugreifen.
Auch können nur Methoden gehooked werden, die public oder protected sind und deren Klasse Enlight_Hook implementiert. Dies trifft auf die meisten Methoden/Klassen zu.
Vorteil der Lösung von Shopware ist das Event-System:
Wenn eine Funktion nicht auf die gewünschte Art und Weise arbeitet, ist man bei OXID gezwungen diese Funktion durch eine eigene zu ersetzen. Bei Shopware kann man sich hier und da Events zunutze machen und muss so nicht die Originalfunktion durch eine eigene ersetzen. Ändert nun Shopware die Originalfunktion durch ein Update, müssen diese Änderungen nicht „von Hand“ in die eigene Funktion eingepflegt werden. An dieser Stelle sei jedoch darauf hingewiesen, dass es in der Praxis bei OXID dank der kurzen Methodenlänge meist möglich ist, die notwendigen Änderungen in der eigenen Funktion durchzuführen und von dort aus die Originalfunktion aufzurufen, so dass diese erhalten bleibt.
Da die Shopware-Plugins über den Shopware Store meist verschlüsselt ausgeliefert werden, ist eine Anpassung oft nicht bzw. nur durch den Anbieter der Erweiterung möglich. Dies schafft unschöne Abhängigkeiten und kann so manches Projekt ausbremsen bzw. teurer machen. Auch bei Oxid sind zahlreiche Erweiterungen nur verschlüsselt erhältlich, der Anteil an unverschlüsseltem Quellcode ist unserer Erfahrung allerdings deutlich geringer.
Fazit zur Erweiterbarkeit
- OXID verleitet zu aufgeräumteren Erweiterungen.
- Installation/Deinstallation wird bei OXID derzeit noch eher nicht als innerer Bestandteil der Erweiterung angesehen.
- OXID verleitet dazu, die für eine Erweiterung notwendigen Template-Änderungen direkt im Thema des Onlineshops niederzuschreiben, anstatt diese ordentlich bei den restlichen Modul-Dateien, getrennt vom Shop, abzulegen.
- Die Codeerweiterung fällt bei OXID leichter und gefühlt „natürlicher“ aus. Das spart oft Zeit und Kosten. Bei Shopware besteht über die Events die Möglichkeit, dort wo diese vorhanden sind in den Quellcode von außen einzugreifen wodurch der Quellcode update-sicherer ist. Dieses Möglichkeit bietet jedoch in der Praxis oft keinen Vorteil, da die OXID-Methoden so kurz sind, dass diese oft in den erweiterten Quellcode eingebunden werden können.
- Bei OXID gibt es mehr unverschlüsselte Module, wodurch individuelle Anpassungen bei Shopware oftmals unnötig aufwändig werden.