Skip to content

Commit 9f6e3a6

Browse files
authored
fix: do not add a doctrine relation if it is a mapped superclass (#370)
1 parent 57441da commit 9f6e3a6

File tree

7 files changed

+107
-8
lines changed

7 files changed

+107
-8
lines changed

src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@ public function generatePropertyAttributes(Property $property, string $className
113113
return [new Attribute('MongoDB\Field', ['type' => $type])];
114114
}
115115

116-
if (null === $relationName = $this->getRelationName($property->reference)) {
117-
$this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null;
118-
116+
if (null === $relationName = $this->getRelationName($property, $className)) {
119117
return [];
120118
}
121119

@@ -146,9 +144,23 @@ public function generateUses(Class_ $class): array
146144
/**
147145
* Gets class or interface name to use in relations.
148146
*/
149-
private function getRelationName(?Class_ $reference): ?string
147+
private function getRelationName(Property $property, string $className): ?string
150148
{
149+
$reference = $property->reference;
150+
151151
if (!$reference) {
152+
$this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null;
153+
154+
return null;
155+
}
156+
157+
if ($reference->isAbstract && !$this->config['doctrine']['inheritanceAttributes']) {
158+
$this->logger ? $this->logger->warning(
159+
<<<'EOD'
160+
Cannot create a relation from the property "{property}" of the class "{class}" to the class "{referenceClass}" because the latter is a Mapped Superclass.
161+
If you want to add a relation anyway, use an inheritance mapping strategy and a discriminator column to do so.
162+
EOD, ['property' => $property->name(), 'class' => $className, 'referenceClass' => $reference->shortName()]) : null;
163+
152164
return null;
153165
}
154166

src/AttributeGenerator/DoctrineOrmAttributeGenerator.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,7 @@ public function generatePropertyAttributes(Property $property, string $className
170170
return [new Attribute('ORM\Column', $args)];
171171
}
172172

173-
if (null === $relationName = $this->getRelationName($property->reference)) {
174-
$this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null;
175-
173+
if (null === $relationName = $this->getRelationName($property, $className)) {
176174
return [];
177175
}
178176

@@ -276,9 +274,23 @@ private function generateIdAttributes(): array
276274
/**
277275
* Gets class or interface name to use in relations.
278276
*/
279-
private function getRelationName(?Class_ $reference): ?string
277+
private function getRelationName(Property $property, string $className): ?string
280278
{
279+
$reference = $property->reference;
280+
281281
if (!$reference) {
282+
$this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null;
283+
284+
return null;
285+
}
286+
287+
if ($reference->isAbstract && !$this->config['doctrine']['inheritanceAttributes']) {
288+
$this->logger ? $this->logger->warning(
289+
<<<'EOD'
290+
Cannot create a relation from the property "{property}" of the class "{class}" to the class "{referenceClass}" because the latter is a Mapped Superclass.
291+
If you want to add a relation anyway, use an inheritance mapping strategy and a discriminator column to do so.
292+
EOD, ['property' => $property->name(), 'class' => $className, 'referenceClass' => $reference->shortName()]) : null;
293+
282294
return null;
283295
}
284296

tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,16 @@
2424
use EasyRdf\Graph as RdfGraph;
2525
use EasyRdf\Resource as RdfResource;
2626
use PHPUnit\Framework\TestCase;
27+
use Prophecy\Argument;
28+
use Prophecy\PhpUnit\ProphecyTrait;
29+
use Psr\Log\LoggerInterface;
2730
use Symfony\Component\Config\Definition\Processor;
2831
use Symfony\Component\String\Inflector\EnglishInflector;
2932

3033
class DoctrineMongoDBAttributeGeneratorTest extends TestCase
3134
{
35+
use ProphecyTrait;
36+
3237
private DoctrineMongoDBAttributeGenerator $generator;
3338

3439
private array $classMap = [];
@@ -66,6 +71,11 @@ protected function setUp(): void
6671
$weightProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger');
6772
$weightProperty->type = 'nonPositiveInteger';
6873
$vehicle->addProperty($weightProperty);
74+
$productProperty = new Property('product');
75+
$productProperty->rangeName = 'Product';
76+
$productProperty->range = new RdfResource('https://schema.org/Product');
77+
$productProperty->reference = $product;
78+
$vehicle->addProperty($productProperty);
6979
$relationProperty = new Property('relation');
7080
$relationProperty->rangeName = 'Person';
7181
$relationProperty->range = new RdfResource('https://schema.org/Person');
@@ -145,4 +155,13 @@ public function testGenerateFieldAttributes(): void
145155
$this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relations'), 'Vehicle')
146156
);
147157
}
158+
159+
public function testGenerateAbstractRelation(): void
160+
{
161+
$loggerProphecy = $this->prophesize(LoggerInterface::class);
162+
$loggerProphecy->warning(Argument::cetera())->shouldBeCalledOnce();
163+
$this->generator->setLogger($loggerProphecy->reveal());
164+
165+
$this->assertSame([], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('product'), 'Vehicle'));
166+
}
148167
}

tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
use EasyRdf\Graph as RdfGraph;
2525
use EasyRdf\Resource as RdfResource;
2626
use PHPUnit\Framework\TestCase;
27+
use Prophecy\Argument;
28+
use Prophecy\PhpUnit\ProphecyTrait;
29+
use Psr\Log\LoggerInterface;
2730
use Symfony\Component\Config\Definition\Processor;
2831
use Symfony\Component\String\Inflector\EnglishInflector;
2932

@@ -32,6 +35,8 @@
3235
*/
3336
class DoctrineOrmAttributeGeneratorTest extends TestCase
3437
{
38+
use ProphecyTrait;
39+
3540
private DoctrineOrmAttributeGenerator $generator;
3641

3742
private array $classMap = [];
@@ -76,6 +81,11 @@ protected function setUp(): void
7681
$prefixedWeightProperty->range = new RdfResource('https://schema.org/QuantitativeValue');
7782
$prefixedWeightProperty->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph));
7883
$vehicle->addProperty($prefixedWeightProperty);
84+
$productProperty = new Property('product');
85+
$productProperty->rangeName = 'Product';
86+
$productProperty->range = new RdfResource('https://schema.org/Product');
87+
$productProperty->reference = $product;
88+
$vehicle->addProperty($productProperty);
7989
$relation01Property = new Property('relation0_1');
8090
$relation01Property->rangeName = 'QuantitativeValue';
8191
$relation01Property->range = new RdfResource('https://schema.org/QuantitativeValue');
@@ -216,4 +226,13 @@ public function testGenerateFieldAttributes(): void
216226
$this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_N'), 'Vehicle')
217227
);
218228
}
229+
230+
public function testGenerateAbstractRelation(): void
231+
{
232+
$loggerProphecy = $this->prophesize(LoggerInterface::class);
233+
$loggerProphecy->warning(Argument::cetera())->shouldBeCalledOnce();
234+
$this->generator->setLogger($loggerProphecy->reveal());
235+
236+
$this->assertSame([], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('product'), 'Vehicle'));
237+
}
219238
}

tests/e2e/customized/App/Schema/Entity/Person.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ class Person extends MyCustomClass implements MyCustomInterface
139139
#[ApiProperty(iri: 'https://schema.org/siblings')]
140140
private ?Collection $siblings = null;
141141

142+
/**
143+
* Of a \[\[Person\]\], and less typically of an \[\[Organization\]\], to indicate a topic that is known about - suggesting possible expertise but not implying it. We do not distinguish skill levels here, or relate this to educational content, events, objectives or \[\[JobPosting\]\] descriptions.
144+
*
145+
* @see https://schema.org/knowsAbout
146+
*/
147+
#[ApiProperty(iri: 'https://schema.org/knowsAbout')]
148+
private ?Thing $knowsAbout = null;
149+
142150
/** @see _:customColumn */
143151
#[ORM\Column(type: 'decimal', precision: 5, scale: 1, options: ['comment' => 'my comment'])]
144152
private ?Person $customColumn = null;
@@ -266,6 +274,16 @@ public function getSiblings(): Collection
266274
return $this->siblings;
267275
}
268276

277+
public function setKnowsAbout(?Thing $knowsAbout): void
278+
{
279+
$this->knowsAbout = $knowsAbout;
280+
}
281+
282+
public function getKnowsAbout(): ?Thing
283+
{
284+
return $this->knowsAbout;
285+
}
286+
269287
public function setCustomColumn(?Person $customColumn): void
270288
{
271289
$this->customColumn = $customColumn;

tests/e2e/original/App/Schema/Entity/Person.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,14 @@ class Person extends Thing
130130
#[ApiProperty(iri: 'https://schema.org/siblings')]
131131
private ?Collection $siblings = null;
132132

133+
/**
134+
* Of a \[\[Person\]\], and less typically of an \[\[Organization\]\], to indicate a topic that is known about - suggesting possible expertise but not implying it. We do not distinguish skill levels here, or relate this to educational content, events, objectives or \[\[JobPosting\]\] descriptions.
135+
*
136+
* @see https://schema.org/knowsAbout
137+
*/
138+
#[ApiProperty(iri: 'https://schema.org/knowsAbout')]
139+
private ?Thing $knowsAbout = null;
140+
133141
/**
134142
* @see _:customColumn
135143
*/
@@ -254,6 +262,16 @@ public function getSiblings(): Collection
254262
return $this->siblings;
255263
}
256264

265+
public function setKnowsAbout(?Thing $knowsAbout): void
266+
{
267+
$this->knowsAbout = $knowsAbout;
268+
}
269+
270+
public function getKnowsAbout(): ?Thing
271+
{
272+
return $this->knowsAbout;
273+
}
274+
257275
public function setCustomColumn(?Person $customColumn): void
258276
{
259277
$this->customColumn = $customColumn;

tests/e2e/schema.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ types:
3535
email: { unique: true, security: "is_granted('ROLE_ADMIN')" }
3636
url: ~
3737
siblings: { cardinality: "(0..*)" }
38+
knowsAbout: { range: https://schema.org/Thing }
3839
customColumn: { ormColumn: {type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}} }
3940
Brand:
4041
properties:

0 commit comments

Comments
 (0)