Skip to content

Commit c783b1d

Browse files
authored
feat(openapi): improve type detection (#399)
Introduce type classes in order to represent array and composite types. Manage correctly allOf and oneOf keywords.
1 parent a5c0082 commit c783b1d

File tree

210 files changed

+8724
-589
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

210 files changed

+8724
-589
lines changed

bin/compile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,8 @@ php schema.phar generate tmp/original tests/e2e/schema_openapi_ref.yml -n -vv --
4040
diff tests/e2e/original/App/OpenApi/Entity/Order.php tmp/original/App/OpenApi/Entity/Order.php;
4141
diff tests/e2e/original/App/OpenApi/Entity/Pet.php tmp/original/App/OpenApi/Entity/Pet.php;
4242
diff tests/e2e/original/App/OpenApi/Entity/User.php tmp/original/App/OpenApi/Entity/User.php;
43+
44+
php schema.phar generate tmp/original tests/e2e/schema_open_education_api.yml -n -vv --ansi;
45+
46+
diff tests/e2e/original/App/OpenApi/Entity/AcademicSession.php tmp/original/App/OpenApi/Entity/AcademicSession.php;
47+
diff tests/e2e/original/App/OpenApi/Entity/Association.php tmp/original/App/OpenApi/Entity/Association.php;

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"symfony/string": "^5.2 || ^6.0"
5252
},
5353
"require-dev": {
54-
"api-platform/core": "^v2.7.0-rc.1",
54+
"api-platform/core": "^v2.7",
5555
"doctrine/orm": "^2.7",
5656
"myclabs/php-enum": "^1.7",
5757
"symfony/doctrine-bridge": "^5.2 || ^6.0",

composer.lock

Lines changed: 403 additions & 444 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/AnnotationGenerator/PhpDocAnnotationGenerator.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,26 +199,27 @@ protected function toPhpDocType(Property $property, bool $adderOrRemover = false
199199
{
200200
$suffix = $property->isNullable ? '|null' : '';
201201
if ($property->isEnum) {
202-
if ($property->isArray) {
202+
if ($property->isArray()) {
203203
return 'string[]'.$suffix;
204204
}
205205

206206
return 'string'.$suffix;
207207
}
208208

209-
$enforcedNonArrayProperty = clone $property;
210-
$enforcedNonArrayProperty->isArray = false;
209+
if (!$property->reference && null !== $phpDocType = $this->phpTypeConverter->getPhpType($property)) {
210+
if ('array' === $phpDocType && $property->type) {
211+
$phpDocType = $property->type->getPhp();
212+
}
211213

212-
if (!$property->reference && null !== $phpDocType = $this->phpTypeConverter->getPhpType($enforcedNonArrayProperty)) {
213-
return ($property->isArray ? sprintf('%s[]', $phpDocType) : $phpDocType).$suffix;
214+
return $phpDocType.$suffix;
214215
}
215216

216217
if (!$property->reference) {
217218
return null;
218219
}
219220

220221
$phpDocType = $property->reference->interfaceName() ?: $property->reference->name();
221-
if (!$property->isArray || $adderOrRemover) {
222+
if ($adderOrRemover || !$property->isArray()) {
222223
return $phpDocType.$suffix;
223224
}
224225

src/AttributeGenerator/ConstraintAttributeGenerator.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ public function generatePropertyAttributes(Property $property, string $className
4242

4343
$asserts = [];
4444

45-
if (!$property->isArray && $property->type) {
46-
switch ($property->type) {
45+
if ($property->type && !$property->isArray()) {
46+
switch ((string) $property->type) {
4747
case 'url':
4848
$asserts[] = new Attribute('Assert\Url');
4949
break;
@@ -74,7 +74,7 @@ public function generatePropertyAttributes(Property $property, string $className
7474
if ($property->isEnum && $property->reference) {
7575
$args = ['callback' => [new Literal(sprintf('%s::class', $property->reference->name())), 'toArray']];
7676

77-
if ($property->isArray) {
77+
if ($property->isArray()) {
7878
$args['multiple'] = true;
7979
}
8080

src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ApiPlatform\SchemaGenerator\Model\Attribute;
1818
use ApiPlatform\SchemaGenerator\Model\Class_;
1919
use ApiPlatform\SchemaGenerator\Model\Property;
20+
use ApiPlatform\SchemaGenerator\Model\Type\CompositeType;
2021
use ApiPlatform\SchemaGenerator\Model\Use_;
2122
use Nette\PhpGenerator\Literal;
2223

@@ -86,34 +87,38 @@ public function generatePropertyAttributes(Property $property, string $className
8687

8788
$type = null;
8889
if ($property->isEnum) {
89-
$type = $property->isArray ? 'simple_array' : 'string';
90-
} elseif ($property->isArray && $property->type) {
90+
$type = $property->isArray() ? 'simple_array' : 'string';
91+
} elseif (!$property->reference && $property->isArray()) {
9192
$type = 'collection';
92-
} elseif (!$property->isArray && $property->type && !$property->reference && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) {
93-
switch ($property->type) {
94-
case 'time':
95-
$type = 'time';
96-
break;
97-
case 'dateTime':
98-
$type = 'date';
99-
break;
100-
default:
101-
$type = $phpType;
102-
switch ($phpType) {
103-
case 'bool':
104-
$type = 'boolean';
105-
break;
106-
case 'int':
107-
$type = 'integer';
108-
break;
109-
case '\\'.\DateTimeInterface::class:
110-
$type = 'date';
111-
break;
112-
case '\\'.\DateInterval::class:
113-
$type = 'string';
114-
break;
115-
}
116-
break;
93+
} elseif ($property->type && !$property->reference && !$property->isArray() && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) {
94+
if ($property->type instanceof CompositeType) {
95+
$type = 'raw';
96+
} else {
97+
switch ((string) $property->type) {
98+
case 'time':
99+
$type = 'time';
100+
break;
101+
case 'dateTime':
102+
$type = 'date';
103+
break;
104+
default:
105+
$type = $phpType;
106+
switch ($phpType) {
107+
case 'bool':
108+
$type = 'boolean';
109+
break;
110+
case 'int':
111+
$type = 'integer';
112+
break;
113+
case '\\'.\DateTimeInterface::class:
114+
$type = 'date';
115+
break;
116+
case '\\'.\DateInterval::class:
117+
$type = 'string';
118+
break;
119+
}
120+
break;
121+
}
117122
}
118123
}
119124

src/AttributeGenerator/DoctrineOrmAttributeGenerator.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ApiPlatform\SchemaGenerator\Model\Attribute;
1818
use ApiPlatform\SchemaGenerator\Model\Class_;
1919
use ApiPlatform\SchemaGenerator\Model\Property;
20+
use ApiPlatform\SchemaGenerator\Model\Type\CompositeType;
2021
use ApiPlatform\SchemaGenerator\Model\Use_;
2122
use Nette\PhpGenerator\Literal;
2223

@@ -102,10 +103,10 @@ public function generatePropertyAttributes(Property $property, string $className
102103

103104
$type = null;
104105
if ($property->isEnum) {
105-
$type = $property->isArray ? 'simple_array' : 'string';
106-
} elseif ($property->isArray && $property->type) {
106+
$type = $property->isArray() ? 'simple_array' : 'string';
107+
} elseif (!$property->reference && $property->isArray()) {
107108
$type = 'json';
108-
} elseif (!$property->isArray && $property->type && !$property->reference && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) {
109+
} elseif ($property->type && !$property instanceof CompositeType && !$property->reference && !$property->isArray() && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) {
109110
switch ($property->type) {
110111
case 'time':
111112
$type = 'time';

src/ClassMutator/AnnotationsAppender.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ private function generatePropertiesAnnotations(Class_ $class): void
119119
$property->addGetterAnnotation($getterAnnotation);
120120
}
121121

122-
if ($property->isArray) {
122+
if ($property->isArray()) {
123123
foreach ($annotationGenerator->generateAdderAnnotations($property) as $adderAnnotation) {
124124
$property->addAdderAnnotation($adderAnnotation);
125125
}

src/ClassMutator/ClassPropertiesTypehintMutator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\SchemaGenerator\ClassMutator;
1515

1616
use ApiPlatform\SchemaGenerator\Model\Class_;
17+
use ApiPlatform\SchemaGenerator\Model\Type\ArrayType;
1718
use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface;
1819

1920
final class ClassPropertiesTypehintMutator implements ClassMutatorInterface
@@ -48,9 +49,9 @@ public function __invoke(Class_ $class, array $context): void
4849
$this->classes
4950
);
5051

51-
if ($property->isArray) {
52+
if ($property->type instanceof ArrayType) {
5253
$nonArrayForcedProperty = clone $property;
53-
$nonArrayForcedProperty->isArray = false;
54+
$nonArrayForcedProperty->type = $property->type->type;
5455

5556
$property->adderRemoverTypeHint = $this->phpTypeConverter->getPhpType($nonArrayForcedProperty, $this->config, $this->classes);
5657
}

src/Model/Class_.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ public function toNetteFile(array $config, InflectorInterface $inflector, ?PhpFi
318318
}
319319

320320
foreach ($sortedProperties as $property) {
321-
if ($property->isArray && 'array' !== $property->typeHint && !$property->isEnum) {
321+
if (!$property->isEnum && 'array' !== $property->typeHint && $property->isArray()) {
322322
$constructor->addBody('$this->? = new ArrayCollection();', [$property->name()]);
323323
}
324324
}

0 commit comments

Comments
 (0)