Fix sending both verification and registration emails at once

This commit is contained in:
Jakub Tobiasz 2023-05-20 19:33:57 +02:00 committed by Jacob Tobiasz
parent f551968738
commit 74d9a71746
No known key found for this signature in database
GPG key ID: 6434250CB3525233
4 changed files with 53 additions and 3 deletions

View file

@ -16,6 +16,7 @@ namespace Sylius\Bundle\ApiBundle\CommandHandler\Account;
use Sylius\Bundle\ApiBundle\Command\Account\SendAccountRegistrationEmail;
use Sylius\Bundle\CoreBundle\Mailer\Emails;
use Sylius\Component\Channel\Repository\ChannelRepositoryInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Mailer\Sender\SenderInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
@ -36,8 +37,13 @@ final class SendAccountRegistrationEmailHandler implements MessageHandlerInterfa
/** @var ShopUserInterface $shopUser */
$shopUser = $this->shopUserRepository->findOneByEmail($command->shopUserEmail);
/** @var ChannelInterface $channel */
$channel = $this->channelRepository->findOneByCode($command->channelCode);
if ($channel->isAccountVerificationRequired() && !$shopUser->isEnabled()) {
return;
}
$this->emailSender->send(
Emails::USER_REGISTRATION,
[$command->shopUserEmail],

View file

@ -14,12 +14,17 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\CommandHandler\Account;
use InvalidArgumentException;
use Sylius\Bundle\ApiBundle\Command\Account\SendAccountRegistrationEmail;
use Sylius\Bundle\ApiBundle\Command\Account\VerifyCustomerAccount;
use Sylius\Calendar\Provider\DateTimeProviderInterface;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\Component\User\Model\UserInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Stamp\DispatchAfterCurrentBusStamp;
/** @experimental */
final class VerifyCustomerAccountHandler implements MessageHandlerInterface
@ -27,12 +32,15 @@ final class VerifyCustomerAccountHandler implements MessageHandlerInterface
public function __construct(
private RepositoryInterface $shopUserRepository,
private DateTimeProviderInterface $calendar,
private MessageBusInterface $commandBus,
private ChannelContextInterface $channelContext,
private LocaleContextInterface $localeContext,
) {
}
public function __invoke(VerifyCustomerAccount $command): JsonResponse
{
/** @var UserInterface|null $user */
/** @var ShopUserInterface|null $user */
$user = $this->shopUserRepository->findOneBy(['emailVerificationToken' => $command->token]);
if (null === $user) {
throw new InvalidArgumentException(
@ -44,6 +52,14 @@ final class VerifyCustomerAccountHandler implements MessageHandlerInterface
$user->setEmailVerificationToken(null);
$user->enable();
$channel = $this->channelContext->getChannel();
$localeCode = $this->localeContext->getLocaleCode();
$this->commandBus->dispatch(
new SendAccountRegistrationEmail($user->getEmail(), $localeCode, $channel->getCode()),
[new DispatchAfterCurrentBusStamp()]
);
return new JsonResponse([]);
}
}

View file

@ -213,6 +213,9 @@
<service id="Sylius\Bundle\ApiBundle\CommandHandler\Account\VerifyCustomerAccountHandler">
<argument type="service" id="sylius.repository.shop_user" />
<argument type="service" id="Sylius\Calendar\Provider\DateTimeProviderInterface" />
<argument type="service" id="sylius.command_bus" />
<argument type="service" id="sylius.context.channel" />
<argument type="service" id="sylius.context.locale" />
<tag name="messenger.message_handler" bus="sylius.command_bus" />
<tag name="messenger.message_handler" bus="sylius_default.bus" />
</service>

View file

@ -15,19 +15,29 @@ namespace spec\Sylius\Bundle\ApiBundle\CommandHandler\Account;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\ApiBundle\Command\Account\SendAccountRegistrationEmail;
use Sylius\Bundle\ApiBundle\Command\Account\VerifyCustomerAccount;
use Sylius\Calendar\Provider\DateTimeProviderInterface;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\Component\User\Model\UserInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Stamp\DispatchAfterCurrentBusStamp;
final class VerifyCustomerAccountHandlerSpec extends ObjectBehavior
{
function let(
RepositoryInterface $shopUserRepository,
DateTimeProviderInterface $dateTimeProvider,
MessageBusInterface $commandBus,
ChannelContextInterface $channelContext,
LocaleContextInterface $localeContext,
): void {
$this->beConstructedWith($shopUserRepository, $dateTimeProvider);
$this->beConstructedWith($shopUserRepository, $dateTimeProvider, $commandBus, $channelContext, $localeContext);
}
function it_is_a_message_handler(): void
@ -39,14 +49,29 @@ final class VerifyCustomerAccountHandlerSpec extends ObjectBehavior
RepositoryInterface $shopUserRepository,
DateTimeProviderInterface $dateTimeProvider,
UserInterface $user,
MessageBusInterface $commandBus,
ChannelContextInterface $channelContext,
LocaleContextInterface $localeContext,
ChannelInterface $channel,
): void {
$shopUserRepository->findOneBy(['emailVerificationToken' => 'ToKeN'])->willReturn($user);
$dateTimeProvider->now()->willReturn(new \DateTime());
$user->getEmail()->willReturn('shop@example.com');
$user->setVerifiedAt(Argument::type(\DateTime::class))->shouldBeCalled();
$user->setEmailVerificationToken(null)->shouldBeCalled();
$user->enable()->shouldBeCalled();
$channel->getCode()->willReturn('WEB');
$channelContext->getChannel()->willReturn($channel);
$localeContext->getLocaleCode()->willReturn('en_US');
$commandBus->dispatch(
new SendAccountRegistrationEmail('shop@example.com', 'en_US', 'WEB'),
[new DispatchAfterCurrentBusStamp()]
)->willReturn(new Envelope(new \stdClass()));
$this(new VerifyCustomerAccount('ToKeN'));
}