Prechádzať zdrojové kódy

review the system mails management

Olivier Massot 1 rok pred
rodič
commit
4bf232d941

+ 49 - 48
config/opentalent/products.yaml

@@ -273,51 +273,52 @@ parameters:
           - DolibarrAccount
 
   opentalent.products:
-      artist:
-        modules:
-          - Core
-          - Users
-          - Events
-          - GeneralConfig
-          - Equipments
-          - Medals
-          - Donors
-          - Commissons
-          - Website
-          - ViewAudit
-          - Messages
-          - Tagg
-          - Statistic
-          - Dolibarr
-
-      artist_premium:
-        extend: artist
-        modules:
-          - MessagesAdvanced
-          - TaggAdvanced
-
-      school:
-        extend: artist_premium
-        modules:
-          - PedagogicsAdministation
-          - PedagogicsSeizure
-          - Courses
-          - Examens
-          - EducationalProjects
-          - Attendances
-          - UsersSchool
-          - BillingAdministration
-          - TemplateMessages
-
-      school_premium:
-        extend: school
-        modules: ~
-
-      manager:
-        extend: artist-premium
-        modules: ~
-
-      manager_premium:
-        extend: manager
-        modules:
-          - CorePremium
+    artist:
+      modules:
+        - Core
+        - Users
+        - Events
+        - GeneralConfig
+        - Equipments
+        - Medals
+        - Donors
+        - Commissons
+        - Website
+        - ViewAudit
+        - Messages
+        - Tagg
+        - Statistic
+        - Dolibarr
+
+    artist-premium:
+      extend: artist
+      modules:
+        - MessagesAdvanced
+        - TaggAdvanced
+
+    school:
+      extend: artist-premium
+      modules:
+        - PedagogicsAdministation
+        - PedagogicsSeizure
+        - Courses
+        - Examens
+        - EducationalProjects
+        - Attendances
+        - UsersSchool
+        - BillingAdministration
+        - TemplateMessages
+
+    school-premium:
+      extend: school
+      modules: ~
+
+    manager:
+      extend: artist-premium
+      modules: ~
+
+    manager-premium:
+      extend: manager
+      modules:
+        - CorePremium
+

+ 1 - 0
config/services.yaml

@@ -21,6 +21,7 @@ services:
             $persistProcessor: '@api_platform.doctrine.orm.state.persist_processor'
             $removeProcessor: '@api_platform.doctrine.orm.state.remove_processor'
             $opentalentNoReplyEmailAddress: 'noreply@opentalent.fr'
+            $opentalentMailReportEmailAddress: 'mail.report@opentalent.fr'
             $legacyBaseUrl: '%env(PUBLIC_API_LEG_BASE_URL)%'
             $baseUrl: '%env(PUBLIC_API_BASE_URL)%'
 

+ 45 - 78
doc/mailer.md

@@ -1,68 +1,69 @@
-# Mailer
+# Mailer : Gestion des emails système
 
-## Principes générales et fonctionnement actuel
+## Principe général et fonctionnement actuel
 
-### Modèle de base (AbstractMailerModel)
+### Les modèles
 
-    Ce modèle sert de classe de base pour tous les modèles d'emails spécifiques.
-    Champs inclus:
-    senderId: l'identifiant de l'expéditeur de l'email.
-    notify: un booléen pour déterminer si une notification doit être envoyée suite à l'email.
+Un modèle toutes les données nécessaires pour construire un certain type d'email (destinataire, sujet de l'email, contenu, etc.)
 
-    Ils contiennent toutes les données nécessaires pour construire un email (destinataire, le sujet de l'email, le contenu)
-    
-    Par exemple, SubdomainChangeModel contient des informations 
-    spécifiques nécessaires pour informer un utilisateur d'un changement de sous-domaine
-    facilitant le stockage des données  mais aussi la standardisation de l'envoi d'emails avec une same interface pour les builders.
+Par exemple, SubdomainChangeModel contient des informations spécifiques nécessaires pour informer un utilisateur 
+d'un changement de sous-domaine facilitant le stockage des données, mais aussi la standardisation de l'envoi d'emails 
+avec une même interface pour les builders.
 
-### Modèle spécifique (SubdomainChangeModel)
+> @dir src/Service/Mailer/Model
 
-    Ce modèle étend AbstractMailerModel et ajoute des champs spécifiques au contexte d'un changement de sous-domaine.
-    Champs en plus:
-    organizationId: identifiant de l'organisation concernée.
-    subdomainId: identifiant du sous-domaine modifié.
-    url: URL associée au sous-domaine après modification.
+### Les Builders
 
-### Builders
+Les Builders sont des composants qui prennent les modèles préparés (comme SubdomainChangeModel) et les transforment 
+en objets Email. 
 
-    Les Builders sont des composants qui prennent les modèles préparés (comme SubdomainChangeModel) et les transforment en objets Email. 
-    Ils utilisent des services de rendu comme Twig pour générer le contenu de l'email basé sur des templates dynamiques, et configurent les objets Email en y ajoutant les destinataires, les sujets, et autres données nécessaires. 
-    Ces objets sont ensuite prêts à être envoyés par le service de messagerie
+Ils utilisent des services de rendu comme Twig pour générer le contenu de l'email basé sur des templates dynamiques, 
+et configurent les objets Email en y ajoutant les destinataires, les sujets, et autres données nécessaires. 
 
-### Builder spécifique (OnSubdomainChangeMailBuilder)
+Ces objets Email sont ensuite prêts à être envoyés par le service de messagerie.
 
-    Ce builder est spécialement conçu pour construire un email au changement de sous domaine. 
-    Il est appelé après que les modifications dans la gestion des sous-domaines soient effectuées par le service de gestion des sous-domaines (SubdomainService). Voici son processus de fonctionnement :
+> @dir src/Service/Mailer/Builder
 
-    - Support de modèle : détermine si le modèle de données (MailerModelInterface) passé correspond à une instance de SubdomainChangeModel.
-    - Construction de l'email : il les informations nécessaires de la base de données avec l'em (sous-domaine, organisation, auteur de la modification) et prépare le contenu de l'email basé sur un template. 
-    - Il définit l'expéditeur (adresse email par défaut pour les emails système) et ajoute le destinataire principal (admin de l'organisation).
-    - Rendu de l'email : Utilise des templates pour générer le contenu de l'email basé sur les informations fournies.
+### Les templates
 
-### Handlers
+Les templates twig servent de base pour la création du contenu des emails.
 
-    Chaque fois que l'action d'envoi de mail est déclenché (via MailerCommand), le handlers est appelé et orchestre le processus d'envioe des emails à l'aide des builders
-    Le handler extrait le modèle d'email (MailerModel) de la commande. Ce modèle contient des détails tels que le type d'email (système ou non), l'identifiant de l'expéditeur, et d'autres informations spécifiques nécessaires pour l'email.
-    Le handler appelle ensuite un builder approprié. Les builders sont des composants spécialisés chargés de construire l'objet email à partir des données fournies par le modèle
-    Par exemple, si l'email concerne un changement de sous-domaine, un SubdomainChangeMailBuilder serait utilisé pour construire l'email en utilisant des templates et des données spécifiques à ce contexte.
+> @dir templates/emails
 
-### Le cas SubdomainService - Service de Gestion des Sous-domaines (SubdomainService)
+### Le service Mailer
 
-    Ce service orchestre la logistique de création, modification et activation de sous-domaines pour les organisations, et utilise le système de messagerie pour notifier les changements importants :
-    Validation et enregistrement des noms de sous-domaines
-    Activation et mise à jour : Gère l'activation des sous-domaines et la synchronisation avec les systèmes externes avec typo3
-    Notification par email : Après un changement significatif comme l'activation d'un nouveau sous-domaine, le service construit le modèle de données pour l'email (en utilisant getMailModel) et envoie une commande (MailerCommand) au système de messagerie pour notifier l'organisation concernée.
+Le service Mailer assure les envois d'emails de la manière la plus agnostique possible.
 
-    Après la construction du modèle de l'email par SubdomainService, une MailerCommand est créée et envoyée au système de messagerie de Symfony. Cette commande est traitée par MailerHandler, qui utilise le service Mailer pour envoyer l'email préparé par le builder OnSubdomainChangeMailBuilder.
+Sa fonction `main` attend un Model en entrée (voir plus haut). A partir de ce modèle, elle : 
 
-    Validation et enregistrement : Il valide les noms de sous-domaines proposés contre des critères spécifiques (validation regex, vérification des sous-domaines réservés) et gère l'enregistrement de nouveaux sous-domaines dans la base de données.
-    Activation et mise à jour : Gère l'activation des sous-domaines et la synchronisation avec les systèmes externes (par exemple, mise à jour d'un site Typo3).
-    Notification par email : Après un changement significatif comme l'activation d'un nouveau sous-domaine, le service construit le modèle de données pour l'email (en utilisant getMailModel) et envoie une commande (MailerCommand) au système de messagerie pour notifier l'organisation concernée.
+- génère le ou les mails correspondants
+- les envoie
+- les enregistre en base de données
+- envoie le rapport d'envoi
+
+> @see src/Service/Mailer/Mailer.php
+
+
+### L'entité Email (Message)
+
+Une ligne est ajoutée à la table Message pour chaque email ou série d'emails envoyés. Les emails systèmes sont 
+identifiés par l'attribut `isSystem`.
+
+> @see src/Entity/Message/Mail.php
+
+### Messenger
+
+Les envois d'email sont gérés par [Messenger](https://symfony.com/doc/current/components/messenger.html).
+
+> @see src/Message/Command/MailerCommand.php et src/Message/Handler/MailerHandler.php
 
 ## Flux général
 
+Exemple d'un email de notification de changement de sous-domaine : 
+
+
     +-----------------------------+                +-------------------------------+
-    | Action: Changement de      |                | Crée                          |
+    | Action: Changement de      |                | Crée un message               |
     | sous-domaine               +--------------->+ MailerCommand avec            |
     | (par utilisateur ou script)|                | SubdomainChangeModel          |
     +-----------------------------+                +---------------+---------------+
@@ -106,37 +107,3 @@
                                                    | requis par getNotify())        |
                                                    +--------------------------------+
 
-### Déclenchement de l'action : Tout commence généralement par un événement dans votre application qui nécessite l'envoi d'un email. Cela pourrait être une action utilisateur, un événement programmé, etc
-
-    Commande d'envoi d'email : Un objet MailerCommand est créé et transmis au système de messagerie de Symfony. Cette commande contient les détails nécessaires pour construire et envoyer l'email, y compris l'identité du destinataire, le contenu de l'email, et d'autres métadonnées pertinentes.
-
-### Traitement de la commande par MailerHandler
-
-    L'objet MailerHandler est invoqué par le système de messagerie de Symfony en réponse à la réception d'un MailerCommand.
-    MailerHandler extrait le modèle d'email du MailerCommand et vérifie si l'email est un email système à travers isSystemEmail().
-    Il appelle ensuite la méthode main de la classe Mailer pour effectuer l'envoi de l'email.
-
-### Construction et envoi de l'email par Mailer
-
-    La méthode main de Mailer délègue la création de l'objet email spécifique de Symfony à createSymfonyEmail. Cette fonction utilise les informations fournies pour configurer les headers de l'email, définir l'expéditeur, etc.
-    Si l'email est un email système, une adresse générique est utilisée. Sinon, les informations spécifiques de l'email sont utilisées pour configurer l'adresse de réponse et d'autres paramètres.
-    Après la création de l'email, Mailer gère l'envoi de cet email via SymfonyMailer et effectue toutes les opérations de suivi nécessaires, comme la mise à jour des statuts et l'envoi de rapports.
-
-### Notification post-envoi (si applicable)
-
-    Après l'envoi de l'email, si le modèle indique qu'une notification doit être envoyée (via getNotify()), MailerHandler utilise le service Notifier pour notifier l'utilisateur ou le système concerné du succès ou de l'échec de l'envoi.
-
-    MailerHandler agit comme un coordinateur qui répond aux événements et commandes d'envoi d'email, tandis que Mailer est celui qui construit et envoie les emails, assurant que chaque aspect de l'email est correctement configuré et envoyé.
-
-## Problématiques
-
-    Dépendance à senderId: Nécessité de spécifier un expéditeur pour chaque email, même pour les emails systèmes où un expéditeur par défaut serait plus approprié.
-    Redondance de isSystemEmail: Stockage de l'information concernant la nature système de l'email dans chaque modèle d'email, ce qui pourrait être géré plus efficacement.
-    Problematique de l'abstract message : https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/Entity/Message/Email.php?ref_type=heads#L37 - https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/Service/Mailer/Builder/AbstractBuilder.php?ref_type=heads#L44
-
-- entité à modifier
-- le builder attribue un auteur que s'il y en a un
-- condition ternaire : isSenderId ? on retrouve l'email : email systeme  :  sinon on renvoie une erreur
-- AbstractBuilder a modifer
-
-/!\ le mailer doit etre totalement agnostique ; il faut trouver le bon endroit pour gérer l'origine du mail

+ 1 - 0
src/Enum/Organization/SettingsProductEnum.php

@@ -20,4 +20,5 @@ enum SettingsProductEnum: string
     case MANAGER = 'manager';
     case MANAGER_PREMIUM = 'manager-premium';
     case EMPTY = '';
+
 }

+ 10 - 7
src/Message/Handler/MailerHandler.php

@@ -9,31 +9,34 @@ use App\Message\Command\MailerCommand;
 use App\Repository\Access\AccessRepository;
 use App\Service\Mailer\Mailer;
 use App\Service\Notifier;
+use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
 use Symfony\Component\Messenger\Attribute\AsMessageHandler;
 
 #[AsMessageHandler(priority: 1)]
 class MailerHandler
 {
     public function __construct(
-        private Mailer $mailer,
-        private Notifier $notifier,
-        private AccessRepository $accessRepository
+        private readonly Mailer $mailer,
+        private readonly Notifier $notifier,
+        private readonly AccessRepository $accessRepository
     ) {
     }
 
+    /**
+     * @throws TransportExceptionInterface
+     */
     public function __invoke(MailerCommand $mailerCommand): void
     {
         $mailerModel = $mailerCommand->getMailerModel();
-        $isSystemEmail = $mailerModel->isSystemEmail();
 
-        $emails = $this->mailer->main($mailerModel, $isSystemEmail);
+        $emails = $this->mailer->main($mailerModel);
 
         if ($mailerModel->getNotify()) {
-            /** @var Email */
+            /** @var Email $email */
             $email = $emails->first()->getEmailEntity();
 
             $this->notifier->notifyMessage(
-                $this->accessRepository->find($mailerCommand->getMailerModel()->getSenderId()),
+                $this->accessRepository->find($mailerCommand->getMailerModel()->getAuthorId()),
                 ['about' => $email->getAbout()]
             );
         }

+ 1 - 2
src/Service/Mailer/Builder/AbstractBuilder.php

@@ -41,11 +41,10 @@ class AbstractBuilder implements AbstractBuilderInterface
     /**
      * @see AbstractBuilderTest::testBuildEmailEntity()
      */
-    public function buildEmailEntity(string $subject, Access $author, string $content): EmailEntity
+    public function buildEmailEntity(string $subject, string $content): EmailEntity
     {
         $emailEntity = new EmailEntity();
         $emailEntity
-            ->setAuthor($author)
             ->setIsSystem(true)
             ->setAbout($subject)
             ->setDateSent(new \DateTime('now'))

+ 1 - 1
src/Service/Mailer/Builder/AbstractBuilderInterface.php

@@ -18,7 +18,7 @@ interface AbstractBuilderInterface
      */
     public function render(string $template, array $context): string;
 
-    public function buildEmailEntity(string $subject, Access $author, string $content): EmailEntity;
+    public function buildEmailEntity(string $subject, string $content): EmailEntity;
 
     public function addRecipient(Email $email, Access|Organization|string $target, EmailSendingTypeEnum $sendType, ?ContactPointTypeEnum $contactPointType = null): void;
 }

+ 5 - 6
src/Service/Mailer/Builder/OnSubdomainChangeMailBuilder.php

@@ -4,7 +4,6 @@ declare(strict_types=1);
 
 namespace App\Service\Mailer\Builder;
 
-use App\Entity\Access\Access;
 use App\Entity\Organization\Organization;
 use App\Entity\Organization\Subdomain;
 use App\Enum\Core\ContactPointTypeEnum;
@@ -13,7 +12,6 @@ use App\Service\Access\Utils as AccessUtils;
 use App\Service\Mailer\Email;
 use App\Service\Mailer\Model\MailerModelInterface;
 use App\Service\Mailer\Model\SubdomainChangeModel;
-use App\Tests\Service\Mailer\Builder\OnSubdomainChangeMailBuilderTest;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\ORM\EntityManagerInterface;
 
@@ -43,7 +41,6 @@ class OnSubdomainChangeMailBuilder extends AbstractBuilder implements BuilderInt
     {
         $subdomain = $this->entityManager->getRepository(Subdomain::class)->find($mailerModel->getSubdomainId());
         $organization = $this->entityManager->getRepository(Organization::class)->find($mailerModel->getOrganizationId());
-        $author = $this->entityManager->getRepository(Access::class)->find($mailerModel->getSenderId());
         $admin = $this->accessUtils->findAdminFor($organization);
 
         $context = [
@@ -55,11 +52,13 @@ class OnSubdomainChangeMailBuilder extends AbstractBuilder implements BuilderInt
         $content = $this->render('subdomain', $context);
 
         $email = (new Email())
-            ->setEmailEntity($this->buildEmailEntity('Nouveau sous domaine: '.$subdomain->getSubdomain(), $author, $content))
+            ->setEmailEntity(
+                $this->buildEmailEntity('Nouveau sous domaine: '.$subdomain->getSubdomain(), $content)
+            )
             ->setContent($content)
             ->setFrom($this->opentalentNoReplyEmailAddress)
-            ->setFromName($organization->getName())
-        ;
+            ->setFromName($organization->getName());
+
         $this->addRecipient($email, $admin, EmailSendingTypeEnum::TO, ContactPointTypeEnum::PRINCIPAL);
 
         return new ArrayCollection([$email]);

+ 1 - 1
src/Service/Mailer/Email.php

@@ -8,7 +8,7 @@ use App\Entity\Message\Email as EmailEntity;
 use Doctrine\Common\Collections\ArrayCollection;
 
 /**
- * Classe Email qui contient les informations nécessaire pour assurer l'envoie d'un mail.
+ * Classe Email qui contient les informations nécessaires pour assurer l'envoi d'un mail.
  */
 class Email
 {

+ 23 - 13
src/Service/Mailer/Mailer.php

@@ -25,19 +25,21 @@ use Symfony\Component\Mime\Email as SymfonyEmail;
 
 /**
  * Classe Mailer : Service assurant l'envoi d'un mail à un destinataire.
+ *
+ * @see doc/mailer.md
  */
 class Mailer
 {
     public function __construct(
         private readonly MailerInterface $symfonyMailer,
         private readonly string $opentalentNoReplyEmailAddress,
+        private readonly string $opentalentMailReportEmailAddress,
         private readonly BuilderIterator $builderIterator,
         private readonly StringsUtils $stringsUtils,
         private readonly EntityManagerInterface $entityManager,
         private readonly Environnement $environnement,
-        private readonly LoggerInterface $logger
-    ) {
-    }
+        private readonly LoggerInterface $logger,
+    ) {}
 
     /**
      * Main fonction qui itère les différentes étapes nécessaires à l'envoi d'un email
@@ -75,7 +77,9 @@ class Mailer
         }
 
         // Envoi du rapport
-        $this->sendReport($emailsCollection);
+        if ($mailerModel->getSendReport()) {
+            $this->sendReport($emailsCollection);
+        }
 
         $this->entityManager->flush();
 
@@ -91,7 +95,7 @@ class Mailer
      */
     public function send(Email $email): void
     {
-        // On créé le mail
+        // On crée le mail
         $symfonyMail = $this->createSymfonyEmail($email);
 
         $this->addRecipients($symfonyMail, $email);
@@ -141,18 +145,24 @@ class Mailer
      *
      * @see MailerTest::testCreateSymfonyEmail()
      */
-    public function createSymfonyEmail(Email $email, bool $isSystemEmail = false): SymfonyEmail {
-    
-        $addressMailFrom = $isSystemEmail ? new Address('ne-pas-repondre@opentalent.com', 'Opentalent') :
-                                            new Address($email->getFrom(), $email->getFromName());
+    public function createSymfonyEmail(Email $email): SymfonyEmail
+    {
+        $isSystem = $email->getEmailEntity()->getIsSystem();
+
+        if ($isSystem) {
+            $addressMailFrom = new Address($this->opentalentNoReplyEmailAddress, 'Opentalent');
+        } else {
+            $addressMailFrom = new Address($email->getFrom(), $email->getFromName());
+        }
 
         $symfonyEmail = (new SymfonyEmail())
             ->from($addressMailFrom)
             ->subject($email->getEmailEntity()->getAbout());
 
-        if (!$isSystemEmail) {
-            $symfonyEmail->replyTo($addressMailFrom)
-                        ->returnPath(Address::create('mail.report@opentalent.fr'));
+        if (!$email->getEmailEntity()->getIsSystem()) {
+            $symfonyEmail
+                ->replyTo($addressMailFrom)
+                ->returnPath(Address::create($this->opentalentMailReportEmailAddress));
         }
 
         return $symfonyEmail;
@@ -285,7 +295,7 @@ class Mailer
      */
     public function addHeaders(SymfonyEmail $symfonyMail, Email $email): void
     {
-        $symfonyMail->getHeaders()->addTextHeader('List-Unsubscribe', 'mailto:' . $email->getFrom() . '?subject=désabonnement');
+        $symfonyMail->getHeaders()->addTextHeader('List-Unsubscribe', 'mailto:'.$email->getFrom().'?subject=désabonnement');
         $symfonyMail->getHeaders()->addTextHeader('X-ID-OT', $email->getEmailEntity()->getUuid()->toString());
     }
 

+ 11 - 12
src/Service/Mailer/Model/AbstractMailerModel.php

@@ -6,20 +6,20 @@ namespace App\Service\Mailer\Model;
 
 abstract class AbstractMailerModel
 {
-    protected int $senderId;
+    protected int $authorId;
     protected bool $notify = true;
-    private bool $isSystemEmail = false;
+    protected bool $sendReport = false;
 
-    public function setSenderId(int $accessId): self
+    public function setAuthorId(int $accessId): self
     {
-        $this->senderId = $accessId;
+        $this->authorId = $accessId;
 
         return $this;
     }
 
-    public function getSenderId(): int
+    public function getAuthorId(): int
     {
-        return $this->senderId;
+        return $this->authorId;
     }
 
     public function setNotify(bool $notify): self
@@ -34,15 +34,14 @@ abstract class AbstractMailerModel
         return $this->notify;
     }
 
-        public function setIsSystemEmail(bool $isSystemEmail): self
+    public function getSendReport(): bool
     {
-        $this->isSystemEmail = $isSystemEmail;
-
-        return $this;
+        return $this->sendReport;
     }
 
-    public function isSystemEmail(): bool
+    public function setSendReport(bool $sendReport): self
     {
-        return $this->isSystemEmail;
+        $this->sendReport = $sendReport;
+        return $this;
     }
 }

+ 6 - 5
src/Service/Mailer/Model/MailerModelInterface.php

@@ -6,14 +6,15 @@ namespace App\Service\Mailer\Model;
 
 interface MailerModelInterface
 {
-    public function setSenderId(int $accessId): AbstractMailerModel;
+    public function setAuthorId(int $accessId): AbstractMailerModel;
 
-    public function getSenderId(): int;
+    public function getAuthorId(): int;
 
     public function setNotify(bool $notify): AbstractMailerModel;
 
     public function getNotify(): bool;
 
-    public function setIsSystemEmail(bool $isSystemEmail): self;
-    
-    public function isSystemEmail(): bool;}
+    public function setSendReport(bool $sendReport): AbstractMailerModel;
+
+    public function getSendReport(): bool;
+}

+ 0 - 2
src/Service/Mailer/Model/SubdomainChangeModel.php

@@ -52,6 +52,4 @@ class SubdomainChangeModel extends AbstractMailerModel implements MailerModelInt
     {
         return $this->url;
     }
-
-
 }

+ 8 - 5
src/Service/Security/Module.php

@@ -128,21 +128,24 @@ class Module
      */
     public function getModulesByProductConfiguration(SettingsProductEnum $product): ?array
     {
-        $product = str_replace('-', '_', $product->value);
         $opentalentProducts = $this->parameterBag->get('opentalent.products');
 
-        if (!array_key_exists($product, $opentalentProducts)) {
-            throw new AccessDeniedHttpException(sprintf('The product %s does not exist !', $product));
+        if (!array_key_exists($product->value, $opentalentProducts)) {
+            throw new AccessDeniedHttpException(sprintf('The product %s does not exist !', $product->value));
         }
-        $productConfig = $opentalentProducts[$product];
+        $productConfig = $opentalentProducts[$product->value];
         $modules = $productConfig['modules'] ?? [];
 
         if (array_key_exists('extend', $productConfig)) {
-            $modules = array_merge($modules, $this->getModulesByProductConfiguration(SettingsProductEnum::from($productConfig['extend'])));
+            $modules = array_merge(
+                $modules,
+                $this->getModulesByProductConfiguration(SettingsProductEnum::from($productConfig['extend']))
+            );
             unset($productConfig['extend']);
         }
 
         return $modules;
+
     }
 
     /**

+ 11 - 23
src/Service/Typo3/SubdomainService.php

@@ -214,29 +214,17 @@ class SubdomainService
     /**
      * Build the data model for the confirmation email.
      */
-    // protected function getMailModel(Subdomain $subdomain): SubdomainChangeModel
-    // {
-    //     $adminAccess = $this->accessRepository->findAdminAccess($subdomain->getOrganization());
-
-    //     /* @phpstan-ignore-next-line */
-    //     return (new SubdomainChangeModel())
-    //         ->setOrganizationId($subdomain->getOrganization()->getId())
-    //         ->setSubdomainId($subdomain->getId())
-    //         ->setUrl($this->organizationUtils->getOrganizationWebsite($subdomain->getOrganization()))
-    //         ->setSenderId($adminAccess->getId());
-    // }
-    protected function getMailModel(Subdomain $subdomain): SubdomainChangeModel
-    {
-        $adminAccess = $this->accessRepository->findAdminAccess($subdomain->getOrganization());
-
-        return (new SubdomainChangeModel())
-            ->setOrganizationId($subdomain->getOrganization()->getId())
-            ->setSubdomainId($subdomain->getId())
-            ->setUrl($this->organizationUtils->getOrganizationWebsite($subdomain->getOrganization()))
-            ->setSenderId($adminAccess->getId())
-            ->setIsSystemEmail(true); 
-    }
-
+     protected function getMailModel(Subdomain $subdomain): SubdomainChangeModel
+     {
+         $adminAccess = $this->accessRepository->findAdminAccess($subdomain->getOrganization());
+
+         /* @phpstan-ignore-next-line */
+         return (new SubdomainChangeModel())
+             ->setAuthorId($adminAccess->getId())
+             ->setOrganizationId($subdomain->getOrganization()->getId())
+             ->setSubdomainId($subdomain->getId())
+             ->setUrl($this->organizationUtils->getOrganizationWebsite($subdomain->getOrganization()));
+     }
 
     /**
      * Send the confirmation email to the organization after a new subdomain has been activated.

+ 3 - 3
tests/Unit/Service/Mailer/Builder/OnSubdomainChangeMailBuilderTest.php

@@ -58,7 +58,7 @@ class OnSubdomainChangeMailBuilderTest extends TestCase
     {
         $subdomainId = 123;
         $organizationId = 444;
-        $senderId = 333;
+        $authorId = 333;
 
         $subDomainChangeBuilder = $this->makeSubDomainChangeBuilderMock('build');
 
@@ -70,14 +70,14 @@ class OnSubdomainChangeMailBuilderTest extends TestCase
         $mailerModel = $this->getMockBuilder(SubdomainChangeModel::class)->disableOriginalConstructor()->getMock();
         $mailerModel->method('getSubdomainId')->willReturn($subdomainId);
         $mailerModel->method('getOrganizationId')->willReturn($organizationId);
-        $mailerModel->method('getSenderId')->willReturn($senderId);
+        $mailerModel->method('getAuthorId')->willReturn($authorId);
 
         $subdomainRepository = $this->getMockBuilder(SubdomainRepository::class)->disableOriginalConstructor()->getMock();
         $subdomainRepository->expects(self::once())->method('find')->with($subdomainId)->willReturn($subdomain);
         $organizationRepository = $this->getMockBuilder(OrganizationRepository::class)->disableOriginalConstructor()->getMock();
         $organizationRepository->expects(self::once())->method('find')->with($organizationId)->willReturn($organization);
         $accessRepository = $this->getMockBuilder(AccessRepository::class)->disableOriginalConstructor()->getMock();
-        $accessRepository->expects(self::once())->method('find')->with($senderId)->willReturn($access);
+        $accessRepository->expects(self::once())->method('find')->with($authorId)->willReturn($access);
 
         $this->entityManager
             ->expects(self::exactly(3))

+ 1 - 1
tests/Unit/Service/Typo3/SubdomainServiceTest.php

@@ -505,7 +505,7 @@ class SubdomainServiceTest extends TestCase
         $mailerModel = $subdomainService->getMailModel($subdomain);
 
         $this->assertInstanceOf(SubdomainChangeModel::class, $mailerModel);
-        $this->assertEquals(1, $mailerModel->getSenderId());
+        $this->assertEquals(1, $mailerModel->getAuthorId());
         $this->assertEquals(1, $mailerModel->getOrganizationId());
         $this->assertEquals(1, $mailerModel->getSubdomainId());
         $this->assertEquals('mysubdomain.opentalent.fr', $mailerModel->getUrl());