Prechádzať zdrojové kódy

Serializer par défault et ajout de l'organization par défault

Vincent GUFFON 4 rokov pred
rodič
commit
7d4c7a9031

+ 8 - 0
config/services.yaml

@@ -44,6 +44,14 @@ services:
 
     #########################################
     ##  SERIALIZER Decorates ##
+    App\Serializer\DefaultNormalizer:
+        # By default .inner is passed as argument
+        decorates: 'api_platform.jsonld.normalizer.item'
+
+    app.serializer.normalizer.item.json:
+        class: 'App\Serializer\DefaultNormalizer'
+        decorates: 'api_platform.serializer.normalizer.item'
+
     App\Serializer\AccessContextBuilder:
         decorates: 'api_platform.serializer.context_builder'
         arguments: [ '@App\Serializer\AccessContextBuilder.inner' ]

+ 15 - 0
src/Annotation/OrganizationDefaultValue.php

@@ -0,0 +1,15 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Annotation;
+
+use Attribute;
+
+/**
+ * Classe OrganizationDefaultValue qui gère l'annotation pour mettre l'organization comme valeur par défaut
+ */
+#[Attribute(Attribute::TARGET_CLASS)]
+final class OrganizationDefaultValue
+{
+    public string $fieldName;
+}

+ 2 - 0
src/Entity/Organization/OrganizationAddressPostal.php

@@ -4,6 +4,7 @@ declare(strict_types=1);
 namespace App\Entity\Organization;
 
 use ApiPlatform\Core\Annotation\ApiResource;
+use App\Annotation\OrganizationDefaultValue;
 use App\Entity\Core\AddressPostal;
 use App\Repository\Organization\OrganizationAddressPostalRepository;
 use Doctrine\ORM\Mapping as ORM;
@@ -30,6 +31,7 @@ use Symfony\Component\Serializer\Annotation\Groups;
     ],
 )]
 #[ORM\Entity(repositoryClass: OrganizationAddressPostalRepository::class)]
+#[OrganizationDefaultValue(fieldName: "organization")]
 class OrganizationAddressPostal
 {
     #[ORM\Id]

+ 63 - 0
src/Serializer/ApiNormalizer.php

@@ -0,0 +1,63 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Serializer;
+
+use App\Entity\Access\Access;
+use App\Service\Utils\EntityUtils;
+use Symfony\Component\Security\Core\Security;
+use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+use Symfony\Component\Serializer\SerializerAwareInterface;
+use Symfony\Component\Serializer\SerializerInterface;
+
+/**
+ * Serializer par défaut
+ */
+final class DefaultNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
+{
+    public function __construct(
+        private NormalizerInterface $decorated,
+        private EntityUtils $entityUtils,
+        private Security $security
+    )
+    {
+        if (!$this->decorated instanceof DenormalizerInterface) {
+            throw new \InvalidArgumentException(sprintf('The decorated normalizer must implement the %s.', DenormalizerInterface::class));
+        }
+    }
+
+    public function supportsNormalization($data, $format = null)
+    {
+        return $this->decorated->supportsNormalization($data, $format);
+    }
+
+    public function normalize($object, $format = null, array $context = [])
+    {
+        $data = $this->decorated->normalize($object, $format, $context);
+        return $data;
+    }
+
+    public function supportsDenormalization($data, $type, $format = null)
+    {
+        return $this->decorated->supportsDenormalization($data, $type, $format);
+    }
+
+    public function denormalize($data, $class, $format = null, array $context = [])
+    {
+        $entity = $this->decorated->denormalize($data, $class, $format, $context);
+
+        /** @var Access $access */
+        $access = $this->security->getUser();
+        $this->entityUtils->defaultValueSettersByAccess($entity, $access);
+
+        return $entity;
+    }
+
+    public function setSerializer(SerializerInterface $serializer)
+    {
+        if($this->decorated instanceof SerializerAwareInterface) {
+            $this->decorated->setSerializer($serializer);
+        }
+    }
+}

+ 33 - 0
src/Service/Utils/EntityUtils.php

@@ -0,0 +1,33 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Service\Utils;
+
+use App\Annotation\OrganizationDefaultValue;
+use App\Entity\Access\Access;
+
+/**
+ * Class EntityUtils : Gestion des valeurs par défauts devant être présentes dans les entités.
+ * @package App\Service\Utils
+ */
+class EntityUtils
+{
+    public function defaultValueSettersByAccess($entity, Access $access)
+    {
+        $this->organizationDefaultValue($entity, $access);
+    }
+
+    /**
+     * @param $entity
+     * @throws \ReflectionException
+     */
+    private function organizationDefaultValue($entity, Access $access)
+    {
+        $reflection = new \ReflectionClass($entity::class);
+        $organizationFaultValue = $reflection->getAttributes(OrganizationDefaultValue::class)[0] ?? null;
+        $fieldName = $organizationFaultValue?->getArguments()['fieldName'] ?? null;
+        if($fieldName){
+            $entity->{sprintf('set%s', ucfirst($fieldName))}(...[$access->getOrganization()]);
+        }
+    }
+}

+ 3 - 3
src/Service/Utils/Reflection.php

@@ -34,15 +34,15 @@ class Reflection
     /**
      * Appel une fonction avec ses paramètres  depuis le nom d'une classe
      * @param string $serviceName
-     * @param string $method
+     * @param string $methodName
      * @param array $parameters
      * @return mixed
      * @throws \ReflectionException
      */
-    public function dynamicInvokeClassWithArgsAndMethod(string $className, string $method, array $parameters = []): mixed
+    public function dynamicInvokeClassWithArgsAndMethod(string $className, string $methodName, array $parameters = []): mixed
     {
         $reflection = new \ReflectionClass($className);
-        $method = $reflection->getMethod($method);
+        $method = $reflection->getMethod($methodName);
         if($method->isStatic()){
             return $method->invoke(null, $parameters);
         }else{