<?php declare(strict_types=1);
namespace Dkc\Productoptions\Subscriber;
use Dkc\Productoptions\Entity\ProductOption\ProductOptionCollection;
use Dkc\Productoptions\Struct\PriceStruct;
use Dkc\Productoptions\Struct\LabelStruct;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Context;
class ProductPageLoadedEventSubscriber implements EventSubscriberInterface
{
private EntityRepositoryInterface $productOptionRepository;
private EntityRepositoryInterface $productOptionProductRepository;
public function __construct(
EntityRepositoryInterface $productOptionRepository,
EntityRepositoryInterface $productOptionProductRepository
) {
$this->productOptionRepository = $productOptionRepository;
$this->productOptionProductRepository = $productOptionProductRepository;
}
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoaded'
];
}
public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
try {
$page = $event->getPage();
$product = $page->getProduct();
$productId = $product->getId();
$salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
$context = $event->getContext();
// Kriterien erstellen
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('products.id', $productId));
$criteria->addFilter(new EqualsFilter('salesChannels.id', $salesChannelId));
// Assoziationen vollständig laden
$criteria->addAssociation('products');
// Suche nach den Optionen
$options = $this->productOptionRepository->search($criteria, $context);
// Preise aus der Zwischentabelle laden
$mappingCriteria = new Criteria();
$mappingCriteria->addFilter(new EqualsFilter('productId', $productId));
$mappings = $this->productOptionProductRepository->search($mappingCriteria, $context);
$priceMappings = [];
foreach ($mappings as $mapping) {
$optionId = $mapping->get('productOptionId');
$price = $mapping->get('price');
if ($optionId && $price !== null) {
$priceMappings[$optionId] = $price;
}
}
// Optionen Collection vorbereiten
$optionsCollection = new ProductOptionCollection();
foreach ($options as $option) {
$optionId = $option->getId();
// Preis setzen
if (isset($priceMappings[$optionId])) {
$priceValue = (float)$priceMappings[$optionId];
$priceStruct = new PriceStruct($priceValue);
$option->addExtension('price', $priceStruct);
}
// Das Label als Struct speichern
$labelData = $option->getLabel();
// Stelle sicher, dass wir ein Array haben
if (!is_array($labelData)) {
$labelData = [];
}
// Setze den Namen als Fallback
if (empty($labelData) || (!isset($labelData['default']) && !isset($labelData['de-DE']))) {
$labelData['default'] = $option->getName();
}
$labelStruct = new LabelStruct($labelData);
$option->addExtension('optionLabel', $labelStruct);
$optionsCollection->add($option);
}
// Füge die Optionen zum Produkt hinzu
$product->addExtension('dkcProductOptions', $optionsCollection);
} catch (\Exception $e) {
// Stille Fehlerbehandlung
}
}
}