Zum Inhalt springen
Stone & Water
Doku · 06 Feed-Generator

Feed-Generator · Akkordeon-Liste, Filtervorlagen, DBAL-Streaming, Keyset-Pagination und gzip für große Kataloge

Über den Feeds-Tab stellst du automatisch aktualisierte URL-Feeds bereit — für Google Shopping, Preisvergleichsportale oder ERP-Anbindungen. Mit Built-in-Vorlagen, eigenen Profilen, Filtervorlagen, Akkordeon-Liste, Umbenennen, Lösch-Bestätigung, Streaming-Performance für große Kataloge und Token-Authentifizierung.

Was ist ein Feed?

Ein Feed liefert deine Produktdaten unter einer eindeutigen, tokenisierten URL aus — automatisch aktualisiert, ohne manuellen Export. Empfänger ist typischerweise ein externes System: Google Shopping, idealo, Billiger.de, ein ERP-System oder eine Auswertungs-Pipeline. Die URL ist tokenisiert — wer den Token nicht hat, sieht nichts.

Feed anlegen — Vorlage oder eigenes Profil

Oben im Feeds-Tab findest du den Selektor „Feed aus Vorlage / Profil anlegen". Mit einem Klick erzeugst du einen neuen Feed:

  • Built-in-Vorlage — Stammdaten, Preise & Lager, SEO, Bilder, Varianten, Vollexport. Es wird automatisch ein Export-Profil mit passender Feldauswahl erzeugt (Name z.B. „Stammdaten (Feed)"), der Feed aktiviert, ein Token generiert.
  • Bestehendes Profil — eigene Export-Profile aus dem Export-Tab lassen sich direkt als Feed aktivieren.
Mehrere Feeds pro Profil: Du kannst beliebig viele Feeds für dasselbe Profil anlegen — beispielsweise ein „Stammdaten"-Profil als Basis für mehrere Feeds mit unterschiedlichen Filtervorlagen (z.B. ein Feed pro Verkaufskanal oder Zielmarkt). Feeds sind über einen eigenen Storage-Key (exportFeeds) vom Quell-Profil entkoppelt.

Feed-Liste als Akkordeon

Alle aktiven Feeds und alle eigenen Export-Profile erscheinen als kompakte Liste — jede Zeile ist ein eigenständiges Akkordeon. Pro Zeile siehst du auf einen Blick:

  • Name — der Feed-Name (umbenennbar)
  • Status-Pille — „Feed aktiv" (grün) oder „kein Feed" (grau)
  • Feed-URL-Vorschau — die tokenisierte URL bei aktiven Feeds
  • Filtervorlage-Chip — die ausgewählte Filtervorlage oder „kein Filter"
  • Produktanzahl-Chip — Anzahl der enthaltenen Produkte, live aus dem Katalog ermittelt
  • Stift-Symbol rechts (öffnet/schließt den Editor) und Papierkorb (löscht mit Sicherheitsabfrage)

Akkordeon-Verhalten

Ein Klick auf die Zeile öffnet und schließt den Editor zuverlässig — ein Chevron rechts zeigt den Zustand und dreht sich beim Öffnen. Der Papierkorb-Button reagiert separat (mit @click.stop) und klappt die Zeile nicht versehentlich auf/zu.

Editor-Inhalt

Im aufgeklappten Editor stehen alle Konfigurations-Optionen pro Feed:

  • Namensfeld — Feed umbenennen (Name muss eindeutig sein; Kollision mit vorhandenem Feed oder Built-in-Profil wird abgelehnt)
  • Aktivieren-Toggle — Feed online/offline schalten
  • Modus — XML, CSV, TSV oder JSON
  • Filtervorlage — Auswahl aus den gespeicherten Filtervorlagen
  • Feed-URL — fertig zum Kopieren (Button auf gleicher Höhe wie der Token-Button)
  • Token — anzeigen oder regenerieren

Filtervorlagen — was wird übernommen, was bewusst nicht

Statt einfacher Checkboxen (mit/ohne Varianten, nur aktive Produkte) wählst du im Feed jetzt eine gespeicherte Filtervorlage — die gleiche, die du auch im Listing oder bei der Mehrfachänderung nutzt.

Im Feed angewendete Kriterien (serverseitig zuverlässig)

  • Aktiv-Status der Produkte
  • Lagerbestand (Min/Max-Range)
  • Hersteller
  • Kategorie
  • Verkaufskanal

Im Feed bewusst NICHT angewendete Kriterien

Qualitäts- und Vollständigkeitskriterien aus der Filtervorlage (z.B. „Bilder fehlen", „Meta-Daten unvollständig", „ohne Beschreibung", „SEO-Score < X") werden im Feed bewusst nicht angewendet — diese Bewertungen werden im Listing live berechnet und sind im Feed-Kontext nicht zuverlässig serverseitig abbildbar.

Warum diese Trennung wichtig ist: Würde der Feed Qualitätskriterien stillschweigend anwenden, würde dein ERP eine still verfälschte Produktmenge bekommen — manche Produkte würden „verschwinden", ohne dass es jemand bemerkt. Mit der klaren Trennung weißt du genau: Filtervorlage definiert welche Produkte, der Feed liefert diese Produkte.

Produktanzahl live

Pro Feed-Zeile zeigt ein Chip die Anzahl der enthaltenen Produkte. Dieser Wert wird live aus dem Katalog ermittelt (über die Filtervorlage-Kriterien) und aktualisiert sich, wenn du eine andere Filtervorlage wählst.

Orientierungswert: Die Anzahl ist ein DAL-Count über die serverseitig abgebildeten Filterkriterien. Sie kann von der exakten CSV-Zeilenzahl minimal abweichen, wenn z.B. defekte Datensätze beim Export überspringen werden — als Orientierungswert ist sie aber sehr nahe an der Wirklichkeit.

Streaming-Performance für große Kataloge

Feeds laufen über den FeedExportService mit mehreren Performance-Layern — auch Kataloge mit zehntausenden Produkten laufen ohne Memory-Probleme durch:

DBAL-Streaming in 2000er-Batches

Die Feed-Generierung lädt die Produktdaten nicht auf einmal in den Speicher. Stattdessen iteriert der Service in Batches von 2.000 Zeilen durch den Katalog und gibt sie zeilenweise aus (PHP-Generator mit yield). Damit ist der Speicherverbrauch unabhängig von der Katalogröße — egal ob 100 oder 100.000 Produkte.

Keyset-Pagination statt LIMIT/OFFSET

Die Batches verwenden Seek-Pagination über die Artikelnummer (eindeutige, indizierte Spalte):

  • Statt LIMIT 2000 OFFSET 50000 (wird mit jeder Seite langsamer, weil die DB intern bis OFFSET durchblättern muss)
  • Verwendet WHERE product_number > :last ORDER BY product_number LIMIT 2000 — die DB nutzt den Index direkt

Die Ausgabezeit bleibt damit linear zur Anzahl Produkte, egal ob du auf Seite 1 oder Seite 25 bist. Bei großen Katalogen ist das der wichtigste Performance-Hebel — klassisches OFFSET wird in PostgreSQL/MySQL bei deep pages oft drastisch langsamer.

gzip-Komprimierung über HTTP

Wenn der abrufende Client Accept-Encoding: gzip im Request-Header sendet (alle modernen ERP-/Crawler-/Browser-Clients tun das automatisch), wird die Antwort serverseitig per gzencode() komprimiert und mit Content-Encoding: gzip + Vary: Accept-Encoding ausgeliefert.

  • Feed-CSVs sind reiner Text und komprimieren sehr gut — typisch 80–90 % Reduktion
  • Eine 50 MB CSV wird zu ~5–10 MB übertragen — drastisch kürzere Ladezeit, deutlich weniger Bandbreite
  • Der Client dekomprimiert transparent — kein extra Aufwand auf ERP-Seite
  • Compression-Level 5 (Standard) — guter Trade-off zwischen CPU und Komprimierung

Datei-Modus für sehr große Kataloge

Pro Feed lässt sich der Modus wählen:

  • Modus „Live bei Abruf" — Feed wird bei jedem Aufruf direkt aus der Datenbank generiert. Immer tagesaktuell, geeignet für seltenes Polling oder kleinere Kataloge.
  • Modus „Datei" — Ein Scheduled Task generiert die Datei vorab (alle 15 Min, atomar geschrieben nach var/staw-pim-feeds/ über Flysystem). Beim Abruf wird die fertige Datei einfach ausgeliefert — keine DB-Last, sehr schneller Response. Ideal für ERPs, die alle paar Minuten pollen.
Graceful Fallback: Im Datei-Modus, wenn die Cron-Datei noch nicht existiert (z.B. direkt nach dem Anlegen eines neuen Feeds), fällt der Controller automatisch auf Live-Generierung zurück. Du musst nicht warten bis der Cron das erste Mal gelaufen ist.

Memory-Limit-Vorsorge

Der Feed-Endpoint setzt das PHP-Memory-Limit defensiv auf 1 GB (@ini_set('memory_limit', '1024M')) — auch bei sehr breiten Spaltenauswahlen mit dutzenden Custom Fields oder vollem SEO-Set läuft die Generierung sauber durch.

Migration alter Feeds

Automatisch & nicht-destruktiv: Falls du bisher Feeds hattest, die direkt am Export-Profil hingen (mit Token/URL), werden diese beim ersten Laden automatisch in die neue Liste übernommen. Bestehende Feed-URLs in deinem ERP, Google-Shopping-Konto oder bei Preisvergleichsportalen bleiben gültig — kein Re-Konfigurieren nötig.

Token und URL-Format

Jeder Feed bekommt einen eindeutigen Token. Die URL hat das Format:

  • https://dein-shop.de/staw-pim/feed/{token}.xml
  • https://dein-shop.de/staw-pim/feed/{token}.csv
  • https://dein-shop.de/staw-pim/feed/{token}.json
  • https://dein-shop.de/staw-pim/feed/{token}.tsv

Token regenerieren

Der Token-Regenerieren-Button erzeugt einen neuen Token — die alte URL wird damit ungültig. Sinnvoll, wenn ein Feed-Link öffentlich geleakt wurde oder ein Partner-Zugriff entzogen werden soll.

Sicherheit

Token nicht öffentlich teilen: Feed-URLs sind tokenisiert und nicht öffentlich indexierbar (kein Eintrag in sitemap.xml, noindex-Header). Wer den Token kennt, sieht die Produktdaten des Feeds — also nicht in öffentlichen Repositories oder Tickets posten. Bei Verdacht auf Leak: Token regenerieren, alte URL ist sofort ungültig.