Exception
9 months ago
Logging
9 months ago
Persister
9 months ago
Region
9 months ago
AssociationCacheEntry.php
9 months ago
CacheConfiguration.php
9 months ago
CacheEntry.php
9 months ago
CacheException.php
9 months ago
CacheFactory.php
9 months ago
CacheKey.php
9 months ago
CollectionCacheEntry.php
9 months ago
CollectionCacheKey.php
9 months ago
CollectionHydrator.php
9 months ago
ConcurrentRegion.php
9 months ago
DefaultCache.php
9 months ago
DefaultCacheFactory.php
9 months ago
DefaultCollectionHydrator.php
9 months ago
DefaultEntityHydrator.php
9 months ago
DefaultQueryCache.php
9 months ago
EntityCacheEntry.php
9 months ago
EntityCacheKey.php
9 months ago
EntityHydrator.php
9 months ago
Lock.php
9 months ago
LockException.php
9 months ago
MultiGetRegion.php
9 months ago
QueryCache.php
9 months ago
QueryCacheEntry.php
9 months ago
QueryCacheKey.php
9 months ago
QueryCacheValidator.php
9 months ago
Region.php
9 months ago
RegionsConfiguration.php
9 months ago
TimestampCacheEntry.php
9 months ago
TimestampCacheKey.php
9 months ago
TimestampQueryCacheValidator.php
9 months ago
TimestampRegion.php
9 months ago
index.php
9 months ago
DefaultEntityHydrator.php
128 lines
| 1 | <?php |
| 2 | declare (strict_types=1); |
| 3 | namespace MailPoetVendor\Doctrine\ORM\Cache; |
| 4 | if (!defined('ABSPATH')) exit; |
| 5 | use MailPoetVendor\Doctrine\ORM\EntityManagerInterface; |
| 6 | use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadata; |
| 7 | use MailPoetVendor\Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; |
| 8 | use MailPoetVendor\Doctrine\ORM\Query; |
| 9 | use MailPoetVendor\Doctrine\ORM\UnitOfWork; |
| 10 | use MailPoetVendor\Doctrine\ORM\Utility\IdentifierFlattener; |
| 11 | use function array_merge; |
| 12 | use function assert; |
| 13 | use function is_array; |
| 14 | use function is_object; |
| 15 | use function reset; |
| 16 | class DefaultEntityHydrator implements EntityHydrator |
| 17 | { |
| 18 | private $em; |
| 19 | private $uow; |
| 20 | private $identifierFlattener; |
| 21 | private static $hints = [Query::HINT_CACHE_ENABLED => \true]; |
| 22 | public function __construct(EntityManagerInterface $em) |
| 23 | { |
| 24 | $this->em = $em; |
| 25 | $this->uow = $em->getUnitOfWork(); |
| 26 | $this->identifierFlattener = new IdentifierFlattener($em->getUnitOfWork(), $em->getMetadataFactory()); |
| 27 | } |
| 28 | public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $entity) |
| 29 | { |
| 30 | $data = $this->uow->getOriginalEntityData($entity); |
| 31 | $data = array_merge($data, $metadata->getIdentifierValues($entity)); |
| 32 | // why update has no identifier values ? |
| 33 | if ($metadata->requiresFetchAfterChange) { |
| 34 | if ($metadata->isVersioned) { |
| 35 | assert($metadata->versionField !== null); |
| 36 | $data[$metadata->versionField] = $metadata->getFieldValue($entity, $metadata->versionField); |
| 37 | } |
| 38 | foreach ($metadata->fieldMappings as $name => $fieldMapping) { |
| 39 | if (isset($fieldMapping['generated'])) { |
| 40 | $data[$name] = $metadata->getFieldValue($entity, $name); |
| 41 | } |
| 42 | } |
| 43 | } |
| 44 | foreach ($metadata->associationMappings as $name => $assoc) { |
| 45 | if (!isset($data[$name])) { |
| 46 | continue; |
| 47 | } |
| 48 | if (!($assoc['type'] & ClassMetadata::TO_ONE)) { |
| 49 | unset($data[$name]); |
| 50 | continue; |
| 51 | } |
| 52 | if (!isset($assoc['cache'])) { |
| 53 | $targetClassMetadata = $this->em->getClassMetadata($assoc['targetEntity']); |
| 54 | $owningAssociation = !$assoc['isOwningSide'] ? $targetClassMetadata->associationMappings[$assoc['mappedBy']] : $assoc; |
| 55 | $associationIds = $this->identifierFlattener->flattenIdentifier($targetClassMetadata, $targetClassMetadata->getIdentifierValues($data[$name])); |
| 56 | unset($data[$name]); |
| 57 | foreach ($associationIds as $fieldName => $fieldValue) { |
| 58 | if (isset($targetClassMetadata->fieldMappings[$fieldName])) { |
| 59 | $fieldMapping = $targetClassMetadata->fieldMappings[$fieldName]; |
| 60 | $data[$owningAssociation['targetToSourceKeyColumns'][$fieldMapping['columnName']]] = $fieldValue; |
| 61 | continue; |
| 62 | } |
| 63 | $targetAssoc = $targetClassMetadata->associationMappings[$fieldName]; |
| 64 | foreach ($assoc['targetToSourceKeyColumns'] as $referencedColumn => $localColumn) { |
| 65 | if (isset($targetAssoc['sourceToTargetKeyColumns'][$referencedColumn])) { |
| 66 | $data[$localColumn] = $fieldValue; |
| 67 | } |
| 68 | } |
| 69 | } |
| 70 | continue; |
| 71 | } |
| 72 | if (!isset($assoc['id'])) { |
| 73 | $targetClass = DefaultProxyClassNameResolver::getClass($data[$name]); |
| 74 | $targetId = $this->uow->getEntityIdentifier($data[$name]); |
| 75 | $data[$name] = new AssociationCacheEntry($targetClass, $targetId); |
| 76 | continue; |
| 77 | } |
| 78 | // handle association identifier |
| 79 | $targetId = is_object($data[$name]) && $this->uow->isInIdentityMap($data[$name]) ? $this->uow->getEntityIdentifier($data[$name]) : $data[$name]; |
| 80 | // @TODO - fix it ! |
| 81 | // handle UnitOfWork#createEntity hash generation |
| 82 | if (!is_array($targetId)) { |
| 83 | $data[reset($assoc['joinColumnFieldNames'])] = $targetId; |
| 84 | $targetEntity = $this->em->getClassMetadata($assoc['targetEntity']); |
| 85 | $targetId = [$targetEntity->identifier[0] => $targetId]; |
| 86 | } |
| 87 | $data[$name] = new AssociationCacheEntry($assoc['targetEntity'], $targetId); |
| 88 | } |
| 89 | return new EntityCacheEntry($metadata->name, $data); |
| 90 | } |
| 91 | public function loadCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, EntityCacheEntry $entry, $entity = null) |
| 92 | { |
| 93 | $data = $entry->data; |
| 94 | $hints = self::$hints; |
| 95 | if ($entity !== null) { |
| 96 | $hints[Query::HINT_REFRESH] = \true; |
| 97 | $hints[Query::HINT_REFRESH_ENTITY] = $entity; |
| 98 | } |
| 99 | foreach ($metadata->associationMappings as $name => $assoc) { |
| 100 | if (!isset($assoc['cache']) || !isset($data[$name])) { |
| 101 | continue; |
| 102 | } |
| 103 | $assocClass = $data[$name]->class; |
| 104 | $assocId = $data[$name]->identifier; |
| 105 | $isEagerLoad = $assoc['fetch'] === ClassMetadata::FETCH_EAGER || $assoc['type'] === ClassMetadata::ONE_TO_ONE && !$assoc['isOwningSide']; |
| 106 | if (!$isEagerLoad) { |
| 107 | $data[$name] = $this->em->getReference($assocClass, $assocId); |
| 108 | continue; |
| 109 | } |
| 110 | $assocMetadata = $this->em->getClassMetadata($assoc['targetEntity']); |
| 111 | $assocKey = new EntityCacheKey($assocMetadata->rootEntityName, $assocId); |
| 112 | $assocPersister = $this->uow->getEntityPersister($assoc['targetEntity']); |
| 113 | $assocRegion = $assocPersister->getCacheRegion(); |
| 114 | $assocEntry = $assocRegion->get($assocKey); |
| 115 | if ($assocEntry === null) { |
| 116 | return null; |
| 117 | } |
| 118 | $data[$name] = $this->uow->createEntity($assocEntry->class, $assocEntry->resolveAssociationEntries($this->em), $hints); |
| 119 | } |
| 120 | if ($entity !== null) { |
| 121 | $this->uow->registerManaged($entity, $key->identifier, $data); |
| 122 | } |
| 123 | $result = $this->uow->createEntity($entry->class, $data, $hints); |
| 124 | $this->uow->hydrationComplete(); |
| 125 | return $result; |
| 126 | } |
| 127 | } |
| 128 |