Skip to content

Commit b187bc8

Browse files
authored
Merge pull request #11308 from greg0ire/throw-instead-of-assert
Throw a full-fledged exception on invalid call
2 parents 2a8802a + 3f7a333 commit b187bc8

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

UPGRADE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Upgrade to 3.0
22

3+
## BC BREAK: Calling `ClassMetadata::getAssociationMappedByTargetField()` with the owning side of an association now throws an exception
4+
5+
Previously, calling
6+
`Doctrine\ORM\Mapping\ClassMetadata::getAssociationMappedByTargetField()` with
7+
the owning side of an association returned `null`, which was undocumented, and
8+
wrong according to the phpdoc of the parent method.
9+
10+
If you do not know whether you are on the owning or inverse side of an association,
11+
you can use `Doctrine\ORM\Mapping\ClassMetadata::isAssociationInverseSide()`
12+
to find out.
13+
314
## BC BREAK: `Doctrine\ORM\Proxy\Autoloader` no longer extends `Doctrine\Common\Proxy\Autoloader`
415

516
Make sure to use the former when writing a type declaration or an `instanceof` check.

src/Mapping/ClassMetadata.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
use function ltrim;
4242
use function method_exists;
4343
use function spl_object_id;
44+
use function sprintf;
4445
use function str_contains;
4546
use function str_replace;
4647
use function strtolower;
@@ -2457,9 +2458,20 @@ public function isAssociationInverseSide(string $assocName): bool
24572458

24582459
public function getAssociationMappedByTargetField(string $assocName): string
24592460
{
2460-
$assoc = $this->associationMappings[$assocName];
2461+
$assoc = $this->getAssociationMapping($assocName);
24612462

2462-
assert($assoc instanceof InverseSideMapping);
2463+
if (! $assoc instanceof InverseSideMapping) {
2464+
throw new LogicException(sprintf(
2465+
<<<'EXCEPTION'
2466+
Context: Calling %s() with "%s", which is the owning side of an association.
2467+
Problem: The owning side of an association has no "mappedBy" field.
2468+
Solution: Call %s::isAssociationInverseSide() to check first.
2469+
EXCEPTION,
2470+
__METHOD__,
2471+
$assocName,
2472+
self::class,
2473+
));
2474+
}
24632475

24642476
return $assoc->mappedBy;
24652477
}

tests/Tests/ORM/Mapping/ClassMetadataTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
use Doctrine\Tests\ORM\Mapping\TypedFieldMapper\CustomIntAsStringTypedFieldMapper;
4848
use Doctrine\Tests\OrmTestCase;
4949
use DoctrineGlobalArticle;
50+
use LogicException;
5051
use PHPUnit\Framework\Attributes\Group as TestGroup;
5152
use ReflectionClass;
5253
use stdClass;
@@ -1054,6 +1055,21 @@ public function testItAddingLifecycleCallbackOnEmbeddedClassIsIllegal(): void
10541055

10551056
$metadata->addLifecycleCallback('foo', 'bar');
10561057
}
1058+
1059+
public function testItThrowsOnInvalidCallToGetAssociationMappedByTargetField(): void
1060+
{
1061+
$metadata = new ClassMetadata(self::class);
1062+
$metadata->mapOneToOne(['fieldName' => 'foo', 'targetEntity' => 'bar']);
1063+
1064+
$this->expectException(LogicException::class);
1065+
$this->expectExceptionMessage(<<<'EXCEPTION'
1066+
Context: Calling Doctrine\ORM\Mapping\ClassMetadata::getAssociationMappedByTargetField() with "foo", which is the owning side of an association.
1067+
Problem: The owning side of an association has no "mappedBy" field.
1068+
Solution: Call Doctrine\ORM\Mapping\ClassMetadata::isAssociationInverseSide() to check first.
1069+
EXCEPTION);
1070+
1071+
$metadata->getAssociationMappedByTargetField('foo');
1072+
}
10571073
}
10581074

10591075
#[MappedSuperclass]

0 commit comments

Comments
 (0)