2024-07-21 16:55:39 +02:00
< ? php
namespace App\MessageHandler ;
2024-08-06 03:38:00 +02:00
use App\Config\Connector\GandiConnector ;
2024-07-29 15:28:05 +02:00
use App\Config\Connector\OvhConnector ;
use App\Config\ConnectorProvider ;
2024-07-21 16:55:39 +02:00
use App\Config\TriggerAction ;
2024-07-29 16:54:31 +02:00
use App\Entity\Connector ;
2024-07-21 16:55:39 +02:00
use App\Entity\Domain ;
use App\Entity\DomainEvent ;
use App\Entity\User ;
use App\Entity\WatchList ;
use App\Entity\WatchListTrigger ;
use App\Message\ProcessDomainTrigger ;
use App\Repository\DomainRepository ;
use App\Repository\WatchListRepository ;
2024-08-04 14:45:27 +02:00
use Psr\Log\LoggerInterface ;
2024-07-21 16:55:39 +02:00
use Symfony\Bridge\Twig\Mime\TemplatedEmail ;
2024-07-29 15:28:05 +02:00
use Symfony\Component\HttpKernel\KernelInterface ;
2024-07-21 16:55:39 +02:00
use Symfony\Component\Mailer\Exception\TransportExceptionInterface ;
use Symfony\Component\Mailer\MailerInterface ;
use Symfony\Component\Messenger\Attribute\AsMessageHandler ;
2024-08-05 01:30:27 +02:00
use Symfony\Component\Mime\Address ;
2024-07-21 16:55:39 +02:00
use Symfony\Component\Mime\Email ;
2024-08-06 03:38:00 +02:00
use Symfony\Contracts\HttpClient\HttpClientInterface ;
2024-07-21 16:55:39 +02:00
#[AsMessageHandler]
final readonly class ProcessDomainTriggerHandler
{
public function __construct (
2024-08-02 23:24:52 +02:00
private string $mailerSenderEmail ,
2024-08-05 01:30:27 +02:00
private string $mailerSenderName ,
2024-08-02 23:24:52 +02:00
private MailerInterface $mailer ,
2024-07-21 16:55:39 +02:00
private WatchListRepository $watchListRepository ,
2024-08-02 23:24:52 +02:00
private DomainRepository $domainRepository ,
2024-08-04 14:45:27 +02:00
private KernelInterface $kernel ,
2024-08-06 03:38:00 +02:00
private LoggerInterface $logger ,
private HttpClientInterface $client
2024-08-02 23:24:52 +02:00
) {
2024-07-21 16:55:39 +02:00
}
/**
* @ throws TransportExceptionInterface
2024-08-02 23:24:52 +02:00
* @ throws \Exception
2024-07-21 16:55:39 +02:00
*/
public function __invoke ( ProcessDomainTrigger $message ) : void
{
/** @var WatchList $watchList */
2024-08-02 23:24:52 +02:00
$watchList = $this -> watchListRepository -> findOneBy ([ 'token' => $message -> watchListToken ]);
2024-07-21 16:55:39 +02:00
/** @var Domain $domain */
2024-08-02 23:24:52 +02:00
$domain = $this -> domainRepository -> findOneBy ([ 'ldhName' => $message -> ldhName ]);
2024-07-21 16:55:39 +02:00
2024-07-30 21:34:48 +02:00
$connector = $watchList -> getConnector ();
if ( null !== $connector && $domain -> getDeleted ()) {
2024-08-04 14:45:27 +02:00
$this -> logger -> notice ( 'Watchlist {watchlist} is linked to connector {connector}. A purchase attempt will be made for domain name {ldhName} with provider {provider}.' , [
'watchlist' => $message -> watchListToken ,
'connector' => $connector -> getId (),
'ldhName' => $message -> ldhName ,
'provider' => $connector -> getProvider () -> value ,
]);
2024-07-30 21:34:48 +02:00
try {
2024-08-06 03:38:00 +02:00
$isDebug = $this -> kernel -> isDebug ();
2024-08-02 23:24:52 +02:00
if ( ConnectorProvider :: OVH === $connector -> getProvider ()) {
2024-08-06 11:58:41 +02:00
$provider = new OvhConnector ( $connector -> getAuthData ());
2024-08-06 03:38:00 +02:00
} elseif ( ConnectorProvider :: GANDI === $connector -> getProvider ()) {
2024-08-06 11:58:41 +02:00
$provider = new GandiConnector ( $connector -> getAuthData (), $this -> client );
2024-08-02 23:24:52 +02:00
} else {
throw new \Exception ( 'Unknown provider' );
}
2024-08-06 03:38:00 +02:00
2024-08-06 11:58:41 +02:00
$provider -> orderDomain ( $domain , $isDebug );
2024-08-06 03:38:00 +02:00
$this -> sendEmailDomainOrdered ( $domain , $connector , $watchList -> getUser ());
2024-08-02 23:24:52 +02:00
} catch ( \Throwable ) {
2024-08-04 14:45:27 +02:00
$this -> logger -> warning ( 'Unable to complete purchase. An error message is sent to user {username}.' , [
'username' => $watchList -> getUser () -> getUserIdentifier (),
]);
2024-07-30 21:34:48 +02:00
$this -> sendEmailDomainOrderError ( $domain , $watchList -> getUser ());
2024-07-29 16:10:34 +02:00
}
2024-07-30 21:34:48 +02:00
}
/** @var DomainEvent $event */
2024-08-03 16:14:46 +02:00
foreach ( $domain -> getEvents () -> filter ( fn ( $event ) => $message -> updatedAt < $event -> getDate () && $event -> getDate () < new \DateTime ()) as $event ) {
2024-07-30 21:34:48 +02:00
$watchListTriggers = $watchList -> getWatchListTriggers ()
2024-08-02 23:24:52 +02:00
-> filter ( fn ( $trigger ) => $trigger -> getEvent () === $event -> getAction ());
2024-07-29 16:10:34 +02:00
2024-07-30 21:34:48 +02:00
/** @var WatchListTrigger $watchListTrigger */
foreach ( $watchListTriggers -> getIterator () as $watchListTrigger ) {
2024-08-04 14:45:27 +02:00
$this -> logger -> info ( 'Action {event} has been detected on the domain name {ldhName}. A notification is sent to user {username}.' , [
'event' => $event -> getAction (),
'ldhName' => $message -> ldhName ,
'username' => $watchList -> getUser () -> getUserIdentifier (),
]);
2024-08-02 23:24:52 +02:00
if ( TriggerAction :: SendEmail == $watchListTrigger -> getAction ()) {
2024-07-29 16:10:34 +02:00
$this -> sendEmailDomainUpdated ( $event , $watchList -> getUser ());
2024-07-21 16:55:39 +02:00
}
}
}
}
2024-07-29 16:54:31 +02:00
/**
* @ throws TransportExceptionInterface
*/
private function sendEmailDomainOrdered ( Domain $domain , Connector $connector , User $user ) : void
{
$email = ( new TemplatedEmail ())
2024-08-05 01:30:27 +02:00
-> from ( new Address ( $this -> mailerSenderEmail , $this -> mailerSenderName ))
2024-07-29 16:54:31 +02:00
-> to ( $user -> getEmail ())
-> priority ( Email :: PRIORITY_HIGHEST )
-> subject ( 'A domain name has been ordered' )
-> htmlTemplate ( 'emails/success/domain_ordered.html.twig' )
-> locale ( 'en' )
-> context ([
2024-08-02 23:24:52 +02:00
'domain' => $domain ,
'provider' => $connector -> getProvider () -> value ,
2024-07-29 16:54:31 +02:00
]);
$this -> mailer -> send ( $email );
}
2024-07-21 16:55:39 +02:00
2024-07-29 20:29:12 +02:00
/**
* @ throws TransportExceptionInterface
*/
private function sendEmailDomainOrderError ( Domain $domain , User $user ) : void
{
$email = ( new TemplatedEmail ())
2024-08-05 01:30:27 +02:00
-> from ( new Address ( $this -> mailerSenderEmail , $this -> mailerSenderName ))
2024-07-29 20:29:12 +02:00
-> to ( $user -> getEmail ())
-> subject ( 'An error occurred while ordering a domain name' )
-> htmlTemplate ( 'emails/errors/domain_order.html.twig' )
-> locale ( 'en' )
-> context ([
2024-08-02 23:24:52 +02:00
'domain' => $domain ,
2024-07-29 20:29:12 +02:00
]);
$this -> mailer -> send ( $email );
}
2024-07-21 16:55:39 +02:00
/**
* @ throws TransportExceptionInterface
*/
private function sendEmailDomainUpdated ( DomainEvent $domainEvent , User $user ) : void
{
$email = ( new TemplatedEmail ())
2024-08-05 01:30:27 +02:00
-> from ( new Address ( $this -> mailerSenderEmail , $this -> mailerSenderName ))
2024-07-21 16:55:39 +02:00
-> to ( $user -> getEmail ())
-> priority ( Email :: PRIORITY_HIGHEST )
-> subject ( 'A domain name has been changed' )
2024-07-29 16:54:31 +02:00
-> htmlTemplate ( 'emails/success/domain_updated.html.twig' )
2024-07-21 16:55:39 +02:00
-> locale ( 'en' )
-> context ([
2024-08-02 23:24:52 +02:00
'event' => $domainEvent ,
2024-07-21 16:55:39 +02:00
]);
$this -> mailer -> send ( $email );
}
}