Markus Michalski FAQ

CDN Product Images: Technik

Architektur, Entscheidungslogik und Caching des Sylius-Plugins CDN Product Images.

English Version

Zurück zur Übersicht

CDN Product Images: Technik

Diese Dokumentation bezieht sich immer auf die aktuellste veroeffentlichte Version.

Live Demo: Teste dieses und weitere Plugins live — ohne Installation, ohne Risiko: demo.markus-michalski.net

Entscheidungslogik

graph TD
    A["Bild-Pfad"] --> B{"Beginnt mit http(s)?"}
    B -->|Nein| C["lokaler Upload, unveraendert"]
    B -->|Ja| D{"Host passt zu CDN-Domain?"}
    D -->|Nein| E["fremde URL, Passthrough"]
    D -->|Ja| F["s3-Bucket/Key extrahieren"]
    F --> G{"Signierte URL im Cache?"}
    G -->|Ja| H["gecachte URL zurueckgeben"]
    G -->|Nein| I["Signing-Service aufrufen"]
    I --> J{"HTTP 200?"}
    J -->|Ja| K["24h cachen, signierte URL"]
    J -->|Nein| L["30s cachen, Original-URL"]

Die Erkennung "CDN-Bild oder lokaler Upload" läuft rein über das Pfad-Präfix (http(s)://) - Sylius' eigener UploadedImagePathGenerator erzeugt ausschließlich relative, Hash-basierte Pfade, die niemals so beginnen können. Es gibt dafür keine eigene Datenbank-Spalte und keine Migration.

Plugin-Struktur

src/
├── Cdn/                      # Signing-Kern: Konfiguration, URL-Signer, Preset-Map
├── Command/                  # mmd:cdn-product-images:setup
├── Controller/Admin/         # Einstellungsseite + Token-Entfernung
├── DependencyInjection/       # Bundle-Extension, Compiler Pass, (leere) Configuration
├── Entity/                   # SigningCredentials (Singleton-Settings-Zeile)
├── Form/Extension/           # cdnUrl-Feld auf Product-/TaxonImageType
├── Form/Type/                # SigningCredentialsType (Admin-Formular)
├── Imagine/                  # dekorierte imagine_filter Twig-Extension
├── Menu/                      # Admin-Sidebar-Eintrag
├── Migrations/                # Doctrine-Migration für die Settings-Tabelle
├── Repository/                # SigningCredentialsRepository
├── Security/                  # SigningTokenCipher (libsodium)
├── Serializer/                # dekorierter Shop-API-Bild-Normalizer
└── Uploader/                  # CDN-fähiger Image-Uploader + Pfad-Erkennung

Dekorierte Services

Dekorierter Service Decorator-Klasse Zweck
liip_imagine.templating.filter_extension CdnAwareImagineFilterExtension imagine_filter auf Twig-Storefront/Admin CDN-fähig machen
sylius.uploader.image CdnAwareImageUploader verhindert, dass ein CDN-Pfad als lokale Datei gelöscht wird
sylius_api.normalizer.image CdnAwareApiImageNormalizer dieselbe Logik für den Shop-API-Kanal - nur registriert, wenn SyliusApiBundle vorhanden ist (eigener Compiler Pass, da Reihenfolge-unabhängig)

Entity & Migration

Entity Tabelle Zweck
SigningCredentials mmd_cdn_signing_credentials Singleton-Zeile (id immer 1) mit CDN-Domain, Signing-API-URL, verschlüsseltem Token-Ciphertext, Schema-Override

Kein Sylius-Resource (kein Grid, keine Liste, kein Create/Delete) - der Admin bearbeitet ausschließlich diese eine Zeile über die Einstellungsseite.

Caching

Was TTL Grund
Erfolgreich signierte URL 24 Stunden Signaturen sind deterministisch - vermeidet einen Netzwerk-Roundtrip pro Bild-Render
Fehlgeschlagener Signing-Versuch 30 Sekunden begrenzt einen Retry-Sturm gegen das Rate-Limit der Signing-API während eines Ausfalls
Aufgelöste Zugangsdaten (Entity → aufbereitete Konfiguration) 60 Sekunden vermeidet eine DB-Abfrage pro Bild-Render; eine Admin-Änderung wirkt innerhalb von rund einer Minute

Resize-Mapping

Jede Sylius-Imagine-Filtergröße wird 1:1 auf eine imgproxy-Resize-Option gemappt (inkl. format: webp und quality: 80, damit ein CDN-Bild dieselbe Bild-Qualität liefert wie ein lokal verarbeitetes). Ein unbekannter Filtername fällt immer auf Passthrough zurück - ein falsch geratenes Resizing wäre schlechter als keines.