Eigene Module: erweitern, wo Magento es vorsieht
Magento ist modular aufgebaut, und eigene Funktionen gehören in eigene Module, nicht in den Core. Für Eingriffe in bestehendes Verhalten gibt es zwei vorgesehene Wege. Plugins, auch Interceptors genannt, ändern öffentliche Methoden vor, nach oder um ihren Aufruf herum — before, after, around — und werden in der di.xml deklariert; die Interceptor-Klassen erzeugt Magento selbst. Observer reagieren auf Events, die Magento oder ein anderes Modul auslöst, und werden in der events.xml zugeordnet, global oder je Bereich wie Storefront oder Admin. Wir wählen den Weg, der am wenigsten berührt: lieber ein after-Plugin als ein around-Plugin, lieber ein Observer, wenn ein passendes Event existiert. Je kleiner der Eingriff, desto kleiner die Prüfung beim nächsten Update.
Abhängigkeiten bekommt ein Modul über Dependency Injection: Der Object Manager setzt ein, was in der di.xml konfiguriert ist. Den Object Manager selbst injizieren wir nicht, auch wenn das in gewachsenem Code oft zu finden ist — es versteckt Abhängigkeiten und erschwert Tests. Eine preference, also eine eigene Standardimplementierung für ein Interface oder eine Klasse, setzen wir nur dort ein, wo kein Plugin reicht. Sie ersetzt das Original vollständig, und von mehreren preferences auf dieselbe Klasse gewinnt nur eine. Nach außen spricht ein gutes Modul über Service Contracts: PHP-Interfaces, getrennt in Data Interfaces für die Datenstrukturen und Service Interfaces für die Operationen. Andere Module, Schnittstellen und spätere Erweiterungen hängen dann an einem Vertrag, nicht an einer Implementierung.
Tabellen und Spalten beschreibt ein Modul über Declarative Schema statt über die alten Upgrade-Skripte. Inhalte, die mit dem Modul kommen — Attribute, Konfiguration, Stammdaten —, legen Data Patches an, Änderungen, die sich nicht deklarativ ausdrücken lassen, Schema Patches; beide lassen sich bei Bedarf revertierbar bauen. Jedes Modul prüfen wir gegen den Magento Coding Standard, einen Regelsatz für PHP_CodeSniffer. Ausgerollt wird über Composer und Git, mit bin/magento setup:upgrade, setup:di:compile und setup:static-content:deploy im Produktionsmodus, nie per Upload von Hand. Der Code liegt in einem Git-Repository, das Ihnen gehört, und jede Änderung ist nachvollziehbar. Fertig ist ein Modul erst, wenn ein anderer Entwickler es ohne Rückfrage lesen kann.
Fremde Extensions und gewachsener Code: prüfen und update-fest machen
Die meisten Magento-Shops, die zu uns kommen, haben eine Geschichte: Extensions aus dem Adobe Commerce Marketplace, kostenlos oder gekauft, Module früherer Dienstleister, kleine Anpassungen direkt im Code. Am Anfang steht deshalb eine Bestandsaufnahme jedes Moduls. Woher kommt es, pflegt es noch jemand, und auf welche Magento- und PHP-Versionen ist es ausgelegt? Welche Plugins, Observer und preferences bringt es mit, welche Klassen ersetzt es, wo kollidiert es mit anderen Modulen? Gibt es Änderungen in vendor/ oder kopierte Core-Dateien? Dazu läuft der Coding Standard über den eigenen Code, und setup:di:compile zeigt, ob sich das Ganze sauber kompilieren lässt. Das Ergebnis ist eine Liste, keine Meinung.
Für jedes Modul fällt dann eine Entscheidung: behalten, aktualisieren, durch eine gepflegte Alternative ersetzen, als eigenes Modul sauber neu bauen oder entfernen, weil niemand die Funktion mehr nutzt. Core-Änderungen ziehen wir in eigene Module heraus, als Plugin oder Observer, damit Composer bei Updates wieder freie Hand hat. Zur Werkzeugfrage: Das Upgrade Compatibility Tool von Adobe ist laut Hersteller nur für Adobe-Commerce-Instanzen verfügbar. In Magento Open Source prüfen wir deshalb mit Coding Standard, Compiler, vorhandenen Tests und einem Durchlauf auf einem Staging-System mit einer Kopie der Live-Daten. Auch die Zugangsschlüssel des Marketplace sind editionsgebunden; ein Schlüssel für Open Source funktioniert nicht für Adobe Commerce. Die günstigste Update-Prüfung gilt einer Extension, die nicht mehr installiert ist.
Wie viel Arbeit ein Update für Ihre Extensions bedeuten kann, zeigt der Schritt auf 2.4.9. Adobe hat dort Zend_Cache durch symfony/cache ersetzt, Laminas MVC durch eine eigene MVC-Implementierung, die Symfony-Abhängigkeiten auf 7.4 LTS gehoben und im WYSIWYG-Editor TinyMCE durch HugeRTE abgelöst. Extensions, die Zend_Cache nutzen, müssen laut Adobe angepasst werden; wer den Editor erweitert hat, prüft gegen HugeRTE. Freigegeben ist für 2.4.9 nur PHP 8.5. Wir passen eigene und übernommene Module an und klären mit den Herstellern gekaufter Extensions, wann kompatible Versionen kommen. Wie Updates, Sicherheitspatches und Betrieb insgesamt laufen, beschreibt unsere Seite zu Magento Open Source. Hier geht es um den Code, der dabei mitmuss.
Schnittstellen zu ERP, PIM und Versand
Eine Schnittstelle entscheidet sich an der Richtungsfrage: Welches System führt Artikelstamm, Preise, Bestände, Kunden und Bestellungen, und welches liest nur? Ist das je Feld geklärt, ist die Technik Handwerk. Magento bringt dafür die Commerce Web API mit, als REST- und als GraphQL-Schnittstelle, beide auch in Magento Open Source. REST nutzen wir meist für den Datenaustausch zwischen Systemen, GraphQL dort, wo ein Frontend oder eine App gezielt Daten abfragt. Bietet das ERP keine Schnittstelle, sondern exportiert Dateien, liest ein eigenes Modul diese Dateien ein, mit denselben Regeln für Protokoll und Fehlerbehandlung. Welches ERP oder PIM dahintersteht, ist zweitrangig. Der Aufwand steckt im Zustand der Daten, nicht im Protokoll.
Große Datenmengen gehören nicht in einen einzelnen Aufruf, der so lange läuft, bis etwas abbricht. Magento verarbeitet Massenvorgänge über Message Queues: Die REST-Bulk-Endpunkte etwa legen Aufträge in eine Warteschlange, die Consumer abarbeiten, gestartet mit bin/magento queue:consumers:start. Als Broker unterstützt Magento RabbitMQ und ActiveMQ Artemis; für den Dauerbetrieb empfiehlt Adobe in den Release Notes zu 2.4.9 ActiveMQ Artemis. Regelmäßige Abgleiche laufen als geplante Jobs über den Magento-Cron. Jeder Lauf schreibt ein Protokoll, ein fehlerhafter Datensatz landet in einer Fehlerliste, statt den ganzen Abgleich anzuhalten, und ein abgebrochener Lauf lässt sich wiederholen, ohne Daten doppelt anzulegen. Stehen die Consumer still, soll das die Überwachung melden, nicht ein Kunde.
Ein Beispiel aus unserer Arbeit ist der Magento-Shop der Manotura GmbH & Co. KG für Bewässerungstechnik: Beregnungsanlagen, Rohrsysteme und Zubehör, ein Sortiment, das sich nur über technische Merkmale sinnvoll filtern lässt. Artikelstamm, Preise und Bestände kommen aus der Warenwirtschaft, Bestellungen gehen dorthin zurück. Die Übertragungen laufen als geplante Jobs mit Protokollierung und Wiederholungslogik, sodass ein einzelner Fehlschlag nicht den ganzen Abgleich blockiert. Über 12.000 Artikel stehen im synchronisierten Katalog, Preise und Bestände werden stündlich abgeglichen, und der Pflegeaufwand liegt rund 40 Prozent unter dem einer Doppelerfassung. Für den Versand bringt 2.4.9 eine Anbindung an DHL über die MyDHL-REST-API mit; andere Dienstleister binden wir über deren Schnittstellen an. Gepflegt wird an einer Stelle, und der Shop folgt.
B2B in Magento Open Source: eigene Module statt B2B-Lizenz
Das B2B-Modul von Adobe gehört zu Adobe Commerce und braucht laut Adobe eine eigene Lizenz. Ebenfalls nur in Adobe Commerce enthalten sind unter anderem Customer Segments und Content Staging. Wer Magento Open Source nutzt, baut B2B-Funktionen deshalb als eigene Module — auf einer Grundlage, die Open Source bereits mitbringt: Kundengruppen, Staffelpreise, Katalog- und Warenkorbpreisregeln, mehrere Websites, Shops und Store Views mit eigenen Sprachen und Währungen, dazu das standardmäßig installierte Inventory Management. Das ist mehr, als viele erwarten, und für manchen B2B-Shop schon genug. Der Rest ist Entwicklung, die zu Ihrem Vertrieb passt statt zu einem fertigen Funktionspaket. Wo bereits eine Adobe-Commerce-Lizenz besteht, nutzen wir das B2B-Modul und ergänzen es dort, wo es nicht reicht.
Typische Module, die wir für B2B in Open Source bauen: Preise je Kunde aus dem ERP statt einer eigenen Kundengruppe pro Kunde, Firmenkonten mit mehreren Bestellern und Rollen, Bestellfreigaben ab einem Betrag oder für bestimmte Warengruppen, Budgets je Kostenstelle, Schnellbestellung über Artikelnummer und Menge, Angebotsanfragen aus dem Warenkorb und ein Katalog, der Preise erst nach geprüfter Registrierung zeigt. Bestellen Einkäufer aus einem Beschaffungssystem, kommt ein Punch-out per OCI dazu; der Warenkorb geht dann zurück in das System des Kunden. Jede dieser Funktionen nutzt die vorgesehenen Erweiterungspunkte, also Plugins, Observer und Service Contracts, und bekommt eigene Tabellen über Declarative Schema. Gebaut wird, was Ihr Vertrieb tatsächlich braucht, nicht alles, was ein B2B-Paket enthalten könnte.
Kundenpreise haben eine technische Seite, die oft unterschätzt wird. Ein Preis, der nur für einen Kunden gilt, darf nicht im HTTP-Cache für alle landen, muss beim Indexieren berücksichtigt werden und in Suche, Filtern und Suchvorschlägen genauso gelten wie auf der Produktseite. Bei vielen Kunden und häufigen Preisänderungen ist die Frage, ob Preise vorab berechnet oder beim Aufruf ermittelt werden, eine Architekturentscheidung mit Folgen für Indexer und Ladezeit. Wir treffen sie vor der Entwicklung, anhand Ihrer Zahl an Kunden, Artikeln und Preisänderungen. Wie Sichtbarkeiten und Kundenpreise in der Shopsuche gelten, beschreibt unsere Seite zur Shopsuche mit OpenSearch. Eine langsame Seite verzeiht ein Geschäftskunde eher als einen Preis, der nicht seiner ist.
Frontend und Performance: Theme, Hyvä, Indexer, Cache
Ein eigenes Theme erbt von einem bestehenden und überschreibt gezielt Layout-Dateien und Templates, statt sie im Ganzen zu kopieren. Jede überschriebene Datei muss beim Update gegen das neue Original gelesen werden; die Zahl der Eingriffe bestimmt deshalb die Wartungskosten, nicht das Aussehen. Seit dem 10. November 2025 ist das Hyvä Theme kostenlos und quelloffen, unter denselben Lizenzen wie Magento Open Source, OSL-3.0 und AFL-3.0. Kostenpflichtig bleiben Hyvä UI, Hyvä Checkout sowie die Pakete Hyvä Commerce und Hyvä Enterprise. Ob Hyvä für Ihren Shop passt, hängt weniger am Theme als an den Extensions: Jedes Modul, das eigenes Frontend mitbringt, muss mit dem gewählten Theme funktionieren. Das prüfen wir vor der Entscheidung, Modul für Modul.
Performance beginnt mit Messen. Bei langsamen Kategorie- und Produktseiten liegt die Ursache selten an der Hardware, meist an Indexern, Cache und Modulen. Indexer halten berechnete Daten wie Preise, Kategoriezuordnungen und Bestände aktuell; bin/magento indexer:reindex baut sie einmalig neu auf, laufend aktuell bleiben sie nur mit einem funktionierenden Cron. Davor steht Varnish als HTTP-Cache, der fertige Seiten ausliefert, ohne PHP zu starten — solange kein Modul eine Seite unnötig als nicht cachebar markiert. Valkey übernimmt Cache und Sessions, Message-Queue-Consumer arbeiten Hintergrundaufgaben ab. Fällt einer dieser Bausteine aus oder ist er falsch eingestellt, wird der ganze Shop langsam, und das Symptom zeigt selten auf die Ursache.
Wir suchen deshalb zuerst die Stelle, an der die Zeit verloren geht: in der Datenbank, in einem Plugin, das bei jedem Produkt eine externe Abfrage stellt, in einem Template, in einem Indexer, der hinterherläuft, oder in der Suche. Für Suche und Filter mit OpenSearch gibt es eine eigene Seite; hier geht es um den Code. Im Produktionsmodus, gesetzt mit bin/magento deploy:mode:set production, laufen Kompilierung und Static Content Deploy mit; ein Live-Shop im Entwicklermodus verschenkt Zeit bei jedem Aufruf. Den Betrieb der Dienste dahinter — Server, Varnish, Valkey, OpenSearch, Staging — beschreibt unsere Seite zu Magento Open Source. Eine Optimierung, die niemand gemessen hat, ist eine Vermutung mit Rechnung.