Installation
Voraussetzungen
Magento 2.4.x — getestet mit 2.4.9, kompatibel mit früheren 2.4.*-Versionen. PHP 8.1–8.5. Kompatibel sowohl mit dem Standardtheme Luma als auch mit dem Hyvä-Theme.
Setup-Schritte
- Füge die per E-Mail erhaltenen Zugangsdaten in
auth.jsonim Stammverzeichnis des Magento-Projekts ein:{ "http-basic": { "repo.codingrow.com": { "username": "...", "password": "..." } } } composer config repositories.codingrow composer https://repo.codingrow.comcomposer require codingrow/module-mmisbin/magento module:enable Codingrow_Mmisbin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush- Füge deinen Lizenzschlüssel unter Admin → Stores → Configuration → Codingrow Extensions → MMIS → License → License Key ein, speichere und führe anschließend
bin/magento cache:flushaus.
Die gesamte Admin-Oberfläche — jedes Label, jeder Tooltip und jede Anleitung — ist in 7 Sprachen verfügbar, automatisch ausgewählt je Admin-Benutzer:
Admin-Konfiguration
Die profilübergreifend geteilten Einstellungen liegen unter Stores → Configuration → Codingrow Extensions → MMIS (Global Settings): Modul an/aus, Menü-Sichtbarkeit, geteilte Bild-Warteschlange/Watchdog. Jedes Importprofil hat eigene Tabs Einstellungen / Mapping / Benachrichtigungen / Log in der MMIS-Profilliste.
Deinstallation
composer remove codingrow/module-mmis, danach
bin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush.
Bereits importierte Produkte werden nie automatisch angefasst — verwende zuerst das
Rollback-Werkzeug, wenn du auch sie entfernen möchtest.
Benutzerhandbuch
Import-Profile
Jeder Lieferant/Feed, von dem du importierst, ist ein eigenständiges Profil: eigener Feed, eigenes Mapping, eigene Zeitplanung, eigene Einstellungen — völlig unabhängig von jedem anderen Profil. Du kannst so viele Profile parallel auf demselben Katalog ausführen, wie du Lieferanten hast, und jedes fasst nur die Produkte an, die es selbst erstellt hat (nie ein von einem Mitarbeiter manuell erstelltes Produkt, selbst wenn es dasselbe SKU-Präfix hätte).
Feed-Quelle und -Format
Ein Profil liest seinen Feed aus einer von drei Quellen:
| Quelle | Was du konfigurierst |
|---|---|
| URL (Standard) | Ein direkter HTTP-/HTTPS-Link. Unterstützt .zip-komprimierte Feeds transparent (erkannt anhand der Dateisignatur, nicht der Dateiendung). |
| Magento-Dateisystem | Ein Pfad innerhalb der Magento-Installation (z. B. var/import/feed.csv) — nützlich, wenn der Lieferant Dateien per SFTP in einem von dir kontrollierten Ordner ablegt. |
| FTP-Server | Host + Benutzer + Passwort (verschlüsselt gespeichert) — das Modul verbindet sich selbstständig und lädt die Datei herunter. |
Es werden drei Feed-Formate unterstützt: CSV (konfigurierbares Trennzeichen: Komma, Semikolon oder Tabulator), XML (du gibst an, welches sich wiederholende Element ein Produkt darstellt) und JSON (Array von Objekten).
https://codingrow.com/sample-feed.csvOpenAPI:
https://codingrow.com/sample-api.openapi.yamlSpalten-Mapping
Sechs Felder sind immer erforderlich (Produktname, Preis, Menge/Bestand, Gewicht, EAN, Marke) — jedes hat seine eigene Zeile mit Quellspalte, Standardwert und Transformation. Über diese sechs hinaus kannst du beliebig viele freie Mapping-Zeilen hinzufügen, die auf jedes reale Magento-Attribut zielen (nicht nur eine feste Liste historischer Felder) — einschließlich selbst erstellter benutzerdefinierter Attribute.
prezzo_base
für den Preis und peso_kg für das Gewicht: ordne „Preis" → Quellspalte
prezzo_base, „Gewicht" → Quellspalte peso_kg zu. Der
Spaltenname spielt nie eine Rolle, nur die Spalte, auf die jede Zeile zeigt, zählt.
Transformationen und Textfunktionen
Jede Mapping-Zeile hat einen „Transformation"-Typ:
| Transformation | Was sie bewirkt |
|---|---|
| Keine | Direkte Kopie des Werts der Quellspalte. |
| Statischer Wert | Ignoriert die Quellspalte, verwendet immer den festen Text aus „Wert". |
| Textvorlage | Freier Text mit Platzhalter {Spaltenname} — siehe Funktionen unten. |
| Suchen und ersetzen | Groß-/Kleinschreibung ignorierende Suche im Wert der Quellspalte, ersetzt durch deinen Text (genau wie eingegeben). |
| Strip HTML tags | Entfernt HTML-Markup und dekodiert Entitäten aus dem Wert der Quellspalte. Nur für Textattribute. |
| Mathematische Formel | Ein eigenständiger Ausdruck — siehe Mathematische Formeln weiter unten. |
Innerhalb einer Textvorlage stehen neben dem einfachen Platzhalter
{Spaltenname} acht Funktionen zur Verfügung (nur für Textfelder):
| Funktion | Wirkung | Beispiel |
|---|---|---|
ucase{Spalte} | ALLES GROSSBUCHSTABEN | ucase{Marke} → "ACME" |
lcase{Spalte} | alles kleinbuchstaben | lcase{Marke} → "acme" |
proper{Spalte} | Erster Buchstabe Jedes Worts Groß | proper{name} → "roter balken" → "Roter Balken" |
trim{Spalte} | Entfernt führende/nachfolgende Leerzeichen | — |
left{Spalte,N} | Erste N Zeichen | left{SKU,5} |
val{Spalte} | Normalisiert eine Zahl im europäischen Format ("1.234,56") in das Standardformat ("1234.56"), ohne Dezimalstellen zu runden | — |
replace{Spalte,'suchen','neu'} | Sucht/ersetzt nur innerhalb dieses Werts (Suche ohne Berücksichtigung von Groß-/Kleinschreibung), innerhalb einer größeren Vorlage verwendbar | replace{name,'Art.','Artikel'} |
striphtml{Spalte} | Entfernt HTML-Markup und dekodiert Entitäten aus diesem Wert, innerhalb einer größeren Vorlage verwendbar | striphtml{beschreibung} |
{ucase{Marke}} - {proper{name}}
erzeugt bei einer Zeile mit Marke="acme" und name="roter balken" das Ergebnis
"ACME - Roter Balken". Ein falsch geschriebener Funktionsname bleibt
unverändert sichtbar in der Ausgabe, statt stillschweigend zu verschwinden — so fällt
ein Tippfehler immer auf.
Mathematische Formeln
Nur für numerische Felder (Preis, Gewicht, Menge oder ein numerisches
benutzerdefiniertes Attribut): ein eigenständiger Ausdruck mit Platzhalter
{Spaltenname}, den vier Grundoperatoren (+ - * /) und Klammern —
nichts weiter (keine Funktionen, keine Vergleiche). Das Ergebnis wird immer auf maximal
2 Dezimalstellen gerundet.
{B2B-Preis} * 1.30
wendet einen Aufschlag von 30% auf den Großhandelspreis des Lieferanten an.
({preis} + {versandkosten}) / 1.22 addiert den Versand und zieht dann 22%
MwSt. ab, um einen Nettopreis zu erhalten.
Textersetzung über mehrere Felder
Eine Suchen-und-Ersetzen-Regel, die gleichzeitig auf mehrere Rohspalten des Feeds wirken kann, ausgeführt noch bevor das Mapping überhaupt beginnt. Eine Spalte an der Quelle zu bereinigen wirkt sich auf jede Mapping-Zeile aus, die sie liest — statt dieselbe Korrektur bei jedem abgeleiteten Feld einzeln zu wiederholen.
Importfilter (Gruppen/Regeln)
Jede Feed-Zeile durchläuft drei Filter, immer in dieser Reihenfolge — ein späterer Filter sieht nur Zeilen, die den vorherigen überstanden haben:
- Erlaubte Feed-Kategorien — immer zuerst. Eine nicht aufgeführte Kategorie verwirft die Zeile bereits hier, noch bevor eine Gruppe überhaupt berücksichtigt wird.
- Gruppen/Regeln — optional. Ist keine Gruppe konfiguriert, läuft jede Zeile, die Schritt 1 überstanden hat, unverändert durch. Existiert mindestens eine Gruppe, kommen nur die von einer Gruppe erfassten Zeilen durch — Zeilen, die von keiner Gruppe erfasst werden, werden verworfen (anders als „kein Filter").
- Zielkategorie der Gruppe — wenn innerhalb der Gruppe gesetzt, die die Zeile erfasst hat, ersetzt sie den Kategoriepfad vollständig; bleibt sie leer, wird der Kategoriepfad des Feeds unverändert übernommen.
Kategorien
Der Kategoriebaum wird automatisch aus dem Kategoriepfad jedes Produkts im Feed erstellt — Kategorien müssen in Magento nicht vorab angelegt werden. Die Einstellung „Übergeordnete Kategorie" erlaubt es, den gesamten Kategoriebaum eines Profils unter einer gemeinsamen Wurzel zu verschachteln — nützlich, wenn mehrere Profile denselben Katalog teilen und du ihre Kategoriebäume visuell getrennt halten möchtest. Kategorien, die leer bleiben (z. B. nachdem ein Lieferant eine komplette Produktlinie einstellt), lassen sich mit einem Klick oder per CLI bereinigen.
Bildergalerie
Ordne beliebig viele Feed-Spalten den Bildrollen zu (base / small / thumbnail / gallery) — eine einzelne Spalte kann gleichzeitig mehreren Rollen dienen. Heruntergeladene Bilder werden optional komprimiert (verkleinert, wenn breiter als 1200 px, neu komprimiert als JPEG mit Qualität 85, nur beibehalten, wenn das Ergebnis tatsächlich leichter ist), mit konfigurierbarer Nebenläufigkeit und einem Watchdog für den Festplattenspeicher, der Downloads — niemals Produktdaten — pausiert, wenn der freie Speicherplatz knapp wird.
Konfigurierbare Produkte (Varianten)
Feed-Zeilen, die denselben Wert in einer „Gruppen-/übergeordneten Spalte" teilen, werden zu Varianten eines einzigen konfigurierbaren Produkts. Beliebig viele Attribute können gleichzeitig variieren — zum Beispiel Größe, Farbe und ein drittes Attribut zusammen —, jedes benötigt lediglich seine eigene Mapping-Zeile mit einer Spalte, die für jede Variante einen anderen Wert liefert.
Gruppierte Produkte
Konzeptionell anders als bei konfigurierbaren Produkten: kein Variantenattribut, keine Gruppenspalte — nur eine direkte Verknüpfung zwischen einem übergeordneten „Container" und einer beliebigen Anzahl einfacher Produkte, die vollständig unabhängig bleiben (eigener Preis, Bestand und eigene aufrufbare Seite) — nützlich, wenn ein Lieferant sowohl die einzelnen Komponenten separat verkauft als auch ein Kit, das sie zusammen mit je einem Mengenwähler zeigt.
Bestandsverwaltung
Bestandsaktualisierungen können absolut (ersetzen den Wert) oder relativ (addieren/subtrahieren zur aktuellen Menge) sein — nützlich für Lieferanten, deren Feed Änderungen statt Gesamtwerte meldet. Rückstand (Backorder) und „Bestand verwalten" folgen der Konfiguration des Profils, nicht einer einzigen globalen Einstellung.
Vorschau und Ausgabedatei
Zwei Möglichkeiten zu sehen, was eine Synchronisierung tatsächlich in den Katalog schreiben würde — nur die gemappten Felder, nie die Kategorie-/Verkaufbarkeits-/ Gruppenfilter (die Stichprobe ist absichtlich unvollständig):
| Vorschau | Spiegelt die aktuellen Werte des Formulars wider, auch ungespeicherte — klicke sie beim Bearbeiten an, um die Wirkung sofort zu sehen, ohne das Profil zu verändern. |
|---|---|
| Ausgabedatei herunterladen | Verwendet die zuletzt gespeicherte Konfiguration und erzeugt eine herunterladbare JSON-Datei. |
Zeitplanung und Benachrichtigungen
Jedes Profil hat seine eigene Cron-Zeitplanung (von alle 15 Minuten bis einmal täglich, oder einen benutzerdefinierten Cron-Ausdruck), sowohl für die vollständige Katalogsynchronisierung als auch für eine leichtere, nur auf Bestand/Preise beschränkte Synchronisierung. E-Mail-Benachrichtigungen (Erfolg/Warnung/kritischer Fehler) werden je Profil konfiguriert, sodass unterschiedliche Lieferanten im selben Shop unterschiedliche Benachrichtigungsrichtlinien haben können.
Produktlebenszyklus: nichts verschwindet überraschend
Ein Produkt, das aus dem Feed verschwindet oder von einem Filter ausgeschlossen wird, wird immer zuerst deaktiviert — nie gelöscht — und reaktiviert sich automatisch selbst, wenn es in einer späteren Synchronisierung wieder auftaucht. Die endgültige Löschung ist eine separate, optionale Einstellung (standardmäßig deaktiviert): Nur ein Produkt, das länger als eine konfigurierbare Anzahl von Tagen deaktiviert geblieben ist, wird tatsächlich gelöscht, und auch dann erst.
CLI-Befehle
Jede Aktion ist auch über die Kommandozeile verfügbar (nützlich für Cron oder einen sehr großen ersten Import per SSH): die Synchronisierung eines Profils ausführen, die Konfiguration eines Profils exportieren/importieren, alles rückgängig machen, was ein Profil je importiert hat, verwaiste Kategorien bereinigen und mehr — jeweils standardmäßig mit einer Dry-Run-Vorschau, wo destruktiv.