Skip to content

Commit

Permalink
Rework association mapping hierarchy
Browse files Browse the repository at this point in the history
- Each type is now either final, abstract or an interface.
- The mappedBy attribute is no longer nullable and moved down the
  hierarchy.
- The inversedBy attribute is still nullable and also moved down the
  hierarchy.
- Code common to ManyToOneAssociationMapping and
  OneToOneOwningSideMapping is de-duplicated and moved up the hierarchy
- Code inside ToManyInverseSideMapping and ToManyOwningSideMapping comes
  from a trait to avoid duplication.
  • Loading branch information
greg0ire committed May 7, 2023
1 parent 3ddb2a8 commit e18b80c
Show file tree
Hide file tree
Showing 35 changed files with 507 additions and 318 deletions.
4 changes: 2 additions & 2 deletions lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ protected function prepare(): void
}

// Mark any non-collection opposite sides as fetched, too.
if ($assoc['mappedBy']) {
if (! $assoc->isOwningSide()) {
$this->hints['fetched'][$dqlAlias][$assoc['mappedBy']] = true;

continue;
Expand Down Expand Up @@ -439,7 +439,7 @@ protected function hydrateRowData(array $row, array &$result): void
$targetClass->reflFields[$inverseAssoc['fieldName']]->setValue($element, $parentObject);
$this->uow->setOriginalEntityProperty(spl_object_id($element), $inverseAssoc['fieldName'], $parentObject);
}
} elseif ($parentClass === $targetClass && $relation['mappedBy']) {
} elseif ($parentClass === $targetClass && ! $relation->isOwningSide()) {
// Special case: bi-directional self-referencing one-one on the same class
$targetClass->reflFields[$relationField]->setValue($element, $parentObject);
}
Expand Down
24 changes: 3 additions & 21 deletions lib/Doctrine/ORM/Mapping/AssociationMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,6 @@
/** @template-implements ArrayAccess<string, mixed> */
abstract class AssociationMapping implements ArrayAccess
{
/**
* required for bidirectional associations
* The name of the field that completes the bidirectional association on
* the owning side. This key must be specified on the inverse side of a
* bidirectional association.
*/
public string|null $mappedBy = null;

/**
* required for bidirectional associations
* The name of the field that completes the bidirectional association on
* the inverse side. This key must be specified on the owning side of a
* bidirectional association.
*/
public string|null $inversedBy = null;

/**
* The names of persistence operations to cascade on the association.
*
Expand Down Expand Up @@ -159,12 +143,12 @@ public static function fromMappingArray(array $mappingArray): static
}

/**
* @psalm-assert-if-true AssociationOwningSideMapping $this
* @psalm-assert-if-false string $this->mappedBy
* @psalm-assert-if-true OwningSideMapping $this
* @psalm-assert-if-false InverseSideMapping $this
*/
final public function isOwningSide(): bool
{
return $this instanceof AssociationOwningSideMapping;
return $this instanceof OwningSideMapping;
}

/** @psalm-assert-if-true ToOneAssociationMapping $this */
Expand Down Expand Up @@ -335,8 +319,6 @@ public function __sleep(): array

foreach (
[
'mappedBy',
'inversedBy',
'fetch',
'inherited',
'declared',
Expand Down
9 changes: 0 additions & 9 deletions lib/Doctrine/ORM/Mapping/AssociationOwningSideMapping.php

This file was deleted.

10 changes: 2 additions & 8 deletions lib/Doctrine/ORM/Mapping/ClassMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -1392,13 +1392,7 @@ protected function _validateAndCompleteAssociationMapping(array $mapping): Assoc
$this->table ?? null,
$this->isInheritanceTypeSingleTable(),
) :
OneToOneAssociationMapping::fromMappingArrayAndName(
$mapping,
$this->namingStrategy,
$this->name,
$this->table,
$this->isInheritanceTypeSingleTable(),
);
OneToOneInverseSideMapping::fromMappingArrayAndName($mapping, $this->name);

case self::MANY_TO_ONE:
return ManyToOneAssociationMapping::fromMappingArrayAndName(
Expand All @@ -1419,7 +1413,7 @@ protected function _validateAndCompleteAssociationMapping(array $mapping): Assoc

return $mapping['isOwningSide'] ?
ManyToManyOwningSideMapping::fromMappingArrayAndNamingStrategy($mapping, $this->namingStrategy) :
ManyToManyAssociationMapping::fromMappingArray($mapping);
ManyToManyInverseSideMapping::fromMappingArray($mapping);

default:
throw MappingException::invalidAssociationType(
Expand Down
30 changes: 30 additions & 0 deletions lib/Doctrine/ORM/Mapping/InverseSideMapping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Mapping;

abstract class InverseSideMapping extends AssociationMapping
{
/**
* required for bidirectional associations
* The name of the field that completes the bidirectional association on
* the owning side. This key must be specified on the inverse side of a
* bidirectional association.
*/
public string $mappedBy;

final public function backRefFieldName(): string
{
return $this->mappedBy;
}

/** @return list<string> */
public function __sleep(): array
{
return [
...parent::__sleep(),
'mappedBy',
];
}
}
2 changes: 1 addition & 1 deletion lib/Doctrine/ORM/Mapping/ManyToManyAssociationMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

namespace Doctrine\ORM\Mapping;

class ManyToManyAssociationMapping extends ToManyAssociationMapping
interface ManyToManyAssociationMapping extends ToManyAssociationMapping
{
}
9 changes: 9 additions & 0 deletions lib/Doctrine/ORM/Mapping/ManyToManyInverseSideMapping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Mapping;

final class ManyToManyInverseSideMapping extends ToManyInverseSideMapping implements ManyToManyAssociationMapping
{
}
2 changes: 1 addition & 1 deletion lib/Doctrine/ORM/Mapping/ManyToManyOwningSideMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use function strtolower;
use function trim;

final class ManyToManyOwningSideMapping extends ManyToManyAssociationMapping implements AssociationOwningSideMapping
final class ManyToManyOwningSideMapping extends ToManyOwningSideMapping implements ManyToManyAssociationMapping
{
/**
* Specification of the join table and its join columns (foreign keys).
Expand Down
22 changes: 1 addition & 21 deletions lib/Doctrine/ORM/Mapping/ManyToOneAssociationMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,6 @@
/**
* The "many" side of a many-to-one association mapping is always the owning side.
*/
final class ManyToOneAssociationMapping extends ToOneAssociationMapping implements AssociationOwningSideMapping
final class ManyToOneAssociationMapping extends ToOneOwningSideMapping
{
/** @var array<string, string> */
public array $sourceToTargetKeyColumns = [];

/** @var array<string, string> */
public array $targetToSourceKeyColumns = [];

/** @var list<JoinColumnMapping> */
public array $joinColumns = [];

/** @return list<string> */
public function __sleep(): array
{
$serialized = parent::__sleep();

$serialized[] = 'joinColumns';
$serialized[] = 'sourceToTargetKeyColumns';
$serialized[] = 'targetToSourceKeyColumns';

return $serialized;
}
}
2 changes: 1 addition & 1 deletion lib/Doctrine/ORM/Mapping/OneToManyAssociationMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Doctrine\ORM\Mapping;

final class OneToManyAssociationMapping extends ToManyAssociationMapping
final class OneToManyAssociationMapping extends ToManyInverseSideMapping
{
/**
* @param mixed[] $mappingArray
Expand Down
2 changes: 1 addition & 1 deletion lib/Doctrine/ORM/Mapping/OneToOneAssociationMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

namespace Doctrine\ORM\Mapping;

class OneToOneAssociationMapping extends ToOneAssociationMapping
interface OneToOneAssociationMapping extends ToOneAssociationMapping
{
}
9 changes: 9 additions & 0 deletions lib/Doctrine/ORM/Mapping/OneToOneInverseSideMapping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Mapping;

final class OneToOneInverseSideMapping extends ToOneInverseSideMapping implements OneToOneAssociationMapping
{
}
22 changes: 1 addition & 21 deletions lib/Doctrine/ORM/Mapping/OneToOneOwningSideMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,6 @@

namespace Doctrine\ORM\Mapping;

final class OneToOneOwningSideMapping extends OneToOneAssociationMapping implements AssociationOwningSideMapping
final class OneToOneOwningSideMapping extends ToOneOwningSideMapping implements OneToOneAssociationMapping
{
/** @var array<string, string> */
public array $sourceToTargetKeyColumns = [];

/** @var array<string, string> */
public array $targetToSourceKeyColumns = [];

/** @var list<JoinColumnMapping> */
public array $joinColumns = [];

/** @return list<string> */
public function __sleep(): array
{
$serialized = parent::__sleep();

$serialized[] = 'joinColumns';
$serialized[] = 'sourceToTargetKeyColumns';
$serialized[] = 'targetToSourceKeyColumns';

return $serialized;
}
}
28 changes: 28 additions & 0 deletions lib/Doctrine/ORM/Mapping/OwningSideMapping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Mapping;

abstract class OwningSideMapping extends AssociationMapping
{
/**
* required for bidirectional associations
* The name of the field that completes the bidirectional association on
* the inverse side. This key must be specified on the owning side of a
* bidirectional association.
*/
public string|null $inversedBy = null;

/** @return list<string> */
public function __sleep(): array
{
$serialized = parent::__sleep();

if ($this->inversedBy !== null) {
$serialized[] = 'inversedBy';
}

return $serialized;
}
}
30 changes: 1 addition & 29 deletions lib/Doctrine/ORM/Mapping/ToManyAssociationMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,6 @@

namespace Doctrine\ORM\Mapping;

abstract class ToManyAssociationMapping extends AssociationMapping
interface ToManyAssociationMapping
{
/**
* Specification of a field on target-entity that is used to index the
* collection by. This field HAS to be either the primary key or a unique
* column. Otherwise the collection does not contain all the entities that
* are actually related.
*/
public string|null $indexBy = null;

/**
* A map of field names (of the target entity) to sorting directions
*
* @var array<string, 'asc'|'desc'>|null
*/
public array|null $orderBy = null;

/** @return list<string> */
public function __sleep(): array
{
$serialized = parent::__sleep();

foreach (['indexBy', 'orderBy'] as $stringOrArrayKey) {
if ($this->$stringOrArrayKey !== null) {
$serialized[] = $stringOrArrayKey;
}
}

return $serialized;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Mapping;

/** @internal */
trait ToManyAssociationMappingImplementation
{
/**
* Specification of a field on target-entity that is used to index the
* collection by. This field HAS to be either the primary key or a unique
* column. Otherwise the collection does not contain all the entities that
* are actually related.
*/
public string|null $indexBy = null;

/**
* A map of field names (of the target entity) to sorting directions
*
* @var array<string, 'asc'|'desc'>|null
*/
public array|null $orderBy = null;

/** @return list<string> */
public function __sleep(): array
{
$serialized = parent::__sleep();

foreach (['indexBy', 'orderBy'] as $stringOrArrayKey) {
if ($this->$stringOrArrayKey !== null) {
$serialized[] = $stringOrArrayKey;
}
}

return $serialized;
}
}
10 changes: 10 additions & 0 deletions lib/Doctrine/ORM/Mapping/ToManyInverseSideMapping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Mapping;

abstract class ToManyInverseSideMapping extends InverseSideMapping implements ToManyAssociationMapping
{
use ToManyAssociationMappingImplementation;
}
10 changes: 10 additions & 0 deletions lib/Doctrine/ORM/Mapping/ToManyOwningSideMapping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Mapping;

abstract class ToManyOwningSideMapping extends OwningSideMapping
{
use ToManyAssociationMappingImplementation;
}
Loading

0 comments on commit e18b80c

Please sign in to comment.