Skip to content

Commit 1febaf0

Browse files
authored
fix: various range issues (#386)
1 parent e5caafe commit 1febaf0

File tree

5 files changed

+81
-17
lines changed

5 files changed

+81
-17
lines changed

src/AnnotationGenerator/PhpDocAnnotationGenerator.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ public function generatePropertyAnnotations(Property $property, string $classNam
7676
$description = $this->formatDoc((string) $property->description(), true);
7777

7878
$annotations = [];
79-
if ($this->isDocUseful($property)) {
80-
$annotations[] = sprintf('@var %s %s', $this->toPhpDocType($property), $this->escapePhpDoc($description[0]));
79+
if ($this->isDocUseful($property) && $phpDocType = $this->toPhpDocType($property)) {
80+
$annotations[] = sprintf('@var %s %s', $phpDocType, $this->escapePhpDoc($description[0]));
8181
} else {
8282
$annotations = $description;
8383
$annotations[] = '';

src/PhpTypeConverter.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,21 @@
1616
use ApiPlatform\SchemaGenerator\Model\Class_;
1717
use ApiPlatform\SchemaGenerator\Model\Property;
1818
use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty;
19-
use ApiPlatform\SchemaGenerator\Schema\TypeConverter;
2019

2120
final class PhpTypeConverter implements PhpTypeConverterInterface
2221
{
23-
private TypeConverter $typeConverter;
24-
25-
public function __construct()
26-
{
27-
$this->typeConverter = new TypeConverter();
28-
}
29-
3022
public function getPhpType(Property $property, array $config = [], array $classes = []): ?string
3123
{
3224
if (!$property instanceof SchemaProperty) {
3325
throw new \LogicException(sprintf('Property "%s" has to be an instance of "%s".', $property->name(), SchemaProperty::class));
3426
}
3527

36-
if ($property->isArray && $property->range) {
37-
return ($config['doctrine']['useCollection'] ?? false) && !$this->typeConverter->getType($property->range) ? 'Collection' : 'array';
28+
if ($property->isArray && $property->reference) {
29+
return ($config['doctrine']['useCollection'] ?? false) ? 'Collection' : 'array';
30+
}
31+
32+
if ($property->isArray) {
33+
return 'array';
3834
}
3935

4036
return $this->getNonArrayType($property, $classes);

src/Schema/PropertyGenerator/PropertyGenerator.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,7 @@ private function getRanges(RdfResource $range, ?array $propertyConfig, array $co
181181
{
182182
$localName = $range->localName();
183183
$dataType = (bool) $this->typeConverter->getType($range);
184-
$ranges = [];
185-
if (!$dataType && $range->isBNode()) {
184+
if (!$dataType) {
186185
if (null !== ($unionOf = $range->get('owl:unionOf'))) {
187186
return $this->getRanges($unionOf, $propertyConfig, $config);
188187
}
@@ -192,9 +191,9 @@ private function getRanges(RdfResource $range, ?array $propertyConfig, array $co
192191
if (null !== ($rdfRest = $range->get('rdf:rest'))) {
193192
$ranges = array_merge($ranges, $this->getRanges($rdfRest, $propertyConfig, $config));
194193
}
195-
}
196194

197-
return $ranges;
195+
return $ranges;
196+
}
198197
}
199198

200199
if (

tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616
use ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator;
1717
use ApiPlatform\SchemaGenerator\Model\Class_;
1818
use ApiPlatform\SchemaGenerator\Model\Interface_;
19+
use ApiPlatform\SchemaGenerator\Model\Property;
1920
use ApiPlatform\SchemaGenerator\PhpTypeConverter;
2021
use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass;
22+
use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty;
23+
use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration;
2124
use EasyRdf\Graph as RdfGraph;
2225
use EasyRdf\Resource as RdfResource;
2326
use PHPUnit\Framework\TestCase;
27+
use Symfony\Component\Config\Definition\Processor;
2428
use Symfony\Component\String\Inflector\EnglishInflector;
2529

2630
class PhpDocAnnotationGeneratorTest extends TestCase
@@ -29,10 +33,15 @@ class PhpDocAnnotationGeneratorTest extends TestCase
2933

3034
protected function setUp(): void
3135
{
36+
$configuration = new SchemaGeneratorConfiguration();
37+
$processedConfiguration = (new Processor())->processConfiguration($configuration, [[
38+
'author' => 'Bill',
39+
]]);
40+
3241
$this->generator = new PhpDocAnnotationGenerator(
3342
new PhpTypeConverter(),
3443
new EnglishInflector(),
35-
['author' => 'Bill'],
44+
$processedConfiguration,
3645
[],
3746
);
3847
}
@@ -54,4 +63,44 @@ public function provideGenerateClassAnnotationsCases(): \Generator
5463
$graph = new RdfGraph();
5564
yield 'with resource' => [new SchemaClass('Res', new RdfResource('https://schema.org/Res', $graph)), ['@see https://schema.org/Res', '@author Bill']];
5665
}
66+
67+
/**
68+
* @dataProvider provideGeneratePropertyAnnotationsCases
69+
*/
70+
public function testGeneratePropertyAnnotations(Property $property, string $className, array $annotations): void
71+
{
72+
$this->assertSame($annotations, $this->generator->generatePropertyAnnotations($property, $className));
73+
}
74+
75+
public function provideGeneratePropertyAnnotationsCases(): \Generator
76+
{
77+
$property = new SchemaProperty('telephone');
78+
$graph = new RdfGraph();
79+
$resource = new RdfResource('https://schema.org/telephone', $graph);
80+
$resource->addResource('rdfs:comment', 'The telephone <b>number</b>.<br>@number');
81+
$property->resource = $resource;
82+
83+
yield 'property with description' => [$property, 'Place', ['The telephone **number**. ', ' \@number', '', '@see https://schema.org/telephone', '']];
84+
85+
$property = new SchemaProperty('review');
86+
$graph = new RdfGraph();
87+
$resource = new RdfResource('https://schema.org/review', $graph);
88+
$resource->addResource('rdfs:comment', 'A review of the item.');
89+
$property->resource = $resource;
90+
$property->isArray = true;
91+
$property->typeHint = 'array';
92+
$property->type = 'string';
93+
$property->range = new RdfResource('https://schema.org/Text');
94+
95+
yield 'array of strings property' => [$property, 'Place', ['@var string[]|null A review of the item.', '@see https://schema.org/review', '']];
96+
97+
$property = new SchemaProperty('address');
98+
$graph = new RdfGraph();
99+
$property->isNullable = false;
100+
$property->isArray = true;
101+
$property->typeHint = 'array';
102+
$property->reference = new SchemaClass('PostalAddress', new RdfResource('https://schema.org/PostalAddress', $graph));
103+
104+
yield 'reference property' => [$property, 'Place', ['@var Collection<PostalAddress> ', '']];
105+
}
57106
}

tests/TypesGeneratorTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ public function testGenerateAllResolveTypes(): void
176176
$competencyWorldEntity = file_get_contents("$this->outputDir/App/Entity/CompetencyWorldEntity.php");
177177
$this->assertStringContainsString('class CompetencyWorldEntity extends Thing', $competencyWorldEntity);
178178
$this->assertStringContainsString('private ?string $hasAppellation = null;', $competencyWorldEntity);
179+
$this->assertStringContainsString('private ?string $hasDescription = null;', $competencyWorldEntity);
180+
$this->assertStringContainsString('private array $intendedOccupation = [];', $competencyWorldEntity);
179181
$this->assertStringContainsString('public function setHasAppellation(?string $hasAppellation): void', $competencyWorldEntity);
180182
$this->assertStringContainsString('public function getHasAppellation(): ?string', $competencyWorldEntity);
181183
}
@@ -239,6 +241,23 @@ private function getGraphs(): array
239241
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:rangeIncludes', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString');
240242
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:rangeIncludes', 'https://schema.org/Text');
241243

244+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasDescription', 'rdf:type', 'rdf:Property');
245+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasDescription', 'schema:domainIncludes', 'https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity');
246+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasDescription', 'schema:rangeIncludes', 'https://gitlab.com/mmorg/nodefr-2/n3-5');
247+
248+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-5', 'rdf:type', 'rdfs:Class');
249+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-5', 'owl:unionOf', 'https://gitlab.com/mmorg/nodefr-2/n3-6');
250+
251+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-6', 'rdf:first', 'http://www.w3.org/2001/XMLSchema#language');
252+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-6', 'rdf:rest', 'https://gitlab.com/mmorg/nodefr-2/n3-7');
253+
254+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-7', 'rdf:first', 'http://www.w3.org/2001/XMLSchema#string');
255+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-7', 'rdf:rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString');
256+
257+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/intendedOccupation', 'rdf:type', 'rdf:Property');
258+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/intendedOccupation', 'schema:domainIncludes', 'https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity');
259+
$nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/intendedOccupation', 'schema:rangeIncludes', 'https://gitlab.com/mmorg/nodefr-2/specialCase');
260+
242261
$graph = new RdfGraph(SchemaGeneratorConfiguration::SCHEMA_ORG_URI);
243262

244263
$graph->addResource('https://schema.org/Article', 'rdf:type', 'rdfs:Class');
@@ -397,6 +416,7 @@ private function getAllResolveTypesConfig(): array
397416
],
398417
'attributeGenerators' => [
399418
],
419+
'relations' => ['defaultCardinality' => '(1..*)'],
400420
'allTypes' => true,
401421
'resolveTypes' => true,
402422
];

0 commit comments

Comments
 (0)