<?php declare(strict_types=1);
namespace MasterFFL\Checkout\Storefront\Page\Checkout;
use MasterFFL\Checkout\Service\FFLAttributeService;
use MasterFFL\Checkout\Service\FFLProductService;
use MasterFFL\Checkout\Service\FFLConfigService;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CheckoutPageLoadedSubscriber implements EventSubscriberInterface
{
public function __construct(
private readonly FFLAttributeService $fflAttributeService,
private readonly EntityRepository $productRepository,
private readonly FFLProductService $fflProductService,
private readonly SystemConfigService $systemConfigService,
private readonly FFLConfigService $fflConfigService // ADD THIS
) {}
public static function getSubscribedEvents(): array
{
return [
CheckoutConfirmPageLoadedEvent::class => 'onCheckoutConfirmPageLoaded',
];
}
public function onCheckoutConfirmPageLoaded(CheckoutConfirmPageLoadedEvent $event): void
{
$firearmTypeValue = '';
$cart = $event->getPage()->getCart();
$salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
$hasFFLProducts = false;
$fflProducts = [];
// Get FFL category mappings
$fflCategoryIds = $this->getFFLCategoryIds($salesChannelId);
foreach ($cart->getLineItems() as $lineItem) {
if ($lineItem->getType() === LineItem::PRODUCT_LINE_ITEM_TYPE) {
$productId = $lineItem->getReferencedId();
$criteria = new Criteria([$productId]);
$criteria->addAssociation('categories');
$product = $this->productRepository->search($criteria, $event->getContext())->first();
if ($product instanceof ProductEntity) {
$isFFLProduct = false;
$firearmType = '';
// Check custom fields first
$customFields = $product->getCustomFields();
if (isset($customFields[$this->fflAttributeService->getFFLAttributeName()])) {
$fflValue = $customFields[$this->fflAttributeService->getFFLAttributeName()];
if ($fflValue === 'yes') {
$isFFLProduct = true;
if (isset($customFields[$this->fflAttributeService->getFirearmTypeAttributeName()])) {
$firearmTypeValue = $customFields[$this->fflAttributeService->getFirearmTypeAttributeName()];
$firearmType = $this->getFirearmTypeLabel($firearmTypeValue);
}
}
}
// Check if product is in FFL category
if ($this->isProductInFFLCategory($product, $fflCategoryIds)) {
$fflValue = $customFields[$this->fflAttributeService->getFFLAttributeName()] ?? "yes";
// print_r($fflValue); die;
if ($fflValue === 'no') {
$isFFLProduct = false;
} else {
$isFFLProduct = true;
$firearmType = $this->getFirearmTypeFromCategory($product, $salesChannelId);
}
}
if ($isFFLProduct) {
$hasFFLProducts = true;
$fflProducts[] = [
'id' => $lineItem->getId(),
'label' => $lineItem->getLabel(),
'fflType' => $firearmType,
'quantity' => $lineItem->getQuantity()
];
}
}
}
}
// FIXED: Get FFL configuration and assign to page
$fflConfig = $this->fflConfigService->getFFLConfig($salesChannelId);
$fflConfig['headerColor'] = $this->fflConfigService->getHeaderColor($salesChannelId);
$fflConfig['buttonColor'] = $this->fflConfigService->getButtonColor($salesChannelId);
$fflConfig['firearmType'] = $firearmTypeValue;
$event->getPage()->assign([
'hasFFLProducts' => $hasFFLProducts,
'fflProducts' => $fflProducts,
'fflProductCount' => count($fflProducts),
'fflConfig' => $fflConfig // ADD THIS
]);
// FIXED: Also set as extensions for backward compatibility
$event->getPage()->addExtension('hasFFLProducts', new \Shopware\Core\Framework\Struct\ArrayStruct(['value' => $hasFFLProducts]));
$event->getPage()->addExtension('fflConfig', new \Shopware\Core\Framework\Struct\ArrayStruct($fflConfig));
}
private function getFFLCategoryIds(string $salesChannelId): array
{
$configKey = 'MasterFFLCheckout.config.categoryMappingTable';
$categoryMappings = $this->systemConfigService->get($configKey, $salesChannelId);
if (!is_array($categoryMappings)) {
return [];
}
$fflCategoryIds = [];
foreach ($categoryMappings as $mapping) {
if (isset($mapping['storeCategory']) && !empty($mapping['storeCategory'])) {
$fflCategoryIds[] = $mapping['storeCategory'];
}
}
return $fflCategoryIds;
}
// private function isProductInFFLCategory(ProductEntity $product, array $fflCategoryIds): bool
// {
// if (empty($fflCategoryIds)) {
// return false;
// }
// $productCategories = $product->getCategories();
// if (!$productCategories) {
// return false;
// }
// echo"<pre>"; print_r($productCategories); die;
// foreach ($productCategories as $category) {
// if (in_array($category->getId(), $fflCategoryIds)) {
// die("Category found: " . $category->getId());
// return true;
// }
// }
// return false;
// }
private function isProductInFFLCategory(ProductEntity $product, array $fflCategoryIds): bool
{
if (empty($fflCategoryIds)) {
return false;
}
$productCategories = $product->getCategories();
if (!$productCategories) {
return false;
}
// Extract category IDs from the CategoryCollection
$productCategoryIds = [];
foreach ($productCategories as $category) {
$productCategoryIds[] = $category->getId();
}
// Check if any product category matches FFL categories
foreach ($productCategoryIds as $categoryId) {
if (in_array($categoryId, $fflCategoryIds)) {
error_log("FFL Category match found: " . $categoryId);
return true;
}
}
return false;
}
private function getFirearmTypeFromCategory(ProductEntity $product, string $salesChannelId): string
{
$configKey = 'MasterFFLCheckout.config.categoryMappingTable';
$categoryMappings = $this->systemConfigService->get($configKey, $salesChannelId);
if (!is_array($categoryMappings)) {
return '';
}
$productCategories = $product->getCategories();
if (!$productCategories) {
return '';
}
foreach ($productCategories as $category) {
foreach ($categoryMappings as $mapping) {
if (isset($mapping['storeCategory']) &&
$mapping['storeCategory'] === $category->getId() &&
isset($mapping['fflMapping'])) {
return $this->getFirearmTypeLabel($mapping['fflMapping']);
}
}
}
return '';
}
private function getFirearmTypeLabel(string $value): string
{
return match($value) {
'hand_gun' => 'Handgun',
'long_gun' => 'Long Gun',
'other_firearm' => 'Other Firearm',
'nfa' => 'NFA Item',
default => ''
};
}
}