diff options
Diffstat (limited to 'vendor/doctrine/orm/src/Utility/IdentifierFlattener.php')
-rw-r--r-- | vendor/doctrine/orm/src/Utility/IdentifierFlattener.php | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/vendor/doctrine/orm/src/Utility/IdentifierFlattener.php b/vendor/doctrine/orm/src/Utility/IdentifierFlattener.php new file mode 100644 index 0000000..3792d33 --- /dev/null +++ b/vendor/doctrine/orm/src/Utility/IdentifierFlattener.php | |||
@@ -0,0 +1,83 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Utility; | ||
6 | |||
7 | use BackedEnum; | ||
8 | use Doctrine\ORM\Mapping\ClassMetadata; | ||
9 | use Doctrine\ORM\UnitOfWork; | ||
10 | use Doctrine\Persistence\Mapping\ClassMetadataFactory; | ||
11 | |||
12 | use function assert; | ||
13 | use function implode; | ||
14 | use function is_a; | ||
15 | |||
16 | /** | ||
17 | * The IdentifierFlattener utility now houses some of the identifier manipulation logic from unit of work, so that it | ||
18 | * can be re-used elsewhere. | ||
19 | */ | ||
20 | final class IdentifierFlattener | ||
21 | { | ||
22 | /** | ||
23 | * Initializes a new IdentifierFlattener instance, bound to the given EntityManager. | ||
24 | */ | ||
25 | public function __construct( | ||
26 | /** | ||
27 | * The UnitOfWork used to coordinate object-level transactions. | ||
28 | */ | ||
29 | private readonly UnitOfWork $unitOfWork, | ||
30 | /** | ||
31 | * The metadata factory, used to retrieve the ORM metadata of entity classes. | ||
32 | */ | ||
33 | private readonly ClassMetadataFactory $metadataFactory, | ||
34 | ) { | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * convert foreign identifiers into scalar foreign key values to avoid object to string conversion failures. | ||
39 | * | ||
40 | * @param mixed[] $id | ||
41 | * | ||
42 | * @return mixed[] | ||
43 | * @psalm-return array<string, mixed> | ||
44 | */ | ||
45 | public function flattenIdentifier(ClassMetadata $class, array $id): array | ||
46 | { | ||
47 | $flatId = []; | ||
48 | |||
49 | foreach ($class->identifier as $field) { | ||
50 | if (isset($class->associationMappings[$field]) && isset($id[$field]) && is_a($id[$field], $class->associationMappings[$field]->targetEntity)) { | ||
51 | $targetClassMetadata = $this->metadataFactory->getMetadataFor( | ||
52 | $class->associationMappings[$field]->targetEntity, | ||
53 | ); | ||
54 | assert($targetClassMetadata instanceof ClassMetadata); | ||
55 | |||
56 | if ($this->unitOfWork->isInIdentityMap($id[$field])) { | ||
57 | $associatedId = $this->flattenIdentifier($targetClassMetadata, $this->unitOfWork->getEntityIdentifier($id[$field])); | ||
58 | } else { | ||
59 | $associatedId = $this->flattenIdentifier($targetClassMetadata, $targetClassMetadata->getIdentifierValues($id[$field])); | ||
60 | } | ||
61 | |||
62 | $flatId[$field] = implode(' ', $associatedId); | ||
63 | } elseif (isset($class->associationMappings[$field])) { | ||
64 | assert($class->associationMappings[$field]->isToOneOwningSide()); | ||
65 | $associatedId = []; | ||
66 | |||
67 | foreach ($class->associationMappings[$field]->joinColumns as $joinColumn) { | ||
68 | $associatedId[] = $id[$joinColumn->name]; | ||
69 | } | ||
70 | |||
71 | $flatId[$field] = implode(' ', $associatedId); | ||
72 | } else { | ||
73 | if ($id[$field] instanceof BackedEnum) { | ||
74 | $flatId[$field] = $id[$field]->value; | ||
75 | } else { | ||
76 | $flatId[$field] = $id[$field]; | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | |||
81 | return $flatId; | ||
82 | } | ||
83 | } | ||