diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
index 6a8aed1f42d..98aa7411952 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
@@ -61,9 +61,24 @@ public function setEntityManager(EntityManagerInterface $em): void
$this->em = $em;
}
+ /**
+ * @param A $maybeOwningSide
+ *
+ * @return (A is ManyToManyAssociationMapping ? ManyToManyOwningSideMapping : (
+ * A is OneToOneAssociationMapping ? OneToOneOwningSideMapping : (
+ * A is OneToManyAssociationMapping ? ManyToOneAssociationMapping : (
+ * A is ManyToOneAssociationMapping ? ManyToOneAssociationMapping : OwningSideMapping
+ * ))))
+ *
+ * @template A of AssociationMapping
+ */
final public function getOwningSide(AssociationMapping $maybeOwningSide): OwningSideMapping
{
if ($maybeOwningSide instanceof OwningSideMapping) {
+ assert($maybeOwningSide instanceof ManyToManyOwningSideMapping ||
+ $maybeOwningSide instanceof OneToOneOwningSideMapping ||
+ $maybeOwningSide instanceof ManyToOneAssociationMapping);
+
return $maybeOwningSide;
}
@@ -72,7 +87,9 @@ final public function getOwningSide(AssociationMapping $maybeOwningSide): Owning
$owningSide = $this->getMetadataFor($maybeOwningSide->targetEntity)
->associationMappings[$maybeOwningSide->mappedBy];
- assert($owningSide instanceof OwningSideMapping);
+ assert($owningSide instanceof ManyToManyOwningSideMapping ||
+ $owningSide instanceof OneToOneOwningSideMapping ||
+ $owningSide instanceof ManyToOneAssociationMapping);
return $owningSide;
}
diff --git a/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php b/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php
index 9f652292647..64c8accadea 100644
--- a/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php
+++ b/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php
@@ -114,8 +114,6 @@ public function count(PersistentCollection $collection): int
$sourceClass = $this->em->getClassMetadata($mapping->sourceEntity);
$association = $this->em->getMetadataFactory()->getOwningSide($mapping);
- assert($association->isManyToManyOwningSide());
-
$joinTableName = $this->quoteStrategy->getJoinTableName($association, $sourceClass, $this->platform);
$joinColumns = ! $mapping->isOwningSide()
? $association->joinTable['inverseJoinColumns']
@@ -346,9 +344,6 @@ protected function generateFilterConditionSQL(ClassMetadata $targetEntity, strin
protected function getOnConditionSQL(AssociationMapping $mapping): array
{
$association = $this->em->getMetadataFactory()->getOwningSide($mapping);
-
- assert($association->isManyToManyOwningSide());
-
$joinColumns = $mapping->isOwningSide()
? $association->joinTable['inverseJoinColumns']
: $association->joinTable['joinColumns'];
@@ -680,7 +675,6 @@ private function getJoinTableRestrictions(
$params = [];
$types = [];
- assert($mapping->isManyToManyOwningSide());
foreach ($mapping->joinTableColumns as $joinTableColumn) {
$whereClauses[] = ($addFilters ? 't.' : '') . $joinTableColumn . ' = ?';
diff --git a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php
index d039f3627a7..0629e409edd 100644
--- a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php
+++ b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php
@@ -21,6 +21,7 @@
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\InverseSideMapping;
use Doctrine\ORM\Mapping\JoinColumnMapping;
+use Doctrine\ORM\Mapping\ManyToManyAssociationMapping;
use Doctrine\ORM\Mapping\MappingException;
use Doctrine\ORM\Mapping\OneToManyAssociationMapping;
use Doctrine\ORM\Mapping\QuoteStrategy;
@@ -518,9 +519,6 @@ protected function deleteJoinTableRecords(array $identifier, array $types): void
}
$association = $this->em->getMetadataFactory()->getOwningSide($association);
-
- assert($association->isManyToManyOwningSide());
-
$joinColumns = $mapping->isOwningSide()
? $association->joinTable['joinColumns']
: $association->joinTable['inverseJoinColumns'];
@@ -902,6 +900,7 @@ public function getManyToManyCollection(
int|null $offset = null,
int|null $limit = null,
): array {
+ assert($assoc->isManyToMany());
$this->switchPersisterContext($offset, $limit);
$stmt = $this->getManyToManyStatement($assoc, $sourceEntity, $offset, $limit);
@@ -956,6 +955,7 @@ private function loadCollectionFromStatement(
*/
public function loadManyToManyCollection(AssociationMapping $assoc, object $sourceEntity, PersistentCollection $collection): array
{
+ assert($assoc->isManyToMany());
$stmt = $this->getManyToManyStatement($assoc, $sourceEntity);
return $this->loadCollectionFromStatement($assoc, $stmt, $collection);
@@ -963,7 +963,7 @@ public function loadManyToManyCollection(AssociationMapping $assoc, object $sour
/** @throws MappingException */
private function getManyToManyStatement(
- AssociationMapping $assoc,
+ AssociationMapping&ManyToManyAssociationMapping $assoc,
object $sourceEntity,
int|null $offset = null,
int|null $limit = null,
@@ -977,14 +977,10 @@ private function getManyToManyStatement(
$parameters = [];
if (! $assoc->isOwningSide()) {
- assert(isset($assoc->mappedBy));
$class = $this->em->getClassMetadata($assoc->targetEntity);
}
$association = $this->em->getMetadataFactory()->getOwningSide($assoc);
-
- assert($association->isManyToManyOwningSide());
-
$joinColumns = $assoc->isOwningSide()
? $association->joinTable['joinColumns']
: $association->joinTable['inverseJoinColumns'];
@@ -1331,15 +1327,13 @@ protected function getSelectColumnAssociationSQL(
* Gets the SQL join fragment used when selecting entities from a
* many-to-many association.
*/
- protected function getSelectManyToManyJoinSQL(AssociationMapping $manyToMany): string
+ protected function getSelectManyToManyJoinSQL(AssociationMapping&ManyToManyAssociationMapping $manyToMany): string
{
$conditions = [];
$association = $manyToMany;
$sourceTableAlias = $this->getSQLTableAlias($this->class->name);
- $association = $this->em->getMetadataFactory()->getOwningSide($manyToMany);
- assert($association->isManyToManyOwningSide());
-
+ $association = $this->em->getMetadataFactory()->getOwningSide($manyToMany);
$joinTableName = $this->quoteStrategy->getJoinTableName($association, $this->class, $this->platform);
$joinColumns = $manyToMany->isOwningSide()
? $association->joinTable['inverseJoinColumns']
@@ -1861,7 +1855,7 @@ private function getTypes(string $field, mixed $value, ClassMetadata $class): ar
if ($assoc->isManyToManyOwningSide()) {
$columns = $assoc->relationToTargetKeyColumns;
} else {
- assert($assoc->isToOneOwningSide() || $assoc->isManyToOne());
+ assert($assoc->isToOneOwningSide());
$columns = $assoc->sourceToTargetKeyColumns;
}
diff --git a/phpstan.neon b/phpstan.neon
index 1774b1f74d8..d63c4b8b0fc 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -45,3 +45,9 @@ parameters:
- lib/Doctrine/ORM/Persisters/Entity/JoinedSubclassPersister.php
- lib/Doctrine/ORM/Query/SqlWalker.php
- lib/Doctrine/ORM/Tools/SchemaValidator.php
+
+ -
+ message: '#^.*Doctrine\\ORM\\Mapping\\AssociationMapping&Doctrine\\ORM\\Mapping\\ManyToManyAssociationMapping, Doctrine\\ORM\\Mapping\\AssociationMapping given\.#'
+ paths:
+ - lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php
+ - lib/Doctrine/ORM/Persisters/Entity/JoinedSubclassPersister.php
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 2a010d89f72..78135a9cbb4 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -407,6 +407,11 @@
generatorType]]>
idGenerator]]>
+
+ assert($owningSide instanceof ManyToManyOwningSideMapping ||
+ $owningSide instanceof OneToOneOwningSideMapping ||
+ $owningSide instanceof ManyToOneAssociationMapping)
+