<?php
declare(strict_types=1);
namespace Iwv\IwvTwoFactorAuthentication\Subscriber;
use Shopware\Core\Checkout\Customer\CustomerEvents;
use Shopware\Core\System\User\UserEvents;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class UserEntitySubscriber implements EventSubscriberInterface
{
/** @var EntityRepositoryInterface */
private $userRepository;
/** @var EntityRepositoryInterface */
private $customerRepository;
public function __construct(
EntityRepositoryInterface $userRepository,
EntityRepositoryInterface $customerRepository
) {
$this->userRepository = $userRepository;
$this->customerRepository = $customerRepository;
}
public static function getSubscribedEvents()
{
return [
UserEvents::USER_WRITTEN_EVENT => 'onUserWrittenEvent',
CustomerEvents::CUSTOMER_WRITTEN_EVENT => 'onCustomerWrittenEvent',
];
}
public function onUserWrittenEvent(EntityWrittenEvent $event): void
{
$payloads = $event->getPayloads();
/** @var \Shopware\Core\System\User\UserEntity $userDB */
$updateUsers = [];
$ids = array_filter(array_map(fn($payload) => ($payload['id'] ?? ''), $payloads));
if ($ids) {
foreach ($this->userRepository->search(
(new Criteria())->addFilter(new EqualsAnyFilter('id', $ids)),
$event->getContext()
) as $userDB) {
$customFields = (array) $userDB->getCustomFields();
if (array_key_exists('iwvTwoFactor', $customFields)) {
if (empty($customFields['iwvTwoFactor'])) {
unset($customFields['iwvTwoFactor']);
unset($customFields['iwvTwoFactorCookie']);
unset($customFields['iwvTwoFactorSession']);
$updateUsers[] = [
'id' => $userDB->getId(),
'customFields' => $customFields
];
} elseif (!array_key_exists('iwvTwoFactorCookie', $customFields)) {
$customFields['iwvTwoFactorCookie'] = bin2hex(random_bytes(25));
$updateUsers[] = [
'id' => $userDB->getId(),
'customFields' => $customFields
];
}
}
}
if ($updateUsers) {
$this->userRepository->update($updateUsers, $event->getContext());
}
}
}
public function onCustomerWrittenEvent(EntityWrittenEvent $event): void
{
$payloads = $event->getPayloads();
/** @var \Shopware\Core\Checkout\Customer\CustomerEntity $userDB */
$updateCustomers = [];
$ids = array_map(fn($payload) => $payload['id'] ?? null, $payloads);
$ids = array_filter($ids, fn($id) => $id !== null);
if (!empty($ids)) {
$criteria = new Criteria();
$criteria->addFilter(new EqualsAnyFilter('id', $ids));
foreach ($this->customerRepository->search($criteria, $event->getContext()) as $userDB) {
$customFields = (array) $userDB->getCustomFields();
if (array_key_exists('iwvTwoFactor', $customFields)) {
if (empty($customFields['iwvTwoFactor'])) {
unset($customFields['iwvTwoFactor']);
unset($customFields['iwvTwoFactorCookie']);
unset($customFields['iwvTwoFactorSession']);
$updateCustomers[] = [
'id' => $userDB->getId(),
'customFields' => $customFields
];
} elseif (!array_key_exists('iwvTwoFactorCookie', $customFields)) {
$customFields['iwvTwoFactorCookie'] = bin2hex(random_bytes(25));
$updateCustomers[] = [
'id' => $userDB->getId(),
'customFields' => $customFields
];
}
}
}
}
if ($updateCustomers) {
$this->customerRepository->update($updateCustomers, $event->getContext());
}
}
}