<?php
declare(strict_types=1);
namespace ZweiPunktSameDayDelivery\Subscriber;
use DateTime;
use DateTimeZone;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use ZweiPunktSameDayDelivery\Service\ConfigService;
class ProductPageLoadedSubscriber implements EventSubscriberInterface
{
private ConfigService $configService;
public function __construct(ConfigService $configService)
{
$this->configService = $configService;
}
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoaded',
];
}
public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
$salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
$this->configService->setSalesChannelId($salesChannelId);
if (!$this->configService->isActive()) {
return;
}
$vacationStart = $this->configService->getVacationStart();
$vacationEnd = $this->configService->getVacationEnd();
$vacationMessage = $this->configService->getVacationMessage();
// Abfragen, welches Banner Layout gezeigt werden soll
$viewBanner = $this->configService->getBannerLayout();
$today = new DateTime();
if ($vacationStart <= $today && $today <= $vacationEnd) {
// Wenn wir uns im Urlaubszeitraum befinden, geben wir die Urlaubsnachricht
// an Twig weiter und beenden die Ausführung der Funktion.
$event->getPage()->assign([
'viewBanner' => $viewBanner,
'vacationMessage' => $vacationMessage,
]);
return;
}
// Überprüfen, ob der aktuelle Tag ein Versandtag ist
$deliveryDays = $this->configService->getDeliveryDays();
$currentDay = strtolower(date('l'));
if (!in_array(strtolower($currentDay), $deliveryDays, true)) {
return;
}
// Überprüfen, ob der aktuelle Tag ein Versandausschluss-Feiertag ist
if ($this->checkExclusionDays($this->configService->getExcludeShippingHolidayDays())) {
return;
}
// Überprüfen, ob der aktuelle Tag ein spezifischer Tag ist, an dem kein Versand erfolgen soll
if ($this->checkExclusionDays($this->configService->getExcludeShippingVacationDays())) {
return;
}
// Zugriff auf die benutzerdefinierten Felder des Produkts
$product = $event->getPage()->getProduct();
$customFields = $product->getCustomFields();
// Prüfen, ob das Feld für den Versand am selben Tag deaktiviert ist
// beim Artikel
if ($customFields['zweipunkt_samedaydelivery_switch'] ?? false) {
return;
}
// Abfragen, ob nur Artikel mit Lagerbestand angezeigt werden sollen
$onlyInStock = $this->configService->getOnlyInStock();
// Nur anzeigen, wenn der Aufruf vor der Deadline erfolgt,
// nach der Deadline wird es bis 00:00 Uhr nicht mehr angezeigt.
$currentHour = (new DateTime('now', new DateTimeZone('Europe/Berlin')))->format('H:i:s');
$orderDeadline = $this->configService->getOrderDeadline();
$orderDeadlineHour = (int) explode(':', $orderDeadline)[0];
if ($currentHour > $orderDeadlineHour) {
return;
}
// Hole das Ausgabeformat
$outputFormat = $this->configService->getOutputFormat();
$event->getPage()->assign([
'viewBanner' => $viewBanner,
'outputFormat' => $outputFormat,
'onlyInStock' => $onlyInStock,
'currentHour' => $currentHour,
'orderDeadline' => $orderDeadline,
'vacationMessage' => '',
]);
}
private function checkExclusionDays(string $excludeDaysString): bool
{
// Teilt die Zeichenkette an jedem Komma auf und speichert die
// resultierenden Werte in einem Array
$excludeDays = explode(',', $excludeDaysString);
// Erstellt ein DateTime-Objekt für den aktuellen Tag
$today = new DateTime();
foreach ($excludeDays as $excludeDay) {
// Entferne Leerzeichen vom Anfang und
// Ende des ausgeschlossenen Tags
$excludeDay = trim($excludeDay);
// Versucht, das Datum aus dem ausgeschlossenen Tag zu erzeugen,
// wobei verschiedene Datumsformate berücksichtigt werden
$excludeDate = DateTime::createFromFormat('m-d', $excludeDay)
?: DateTime::createFromFormat('n-j', $excludeDay)
?: DateTime::createFromFormat('j.n', $excludeDay)
?: DateTime::createFromFormat('d.m', $excludeDay)
;
// Überprüft, ob das aus dem ausgeschlossenen Tag erzeugte Datum
// gültig ist und ob es mit dem heutigen Datum übereinstimmt
if (
$excludeDate !== false &&
$excludeDate->format('m-d') === $today->format('m-d')
) {
return true;
}
}
return false;
}
}