Browse Source

SchemaSnippetsGenerator: add other relational attributes

Olivier Massot 11 months ago
parent
commit
b6ed7e8186
1 changed files with 96 additions and 24 deletions
  1. 96 24
      src/Service/Doctrine/SchemaValidation/SchemaSnippetsMaker.php

+ 96 - 24
src/Service/Doctrine/SchemaValidation/SchemaSnippetsMaker.php

@@ -11,7 +11,9 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping\ClassMetadataInfo;
 use Doctrine\ORM\Mapping\ClassMetadataInfo;
 use Doctrine\ORM\Mapping\Column;
 use Doctrine\ORM\Mapping\Column;
 use Doctrine\ORM\Mapping\Entity;
 use Doctrine\ORM\Mapping\Entity;
+use Doctrine\ORM\Mapping\InverseJoinColumn;
 use Doctrine\ORM\Mapping\JoinColumn;
 use Doctrine\ORM\Mapping\JoinColumn;
+use Doctrine\ORM\Mapping\JoinTable;
 use Doctrine\ORM\Mapping\ManyToMany;
 use Doctrine\ORM\Mapping\ManyToMany;
 use Doctrine\ORM\Mapping\ManyToOne;
 use Doctrine\ORM\Mapping\ManyToOne;
 use Doctrine\ORM\Mapping\OneToMany;
 use Doctrine\ORM\Mapping\OneToMany;
@@ -428,6 +430,31 @@ class SchemaSnippetsMaker
             $prop->setType(Collection::class);
             $prop->setType(Collection::class);
         }
         }
 
 
+        $attributes = [];
+        $attributes[] = $this->makeRelationAttribute($type);
+
+        $joinTable = $this->makeJoinTableAttributes($type);
+        if ($joinTable) {
+            $attributes[] = $joinTable;
+        }
+
+        $attributes = array_merge($attributes, $this->makeJoinColumnAttributes($type));
+
+        $attributes = array_merge($attributes, $this->makeJoinColumnAttributes($type, true));
+
+        $prop->setAttributes($attributes);
+
+        return $prop;
+    }
+
+    /**
+     * Make the attribute defining the relation (ex: #[ORM\ManyToMany(...)])
+     *
+     * @param array $type
+     * @return Attribute
+     */
+    protected function makeRelationAttribute(array $type): Attribute
+    {
         $options = [];
         $options = [];
         if (isset($type['mappedBy'])) {
         if (isset($type['mappedBy'])) {
             $options['mappedBy'] = $type['mappedBy'];
             $options['mappedBy'] = $type['mappedBy'];
@@ -458,36 +485,81 @@ class SchemaSnippetsMaker
             ClassMetadataInfo::ONE_TO_ONE => OneToOne::class,
             ClassMetadataInfo::ONE_TO_ONE => OneToOne::class,
         ];
         ];
 
 
-        $prop->addAttribute($relationClassNames[$type['type']], $options);
+        return new Attribute($relationClassNames[$type['type']], $options);
+    }
 
 
-        if (isset($type['joinColumns'])) {
-            foreach ($type['joinColumns'] as $joinColDefinition) {
-                $attributeOptions = [];
+    /**
+     * Make the #[ORM\JoinTable] attribute (if a definition exists)
+     *
+     * @param array $type
+     * @return Attribute|null
+     */
+    protected function makeJoinTableAttributes(array $type): ?Attribute {
+        if (!isset($type['joinTable'])) {
+            return null;
+        }
 
 
-                if ($joinColDefinition['name'] !== $type['fieldName'] . '_id') {
-                    $attributeOptions['name'] = $type['fieldName'] . '_id';
-                }
-                if ($joinColDefinition['unique'] === true) {
-                    $attributeOptions['unique'] = true;
-                }
-                if ($joinColDefinition['nullable'] === false) {
-                    $attributeOptions['nullable'] = false;
-                }
-                if ($joinColDefinition['onDelete'] !== null) {
-                    $attributeOptions['onDelete'] = $joinColDefinition['onDelete'];
-                }
-                if ($joinColDefinition['columnDefinition'] !== null) {
-                    $attributeOptions['referencedColumnName'] = $joinColDefinition['columnDefinition'];
-                }
-                if ($joinColDefinition['referencedColumnName'] !== 'id') {
-                    $attributeOptions['referencedColumnName'] = $joinColDefinition['referencedColumnName'];
-                }
+        $options = [];
+        if ($type['joinTable']['name']) {
+            $options['name'] = $type['joinTable']['name'];
+        }
+
+        return new Attribute(JoinTable::class, $options);
+    }
+
+    /**
+     * Make the #[JoinColumn] attributes, if definitions exists.
+     *
+     * Is `$inverse` is true, make the #[InverseJoinColumn] instead.
+     *
+     * @param array $type
+     * @param bool $inverse
+     * @return array
+     */
+    protected function makeJoinColumnAttributes(array $type, bool $inverse = false): array {
+        $key = $inverse ? 'inverseJoinColumns' : 'joinColumns';
+
+        $definition = $type[$key] ?? $type['joinTable'][$key] ?? [];
+        if (empty($definition)) {
+            return [];
+        }
+
+        $attributes = [];
 
 
-                $prop->addAttribute(JoinColumn::class, $attributeOptions);
+        foreach ($definition as $joinColDefinition) {
+            $options = [];
+
+            if (isset($joinColDefinition['name']) && $joinColDefinition['name'] !== $type['fieldName'] . '_id') {
+                $options['name'] = $joinColDefinition['name'];
+            }
+            if (($joinColDefinition['unique'] ?? false) === true) {
+                $options['unique'] = true;
+            }
+            if (($joinColDefinition['nullable'] ?? true) === false) {
+                $options['nullable'] = false;
+            }
+            if (($joinColDefinition['onDelete'] ?? null) !== null) {
+                $options['onDelete'] = $joinColDefinition['onDelete'];
+            }
+            if (($joinColDefinition['columnDefinition'] ?? null) !== null) {
+                $options['columnDefinition'] = $joinColDefinition['columnDefinition'];
+            }
+            if (($joinColDefinition['referencedColumnName'] ?? 'id') !== 'id') {
+                $options['referencedColumnName'] = $joinColDefinition['referencedColumnName'];
             }
             }
+
+            if (empty($options)) {
+                // Useless attribute
+                continue;
+            }
+
+            $attributes[] = new Attribute(
+                $inverse ? InverseJoinColumn::class : JoinColumn::class,
+                $options
+            );
         }
         }
 
 
-        return $prop;
+        return $attributes;
     }
     }
 
 
     /**
     /**