<?php declare(strict_types=1);
namespace Dkc\Productoptions\Subscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
use Psr\Log\LoggerInterface;
class OrderLineItemSubscriber implements EventSubscriberInterface
{
private LoggerInterface $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public static function getSubscribedEvents(): array
{
return [
CartConvertedEvent::class => ['onCartConverted', 9999],
];
}
/**
* CartConvertedEvent fires when the cart is converted to an order (array-based).
* This is the correct hook in SW 6.4 to manipulate order line items before persist.
* We enrich the label and customFields so options appear in:
* - Admin order detail
* - All email templates (order confirmation, shipping, etc.)
* - Invoice / delivery note documents
*/
public function onCartConverted(CartConvertedEvent $event): void
{
$converted = $event->getConvertedCart();
if (!isset($converted['lineItems']) || !is_array($converted['lineItems'])) {
return;
}
$modified = false;
foreach ($converted['lineItems'] as &$lineItem) {
$payload = $lineItem['payload'] ?? [];
if (!isset($payload['dkc_product_options']) || empty($payload['dkc_product_options'])) {
continue;
}
$options = $payload['dkc_product_options'];
$optionLabels = $payload['dkc_product_options_labels'] ?? [];
// 1. CustomFields setzen (fuer programmatischen Zugriff)
$customFields = $lineItem['customFields'] ?? [];
$customFields['dkc_product_options'] = $options;
if (!empty($optionLabels)) {
$customFields['dkc_product_options_labels'] = $optionLabels;
}
$lineItem['customFields'] = $customFields;
// 2. Payload beibehalten (fuer Twig-Zugriff in Templates)
// payload ist bereits gesetzt, nichts zu tun
// 3. Label/Description erweitern fuer E-Mail und Dokumente
$optionTexts = [];
foreach ($options as $option) {
$name = $option['name'] ?? '';
$price = (float) ($option['price'] ?? 0);
if ($price > 0) {
$optionTexts[] = $name . ' (+ ' . number_format($price, 2, ',', '.') . ' EUR)';
} else {
$optionTexts[] = $name;
}
}
if (!empty($optionTexts)) {
$optionsString = implode(', ', $optionTexts);
$currentLabel = $lineItem['label'] ?? '';
// Nur anhaengen wenn noch nicht enthalten
if (strpos($currentLabel, 'Produktoptionen:') === false) {
$lineItem['label'] = $currentLabel . ' | Produktoptionen: ' . $optionsString;
}
$modified = true;
$this->logger->info('[DkcProductOptions] Order line item enriched', [
'label' => $lineItem['label'],
'options' => $optionTexts,
]);
}
}
if ($modified) {
$event->setConvertedCart($converted);
}
}
}