<?php declare(strict_types=1);
namespace HochwarthCheckoutCheckbox\Core\Checkout;
use HochwarthCheckoutCheckbox\Core\Content\HochwarthCheckbox\HochwarthCheckboxEntity;
use HochwarthCheckoutCheckbox\Core\Content\HochwarthCheckbox\SalesChannel\AbstractHochwarthCheckboxRoute;
use HochwarthCheckoutCheckbox\Core\Content\HochwarthCheckbox\SalesChannel\HochwarthCheckboxRoute;
use HochwarthCheckoutCheckbox\HochwarthCheckoutCheckbox;
use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
use Shopware\Core\Checkout\CheckoutRuleScope;
use Shopware\Core\Checkout\Order\Event\OrderStateMachineStateChangeEvent;
use Shopware\Core\Content\Rule\RuleEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextRestorer;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Contracts\EventDispatcher\Event;
class CheckoutOrderPlacedSubscriber implements EventSubscriberInterface
{
/**
* @var EntityRepositoryInterface
*/
private $customerRepository;
/**
* @var RequestStack
*/
private $requestStack;
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var EntityRepositoryInterface
*/
private $orderRepository;
private HochwarthCheckboxRoute $checkboxRoute;
private EntityRepositoryInterface $ruleRepository;
private SalesChannelContextRestorer $salesChannelContextRestorer;
public function __construct(
SystemConfigService $systemConfigService,
EntityRepositoryInterface $customerRepository,
EntityRepositoryInterface $orderRepository,
RequestStack $requestStack,
AbstractHochwarthCheckboxRoute $checkboxRoute,
EntityRepositoryInterface $ruleRepository,
SalesChannelContextRestorer $salesChannelContextRestorer
) {
$this->systemConfigService = $systemConfigService;
$this->customerRepository = $customerRepository;
$this->orderRepository = $orderRepository;
$this->requestStack = $requestStack;
$this->checkboxRoute = $checkboxRoute;
$this->ruleRepository = $ruleRepository;
$this->salesChannelContextRestorer = $salesChannelContextRestorer;
}
public static function getSubscribedEvents(): array
{
return [
CartConvertedEvent::class => 'onCartConverted',
CheckoutOrderPlacedEvent::class => 'onCheckoutOrderPlaced',
'state_enter.order.state.completed' => 'onEnterOrderStateCompleted'
];
}
public function onCartConverted(CartConvertedEvent $event): void
{
if ($this->requestStack->getCurrentRequest()->request->get('hochwarth-checkout-checkbox') === null) {
return;
}
$checkboxValue = $this->requestStack->getCurrentRequest()->request->get('hochwarth-checkout-checkbox');
$data = $event->getConvertedCart();
if (!is_array($checkboxValue)) {
$saveCheckboxValueTo = $this->systemConfigService->get('HochwarthCheckoutCheckbox.config.checkboxSave');
if ($saveCheckboxValueTo === 'order') {
$data['customFields'][HochwarthCheckoutCheckbox::CUSTOMER_MARKETING_ALLOWED] = (bool)$checkboxValue;
} elseif ($saveCheckboxValueTo === 'customer') {
$this->customerRepository->update([['id' => $data['orderCustomer']['customerId'], 'customFields' => [HochwarthCheckoutCheckbox::CUSTOMER_MARKETING_ALLOWED => (bool)$checkboxValue]]], $event->getContext());
}
$event->setConvertedCart($data);
return;
}
$checkboxes = $this->checkboxRoute->load($this->requestStack->getMasterRequest(), $event->getSalesChannelContext(), new Criteria())->getCheckboxes();
$saveCustomer = [];
$saveOrder = [];
/** @var HochwarthCheckboxEntity $checkbox */
foreach ($checkboxes as $checkbox) {
switch ($checkbox->getStorage()) {
case 'customer':
$saveCustomer[] = [
'id' => $checkbox->getId(),
'label' => $checkbox->getAdminLabel() ?? 'Marketing checkbox',
'value' => (bool)($checkboxValue[$checkbox->getId()] ?? false)
];
break;
case 'order':
$saveOrder[] = [
'id' => $checkbox->getId(),
'label' => $checkbox->getAdminLabel() ?? 'Marketing checkbox',
'value' => (bool)($checkboxValue[$checkbox->getId()] ?? false)
];
break;
}
}
if (\count($saveOrder)) {
$data['customFields'][HochwarthCheckoutCheckbox::CUSTOMER_MARKETING_ALLOWED_MULTI] = $saveOrder;
}
if (\count($saveCustomer)) {
$this->customerRepository->update([['id' => $data['orderCustomer']['customerId'], 'customFields' => [HochwarthCheckoutCheckbox::CUSTOMER_MARKETING_ALLOWED_MULTI => $saveCustomer]]], $event->getContext());
}
$event->setConvertedCart($data);
}
public function onCheckoutOrderPlaced(CheckoutOrderPlacedEvent $event): void
{
$this->setRules($event);
}
public function onEnterOrderStateCompleted(OrderStateMachineStateChangeEvent $event): void
{
$this->setRules($event);
}
/**
* @param CheckoutOrderPlacedEvent|OrderStateMachineStateChangeEvent $event
*/
private function setRules(Event $event): void
{
$order = $event->getOrder();
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('conditions.type', 'hochwarthCheckoutCheckbox'));
$context = $event->getContext();
$salesChannelContext = $this->salesChannelContextRestorer->restoreByOrder($order->getId(), $context);
$rules = $this->ruleRepository->search($criteria, $context);
$ruleIds = $context->getRuleIds();
/** @var RuleEntity $rule */
foreach ($rules as $rule) {
if ($rule->getPayload()->match(new OrderRuleScope($salesChannelContext, $order))) {
$ruleIds[] = $rule->getId();
}
}
$context->setRuleIds($ruleIds);
}
}