Przeglądaj źródła

Datapersisters refactoring, hooks are now in the OnChange classes

Olivier Massot 3 lat temu
rodzic
commit
286b12eb46

+ 15 - 71
src/DataPersister/BaseDataPersister.php

@@ -3,6 +3,9 @@
 namespace App\DataPersister;
 namespace App\DataPersister;
 
 
 use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
 use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
+use App\Service\OnChange\Organization\OnChangeContext;
+use App\Service\OnChange\Organization\OnChangeDefault;
+use App\Service\OnChange\Organization\OnChangeInterface;
 use Doctrine\ORM\EntityManagerInterface;
 use Doctrine\ORM\EntityManagerInterface;
 use Symfony\Contracts\Service\Attribute\Required;
 use Symfony\Contracts\Service\Attribute\Required;
 
 
@@ -12,16 +15,18 @@ use Symfony\Contracts\Service\Attribute\Required;
  */
  */
 class BaseDataPersister implements ContextAwareDataPersisterInterface
 class BaseDataPersister implements ContextAwareDataPersisterInterface
 {
 {
-    protected array $context = [];
-
     // <-- dependencies injections
     // <-- dependencies injections
-    protected EntityManagerInterface $entityManager;
     protected ContextAwareDataPersisterInterface $contextAwareDataPersister;
     protected ContextAwareDataPersisterInterface $contextAwareDataPersister;
+    protected OnChangeInterface $onChange;
 
 
     #[Required]
     #[Required]
     public function setContextAwareDataPersister(ContextAwareDataPersisterInterface $contextAwareDataPersister): void {$this->contextAwareDataPersister = $contextAwareDataPersister;}
     public function setContextAwareDataPersister(ContextAwareDataPersisterInterface $contextAwareDataPersister): void {$this->contextAwareDataPersister = $contextAwareDataPersister;}
-    #[Required]
-    public function setEntityManager(EntityManagerInterface $entityManager): void {$this->entityManager = $entityManager;}
+
+    public function __construct(
+        OnChangeDefault $onChange
+    ) {
+        $this->onChange = $onChange;
+    }
     // dependencies injections -->
     // dependencies injections -->
 
 
     public function supports($data, array $context = []): bool
     public function supports($data, array $context = []): bool
@@ -31,55 +36,21 @@ class BaseDataPersister implements ContextAwareDataPersisterInterface
 
 
     public function persist($data, array $context = [])
     public function persist($data, array $context = [])
     {
     {
-        $this->context = $context;
+        $onChangeContext = new OnChangeContext($context);
 
 
-        $this->validate($data);
+        $this->onChange->validate($data, $onChangeContext);
 
 
-        $data = $this->preProcess($data);
+        $data = $this->onChange->preProcess($data, $onChangeContext);
 
 
-        $this->prePersist($data);
+        $this->onChange->beforeChange($data, $onChangeContext);
 
 
         $result = $this->contextAwareDataPersister->persist($data, $context);
         $result = $this->contextAwareDataPersister->persist($data, $context);
 
 
-        $this->postPersist($data);
+        $this->onChange->onChange($data, $onChangeContext);
 
 
         return $result;
         return $result;
     }
     }
 
 
-    /**
-     * Validation de la nouvelle donnée
-     *
-     * @param $data
-     */
-    protected function validate($data): void {
-    }
-
-    /**
-     * Transformation de la donnée en entrée
-     *
-     * @param $data
-     * @return mixed
-     */
-    protected function preProcess($data) {
-        return $data;
-    }
-
-    /**
-     * Opérations avant mise à jour
-     *
-     * @param $data
-     */
-    protected function prePersist($data): void {
-    }
-
-    /**
-     * Opérations après mise à jour
-     *
-     * @param $data
-     */
-    protected function postPersist($data): void {
-    }
-
     /**
     /**
      * La fonction native 'remove' n'est pas supportée par défaut, la réimplémenter au besoin
      * La fonction native 'remove' n'est pas supportée par défaut, la réimplémenter au besoin
      *
      *
@@ -89,31 +60,4 @@ class BaseDataPersister implements ContextAwareDataPersisterInterface
     public function remove($data, array $context = []): void {
     public function remove($data, array $context = []): void {
         throw new \RuntimeException('not supported', 500);
         throw new \RuntimeException('not supported', 500);
     }
     }
-
-    /**
-     * La requête traitée est de type POST
-     *
-     * @return bool
-     */
-    protected function isPostRequest(): bool {
-        return $this->context['collection_operation_name'] ?? null === 'post';
-    }
-
-    /**
-     * La requête traitée est de type PUT
-     *
-     * @return bool
-     */
-    protected function isPutRequest(): bool {
-        return $this->context['item_operation_name'] ?? null === 'put';
-    }
-
-    /**
-     * Retourne l'entité existante (avant mise à jour) si elle existe, null sinon
-     *
-     * @return mixed|null
-     */
-    protected function previousData() {
-        return $this->context['previous_data'] ?? null;
-    }
 }
 }

+ 4 - 62
src/DataPersister/Organization/SubdomainDataPersister.php

@@ -5,12 +5,7 @@ namespace App\DataPersister\Organization;
 
 
 use App\DataPersister\BaseDataPersister;
 use App\DataPersister\BaseDataPersister;
 use App\Entity\Organization\Subdomain;
 use App\Entity\Organization\Subdomain;
-use App\Message\Command\Typo3\Typo3UpdateCommand;
-use App\Service\MailHub;
 use App\Service\OnChange\Organization\OnSubdomainChange;
 use App\Service\OnChange\Organization\OnSubdomainChange;
-use App\Service\Organization\Utils;
-use App\Service\Typo3\BindFileService;
-use Symfony\Component\Messenger\MessageBusInterface;
 
 
 /**
 /**
  * Ccustom dataPersister gérant la resource Subdomain
  * Ccustom dataPersister gérant la resource Subdomain
@@ -18,74 +13,21 @@ use Symfony\Component\Messenger\MessageBusInterface;
 class SubdomainDataPersister extends BaseDataPersister
 class SubdomainDataPersister extends BaseDataPersister
 {
 {
     public function __construct(
     public function __construct(
-        private BindFileService $bindFileService,
-        private MessageBusInterface $messageBus,
-        private OnSubdomainChange $onSubdomainChange
-    ) {}
+        OnSubdomainChange $onChange
+    ) {
+        parent::__construct($onChange);
+    }
 
 
     public function supports($data, array $context = []): bool
     public function supports($data, array $context = []): bool
     {
     {
         return $data instanceof Subdomain;
         return $data instanceof Subdomain;
     }
     }
 
 
-    protected function validate($subdomain): void {
-        if ($this->isPostRequest()) {
-            // Ensure we do not exceed the limit of 3 subdomains per organization
-            if (count($subdomain->getOrganization()->getSubdomains()) >= 3) {
-                throw new \RuntimeException('This organization has already registered 3 subdomains');
-            }
-        }
-    }
-
     /**
     /**
      * @param Subdomain $subdomain
      * @param Subdomain $subdomain
      */
      */
     protected function postPersist($subdomain): void
     protected function postPersist($subdomain): void
     {
     {
-        $shallPersist = false;
-
-        // Ensure it is the only active subdomain of this organization by disabling other organization subdomains
-        if ($subdomain->isActive()) {
-            foreach ($subdomain->getOrganization()->getSubdomains() as $other) {
-                if ($other !== $subdomain && $other->isActive()) {
-                    $other->setActive(false);
-                    $shallPersist = true;
-                }
-            }
-        }
-
-        // Register into the BindFile
-        if ($this->isPostRequest()) {
-            $this->bindFileService->registerSubdomain($subdomain->getSubdomain());
-        }
-
-        // Update the admin username
-        //if ($this->isPutRequest() && $this->previousData()) {
-        //    if ($subdomain->isActive() && !$this->previousData()->isActive()) {
-        //        $this->onSubdomainChange->updateAdminUsername($subdomain->getOrganization());
-        //        $shallPersist = true;
-        //    }
-        //}
-
-        if ($shallPersist) {
-            $this->entityManager->flush();
-        }
-
-        // Update the typo3 website (asynchronously with messenger)
-        // /!\ This has to be executed after everything has been persisted
-        if ($this->isPutRequest() && $this->previousData()) {
-            if ($subdomain->isActive() && !$this->previousData()->isActive()) {
-                $this->messageBus->dispatch(
-                    new Typo3UpdateCommand($subdomain->getOrganization()->getId())
-                );
-            }
-        }
 
 
-        // Envoi d'un email
-        if ($this->isPutRequest() && $this->previousData()) {
-            if ($subdomain->isActive() && !$this->previousData()->isActive()) {
-                $this->onSubdomainChange->sendEmailAfterSubdomainChange($subdomain);
-            }
-        }
     }
     }
 }
 }

+ 37 - 0
src/Service/OnChange/Organization/OnChangeContext.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Service\OnChange\Organization;
+
+class OnChangeContext
+{
+    public function __construct(
+        private array $context
+    ) {}
+
+    /**
+     * La requête traitée est de type POST
+     *
+     * @return bool
+     */
+    public function isPostRequest(): bool {
+        return $this->context['collection_operation_name'] ?? null === 'post';
+    }
+
+    /**
+     * La requête traitée est de type PUT
+     *
+     * @return bool
+     */
+    public function isPutRequest(): bool {
+        return $this->context['item_operation_name'] ?? null === 'put';
+    }
+
+    /**
+     * Retourne l'entité existante (avant mise à jour) si elle existe, null sinon
+     *
+     * @return mixed|null
+     */
+    public function previousData() {
+        return $this->context['previous_data'] ?? null;
+    }
+}

+ 16 - 0
src/Service/OnChange/Organization/OnChangeDefault.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Service\OnChange\Organization;
+
+class OnChangeDefault implements OnChangeInterface
+{
+    public function validate($data, OnChangeContext $context): void {}
+
+    public function preProcess($data, OnChangeContext $context): mixed {
+        return $data;
+    }
+
+    public function beforeChange($data, OnChangeContext $context): void {}
+
+    public function onChange($data, OnChangeContext $context): void {}
+}

+ 39 - 0
src/Service/OnChange/Organization/OnChangeInterface.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Service\OnChange\Organization;
+
+interface OnChangeInterface
+{
+    /**
+     * Validate the new data, throw a RuntimeException if data is not valid
+     *
+     * @param $data
+     * @param OnChangeContext $context
+     */
+    public function validate($data, OnChangeContext $context): void;
+
+    /**
+     * Apply transformations to the new data before it to be persisted
+     *
+     * @param $data
+     * @param OnChangeContext $context
+     * @return mixed
+     */
+    public function preProcess($data, OnChangeContext $context): mixed;
+
+    /**
+     * Other operations to run before the data to be persisted
+     *
+     * @param $data
+     * @param OnChangeContext $context
+     */
+    public function beforeChange($data, OnChangeContext $context): void;
+
+    /**
+     * Operations to run after the data has been persisted
+     *
+     * @param $data
+     * @param OnChangeContext $context
+     */
+    public function onChange($data, OnChangeContext $context): void;
+}

+ 66 - 1
src/Service/OnChange/Organization/OnSubdomainChange.php

@@ -4,11 +4,15 @@ namespace App\Service\OnChange\Organization;
 
 
 use App\Entity\Organization\Organization;
 use App\Entity\Organization\Organization;
 use App\Entity\Organization\Subdomain;
 use App\Entity\Organization\Subdomain;
+use App\Message\Command\Typo3\Typo3UpdateCommand;
 use App\Service\MailHub;
 use App\Service\MailHub;
+use App\Service\Typo3\BindFileService;
+use Doctrine\ORM\EntityManagerInterface;
 use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
 use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
+use Symfony\Component\Messenger\MessageBusInterface;
 use Symfony\Component\Security\Core\Security;
 use Symfony\Component\Security\Core\Security;
 
 
-class OnSubdomainChange
+class OnSubdomainChange extends OnChangeDefault
 {
 {
     public function __construct(
     public function __construct(
         private \App\Service\Organization\Utils $organizationUtils,
         private \App\Service\Organization\Utils $organizationUtils,
@@ -16,8 +20,69 @@ class OnSubdomainChange
         private MailHub $mailHub,
         private MailHub $mailHub,
         private Security $security,
         private Security $security,
         private JWTTokenManagerInterface $jwtManager,
         private JWTTokenManagerInterface $jwtManager,
+        private BindFileService $bindFileService,
+        private MessageBusInterface $messageBus,
+        private EntityManagerInterface $entityManager
     ) {}
     ) {}
 
 
+    public function validate($subdomain, OnChangeContext $context): void {
+        // Ensure we do not exceed the limit of 3 subdomains per organization
+        if (
+            $context->isPostRequest() &&
+            count($subdomain->getOrganization()->getSubdomains()) >= 3
+        ) {
+            throw new \RuntimeException('This organization has already registered 3 subdomains');
+        }
+    }
+
+    public function onChange($subdomain, OnChangeContext $context): void {
+        $shallPersist = false;
+
+        // Ensure it is the only active subdomain of this organization by disabling other organization subdomains
+        if ($subdomain->isActive()) {
+            foreach ($subdomain->getOrganization()->getSubdomains() as $other) {
+                if ($other !== $subdomain && $other->isActive()) {
+                    $other->setActive(false);
+                    $shallPersist = true;
+                }
+            }
+        }
+
+        // Register into the BindFile
+        if ($context->isPostRequest()) {
+            $this->bindFileService->registerSubdomain($subdomain->getSubdomain());
+        }
+
+        // Update the admin username
+        //if ($this->isPutRequest() && $this->previousData()) {
+        //    if ($subdomain->isActive() && !$this->previousData()->isActive()) {
+        //        $this->onSubdomainChange->updateAdminUsername($subdomain->getOrganization());
+        //        $shallPersist = true;
+        //    }
+        //}
+
+        if ($shallPersist) {
+            $this->entityManager->flush();
+        }
+
+        // Update the typo3 website (asynchronously with messenger)
+        // /!\ This has to be executed after everything has been persisted
+        if ($context->isPutRequest() && $context->previousData()) {
+            if ($subdomain->isActive() && !$context->previousData()->isActive()) {
+                $this->messageBus->dispatch(
+                    new Typo3UpdateCommand($subdomain->getOrganization()->getId())
+                );
+            }
+        }
+
+        // Envoi d'un email
+        if ($context->isPutRequest() && $context->previousData()) {
+            if ($subdomain->isActive() && !$context->previousData()->isActive()) {
+                $this->sendEmailAfterSubdomainChange($subdomain);
+            }
+        }
+    }
+
     /**
     /**
      * Update the admin username to match the pattern 'admin{subdomain}'
      * Update the admin username to match the pattern 'admin{subdomain}'
      *
      *