custom/plugins/dkcProductoptions/src/Subscriber/OrderLineItemSubscriber.php line 33

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Dkc\Productoptions\Subscriber;
  3. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  4. use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
  5. use Psr\Log\LoggerInterface;
  6. class OrderLineItemSubscriber implements EventSubscriberInterface
  7. {
  8.     private LoggerInterface $logger;
  9.     public function __construct(LoggerInterface $logger)
  10.     {
  11.         $this->logger $logger;
  12.     }
  13.     public static function getSubscribedEvents(): array
  14.     {
  15.         return [
  16.             CartConvertedEvent::class => ['onCartConverted'9999],
  17.         ];
  18.     }
  19.     /**
  20.      * CartConvertedEvent fires when the cart is converted to an order (array-based).
  21.      * This is the correct hook in SW 6.4 to manipulate order line items before persist.
  22.      * We enrich the label and customFields so options appear in:
  23.      * - Admin order detail
  24.      * - All email templates (order confirmation, shipping, etc.)
  25.      * - Invoice / delivery note documents
  26.      */
  27.     public function onCartConverted(CartConvertedEvent $event): void
  28.     {
  29.         $converted $event->getConvertedCart();
  30.         if (!isset($converted['lineItems']) || !is_array($converted['lineItems'])) {
  31.             return;
  32.         }
  33.         $modified false;
  34.         foreach ($converted['lineItems'] as &$lineItem) {
  35.             $payload $lineItem['payload'] ?? [];
  36.             if (!isset($payload['dkc_product_options']) || empty($payload['dkc_product_options'])) {
  37.                 continue;
  38.             }
  39.             $options $payload['dkc_product_options'];
  40.             $optionLabels $payload['dkc_product_options_labels'] ?? [];
  41.             // 1. CustomFields setzen (fuer programmatischen Zugriff)
  42.             $customFields $lineItem['customFields'] ?? [];
  43.             $customFields['dkc_product_options'] = $options;
  44.             if (!empty($optionLabels)) {
  45.                 $customFields['dkc_product_options_labels'] = $optionLabels;
  46.             }
  47.             $lineItem['customFields'] = $customFields;
  48.             // 2. Payload beibehalten (fuer Twig-Zugriff in Templates)
  49.             // payload ist bereits gesetzt, nichts zu tun
  50.             // 3. Label/Description erweitern fuer E-Mail und Dokumente
  51.             $optionTexts = [];
  52.             foreach ($options as $option) {
  53.                 $name $option['name'] ?? '';
  54.                 $price = (float) ($option['price'] ?? 0);
  55.                 if ($price 0) {
  56.                     $optionTexts[] = $name ' (+ ' number_format($price2',''.') . ' EUR)';
  57.                 } else {
  58.                     $optionTexts[] = $name;
  59.                 }
  60.             }
  61.             if (!empty($optionTexts)) {
  62.                 $optionsString implode(', '$optionTexts);
  63.                 $currentLabel $lineItem['label'] ?? '';
  64.                 // Nur anhaengen wenn noch nicht enthalten
  65.                 if (strpos($currentLabel'Produktoptionen:') === false) {
  66.                     $lineItem['label'] = $currentLabel ' | Produktoptionen: ' $optionsString;
  67.                 }
  68.                 $modified true;
  69.                 $this->logger->info('[DkcProductOptions] Order line item enriched', [
  70.                     'label' => $lineItem['label'],
  71.                     'options' => $optionTexts,
  72.                 ]);
  73.             }
  74.         }
  75.         if ($modified) {
  76.             $event->setConvertedCart($converted);
  77.         }
  78.     }
  79. }