Markus Michalski FAQ

Product Custom Inputs: Technik

Technische Details zu Product Custom Inputs: Ablauf-Diagramm, Entities und Tabellen, Plugin-Struktur, Migrationen, getrennte Validierung für Storefront und Shop API, Tests.

English Version

Zurück zur Übersicht

Product Custom Inputs: Technik

Diese Dokumentation bezieht sich immer auf die aktuellste veröffentlichte Version.

Ablauf

graph TD
    A["Add-to-Cart-Formular"] --> B["Werte sammeln beim Submit"]
    B --> C["sylius.cart_item_add, Priorität -100"]
    C --> D{"Neue Position oder Merge?"}
    D -->|Neue Position| E["Werte speichern"]
    D -->|Merge| F["Bestehende Werte überschreiben"]
    G["Shop API POST"] --> H{"Plugin aktiv, Warenkorb, Feld passt?"}
    H -->|No| I["404 oder 422"]
    H -->|Yes| E
    E --> J["Anzeige über Twig-Funktion"]
    F --> J

Der Listener läuft mit Priorität -100 und damit nach dem Listener von Sylius. Erst dann steht fest, ob die Position neu ist oder in eine bestehende gemergt wurde.

Entities

erDiagram
    FIELD ||--o{ FIELD_TRANSLATION : has
    FIELD }o--o{ PRODUCT : attached_to
    FIELD ||--o{ ORDER_ITEM_VALUE : filled_by
    ORDER_ITEM ||--o{ ORDER_ITEM_VALUE : holds
Tabelle Inhalt
mmd_sylius_product_custom_inputs_field Felddefinition: Typ, Pflicht, Position, Grenzen, Auswahloptionen (JSON)
mmd_sylius_product_custom_inputs_field_translation Label und Platzhalter pro Locale, eindeutig je Feld und Locale
mmd_sylius_product_custom_inputs_field_product Zuordnung Feld zu Produkt (Many-to-Many)
mmd_sylius_product_custom_inputs_order_item_value Kundeneingabe, eindeutig je Bestellposition und Feld
mmd_sylius_product_custom_inputs_settings Singleton-Zeile (ID 1) mit dem Schalter "Aktiviert"

Die Zuordnung nach Vorbild von ProductOption und Product liegt auf Seite des Feldes. Der Fremdschlüssel der Werte liegt auf der Wert-Tabelle, weil OrderItem in Sylius eine Mapped-Superclass ist, die ein Plugin nicht um eine Relation erweitern kann.

Struktur

src/
  Api/            Provider, Processor, ShopOrderItemResolver
  Command/        SetupCommand
  Controller/     Einstellungsseite
  DependencyInjection/
  Entity/         Felder, Übersetzung, Werte, Einstellungen, Feldtyp-Enum
  EventListener/  CartItemAddCustomInputsListener
  Factory/        Factory für Felder
  Form/           Admin-Formulare, Extensions für CartItemType und Produktformular
  Repository/     Repositories für Felder, Werte und Einstellungen
  Menu/           AdminMenuListener, MenuGroup
  Migrations/     Drei Doctrine-Migrationen
  Twig/           OrderItemCustomInputValuesExtension
  Validation/     ProductCustomInputFieldStringValueValidator
config/
  grids/ routes/ twig_hooks/ services.php
templates/        admin/ und shop/

Migrationen

Drei Migrationen im Namespace Mmd\SyliusProductCustomInputsPlugin\Migrations, sie laufen nach den Migrationen des Sylius-Core: Tabellen für Feld, Übersetzung und Wert, danach die Einstellungstabelle samt Startzeile, zuletzt die Umstellung auf global zuordenbare Felder. Ausgeführt werden sie über den Setup-Command, der nur diese Migrationen berücksichtigt und vorher prüft, dass die des Sylius-Core durch sind.

Validierung

Die Storefront prüft mit typisierten Symfony-Form-Constraints, die Shop API mit ProductCustomInputFieldStringValueValidator auf dem Textformat. Das sind absichtlich zwei getrennte Wege, weil die Eingaben dort in unterschiedlicher Form ankommen. Der Validator prüft Zeit und Datum streng, damit etwa 25:00 oder 2026-02-30 abgelehnt werden.

Tests

PHPUnit: Unit-Tests und Functional-Tests (Admin-CRUD, API, Formular-Extensions, Hook-Registrierung). Das Behat-Gerüst ist vorhanden, enthält aber noch keine Szenarien. Statische Analyse mit PHPStan auf Level max, Coding Standard mit ECS.