<?php declare(strict_types=1);
namespace DreiwmBrandstetterPlugin\Subscriber;
use DateTime;
use Exception;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\Struct\ArrayEntity;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
ProductEvents::PRODUCT_LOADED_EVENT => 'onProductLoaded',
];
}
/**
* Wird aufgerufen, wenn ein Produkt geladen wird.
* Fügt die Erweiterung `seasonalAvailability` zum Produkt hinzu.
* @param EntityLoadedEvent $event
* @throws Exception
*/
public function onProductLoaded(EntityLoadedEvent $event): void
{
foreach ($event->getEntities() as $productEntity) {
// hole die CustomFields aus dem Produkt
$productAvailableFrom = $productEntity->getTranslated()['customFields']['product_available_from'] ?? null;
$productAvailableUntil = $productEntity->getTranslated()['customFields']['product_available_until'] ?? null;
$seasonalAvailability = $this->getProductValidTimeRangeListing($productAvailableFrom,
$productAvailableUntil);
if ($seasonalAvailability) {
// füge die Erweiterung zum Produkt hinzu
$productEntity->addExtension('seasonalAvailability', new ArrayEntity($seasonalAvailability));
}
}
}
/**
* Gibt den Zeitraum zurück, in dem das Produkt gültig ist.
* Wenn es keine Einschränkungen gibt, wird null zurückgegeben.
* @param string|null $productValidFrom
* @param string|null $productValidUntil
* @return array|null
* @throws Exception
*/
public function getProductValidTimeRangeListing(
null|string $productValidFrom,
null|string $productValidUntil
): ?array {
$currentYear = date('Y');
$currentDate = new DateTime();
$season = "Jetzt für kurze Zeit";
$currentlyNotAvailable = "Nur zur Saison erhältlich";
if ($productValidFrom) {
$validFromDate = new DateTime($productValidFrom);
} else {
$validFromDate = null;
}
if ($productValidUntil) {
$validUntilDate = new DateTime($productValidUntil);
} else {
$validUntilDate = null;
}
// Case 3: von DD.MM.YYYY bis DD.MM.YYYY
if ($validFromDate && $validUntilDate) {
if ($currentDate >= $validFromDate && $currentDate <= $validUntilDate) {
return [
'message' => $season,
'season' => true
];
} elseif ($currentDate < $validFromDate) {
// Wenn `validFromDate` und `validUntilDate` im gleichen Jahr liegen
if ($validFromDate->format('Y') == $validUntilDate->format('Y')) {
// wenn beide Daten im aktuellen Jahr liegen
if ($validFromDate->format('Y') == $currentYear) {
return
[
'message' => "ab " . $validFromDate->format('d.m.') . " bis " . $validUntilDate->format('d.m.Y'),
'season' => false
];
} else {
// wenn beide Daten nicht im aktuellen Jahr liegen
return [
'message' => "ab " . $validFromDate->format('d.m.Y') . " bis " . $validUntilDate->format('d.m.Y'),
'season' => false
];
}
} else {
// wenn `validFromDate` im aktuellen Jahr und `validUntilDate` im nächsten Jahr liegt
if ($validFromDate->format('Y') == $currentYear && $validUntilDate->format('Y') > $currentYear) {
return [
'message' => "ab " . $validFromDate->format('d.m.') . " bis " . $validUntilDate->format('d.m.Y'),
'season' => false
];
} else {
// wenn `validFromDate` und `validUntilDate` in unterschiedlichen Jahren liegen, beide in zukünftigen Jahren
return [
'message' => "ab " . $validFromDate->format('d.m.Y') . " bis " . $validUntilDate->format('d.m.Y'),
'season' => false
];
}
}
} else {
return [
'message' => $currentlyNotAvailable,
'season' => false
];
}
}
// Case 4: gesperrt (frei von DD.MM.YYYY bis DD.MM.YYYY)
if ($validFromDate && $validUntilDate && $currentDate <= $validUntilDate) {
$fromYear = $validFromDate->format('Y') != $currentYear ? $validFromDate->format('.Y') : '';
$untilYear = $validUntilDate->format('Y') != $currentYear ? $validUntilDate->format('.Y') : '';
return [
'message' => $validFromDate->format('d.m.') . $fromYear . " bis " . $validUntilDate->format('d.m.') . $untilYear,
'season' => false
];
}
// Case 5: ab DD.MM.YYYY
if ($validFromDate && !$validUntilDate) {
if ($currentDate >= $validFromDate) {
return null;
} else {
return [
'message' => "ab " . $validFromDate->format('d.m.Y'),
'season' => false
];
}
}
// Case 6: bis DD.MM.YYYY
if (!$validFromDate && $validUntilDate) {
if ($currentDate <= $validUntilDate) {
return null;
} else {
return [
'message' => $currentlyNotAvailable,
'season' => true
];
}
}
// Case 7: gesperrt (frei ab DD.MM.YYYY)
if ($validFromDate && $currentDate >= $validFromDate) {
return null;
} else {
if ($validFromDate) {
return [
'message' => "ab " . $validFromDate->format('d.m.Y'),
'season' => false
];
}
}
return null;
}
}