Browse Source

SchemaSnippetsMaker : various fixes

Olivier Massot 11 months ago
parent
commit
e5c253ee40
1 changed files with 47 additions and 10 deletions
  1. 47 10
      src/Service/Doctrine/SchemaValidation/SchemaSnippetsMaker.php

+ 47 - 10
src/Service/Doctrine/SchemaValidation/SchemaSnippetsMaker.php

@@ -134,7 +134,7 @@ class SchemaSnippetsMaker
     protected function makeMethodsSnippetForProp(Property $prop): array {
         $methods = [];
 
-        if ($prop->getType() !== 'Collection') {
+        if ($prop->getType() !== Collection::class) {
             $methods[] = $this->makeSnippetGetterForProp($prop);
             $methods[] = $this->makeSnippetSetterForProp($prop);
         } else {
@@ -288,6 +288,16 @@ class SchemaSnippetsMaker
         }
     }
 
+    protected function getRelationTargetEntityName(array $type): string
+    {
+        $targetEntityName = $this->entityUtils->getEntityNameFromFullName($type['targetEntity']);
+        try {
+            return $this->entityUtils->getFullNameFromEntityName($targetEntityName);
+        } catch (\LogicException) {
+            return 'mixed';
+        }
+    }
+
     /**
      * Construit l'objet PhpFile
      * @see https://api.nette.org/php-generator/master/Nette/PhpGenerator/PhpFile.html
@@ -407,13 +417,8 @@ class SchemaSnippetsMaker
             isset($type['type']) &&
             $type['type'] === ClassMetadataInfo::ONE_TO_ONE || $type['type'] === ClassMetadataInfo::MANY_TO_ONE
         ) {
-            $targetEntityName = $this->entityUtils->getEntityNameFromFullName($type['targetEntity']);
-            try {
-                $newType = $this->entityUtils->getFullNameFromEntityName($targetEntityName);
-            } catch (\LogicException) {
-                $newType = 'mixed';
-            }
-            $prop->setType($newType);
+            $targetEntityName = $this->getRelationTargetEntityName($type);
+            $prop->setType($targetEntityName);
 
         } else {
             $prop->setType(Collection::class);
@@ -513,6 +518,34 @@ class SchemaSnippetsMaker
         return $method;
     }
 
+    protected function getTargetEntityNameFromCollectionProp(Property $prop): ?string
+    {
+        if ($prop->getType() !== Collection::class) {
+            throw new \LogicException('The property must be a collection');
+        }
+
+        foreach ($prop->getAttributes() as $attribute) {
+            if (
+                $attribute instanceof Attribute &&
+                ($attribute->getName() === OneToMany::class || $attribute->getName() === ManyToMany::class)
+            ) {
+                $targetEntityName = $attribute->getArguments()['targetEntity'];
+                if (!$targetEntityName) {
+                    return null;
+                }
+
+                // Normalize result (it could be a FQN, or a '::class' notation)
+                $targetEntityName = str_replace('::class', '', $targetEntityName);
+
+                if (!str_contains($targetEntityName, '\\')) {
+                    $targetEntityName = $this->entityUtils->getFullNameFromEntityName($targetEntityName);
+                }
+                return $targetEntityName;
+            }
+        }
+        return null;
+    }
+
     /**
      * Make an 'adder' method for the given property
      *
@@ -525,8 +558,10 @@ class SchemaSnippetsMaker
 
         $method = new Method('add' . ucfirst($singularPropName));
 
+        $targetEntityName = $this->getTargetEntityNameFromCollectionProp($prop);
+
         $parameter = new Parameter($singularPropName);
-        $parameter->setType($prop->getType());
+        $parameter->setType($targetEntityName ?? 'mixed');
         $method->setParameters([$parameter]);
 
         $method->setReturnType('self');
@@ -556,8 +591,10 @@ class SchemaSnippetsMaker
 
         $method = new Method('remove' . ucfirst($singularPropName));
 
+        $targetEntityName = $this->getTargetEntityNameFromCollectionProp($prop);
+
         $parameter = new Parameter($singularPropName);
-        $parameter->setType($prop->getType());
+        $parameter->setType($targetEntityName ?? 'mixed');
         $method->setParameters([$parameter]);
 
         $method->setReturnType('self');