/**
  * {@inheritdoc}
  */
 public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $entity)
 {
     $data = $this->uow->getOriginalEntityData($entity);
     $data = array_merge($data, $metadata->getIdentifierValues($entity));
     // why update has no identifier values ?
     foreach ($metadata->associationMappings as $name => $assoc) {
         if (!isset($data[$name])) {
             continue;
         }
         if (!($assoc['type'] & ClassMetadata::TO_ONE)) {
             unset($data[$name]);
             continue;
         }
         if (!isset($assoc['cache'])) {
             $targetClassMetadata = $this->em->getClassMetadata($assoc['targetEntity']);
             $owningAssociation = !$assoc['isOwningSide'] ? $targetClassMetadata->associationMappings[$assoc['mappedBy']] : $assoc;
             $associationIds = $this->identifierFlattener->flattenIdentifier($targetClassMetadata, $targetClassMetadata->getIdentifierValues($data[$name]));
             unset($data[$name]);
             foreach ($associationIds as $fieldName => $fieldValue) {
                 if (isset($targetClassMetadata->fieldMappings[$fieldName])) {
                     $fieldMapping = $targetClassMetadata->fieldMappings[$fieldName];
                     $data[$owningAssociation['targetToSourceKeyColumns'][$fieldMapping['columnName']]] = $fieldValue;
                     continue;
                 }
                 $targetAssoc = $targetClassMetadata->associationMappings[$fieldName];
                 foreach ($assoc['targetToSourceKeyColumns'] as $referencedColumn => $localColumn) {
                     if (isset($targetAssoc['sourceToTargetKeyColumns'][$referencedColumn])) {
                         $data[$localColumn] = $fieldValue;
                     }
                 }
             }
             continue;
         }
         if (!isset($assoc['id'])) {
             $targetClass = ClassUtils::getClass($data[$name]);
             $targetId = $this->uow->getEntityIdentifier($data[$name]);
             $data[$name] = new AssociationCacheEntry($targetClass, $targetId);
             continue;
         }
         // handle association identifier
         $targetId = is_object($data[$name]) && $this->uow->isInIdentityMap($data[$name]) ? $this->uow->getEntityIdentifier($data[$name]) : $data[$name];
         // @TODO - fix it !
         // handle UnitOfWork#createEntity hash generation
         if (!is_array($targetId)) {
             $data[reset($assoc['joinColumnFieldNames'])] = $targetId;
             $targetEntity = $this->em->getClassMetadata($assoc['targetEntity']);
             $targetId = [$targetEntity->identifier[0] => $targetId];
         }
         $data[$name] = new AssociationCacheEntry($assoc['targetEntity'], $targetId);
     }
     return new EntityCacheEntry($metadata->name, $data);
 }
 /**
  * @group utilities
  */
 public function testFlattenIdentifierWithMutlipleIds()
 {
     $leeds = new City('Leeds');
     $london = new City('London');
     $this->_em->persist($leeds);
     $this->_em->persist($london);
     $this->_em->flush();
     $flight = new Flight($leeds, $london);
     $this->_em->persist($flight);
     $this->_em->flush();
     $class = $this->_em->getClassMetadata('Doctrine\\Tests\\Models\\Cache\\Flight');
     $id = $class->getIdentifierValues($flight);
     $this->assertCount(2, $id);
     $this->assertArrayHasKey('leavingFrom', $id);
     $this->assertArrayHasKey('goingTo', $id);
     $this->assertEquals($leeds, $id['leavingFrom']);
     $this->assertEquals($london, $id['goingTo']);
     $flatIds = $this->identifierFlattener->flattenIdentifier($class, $id);
     $this->assertCount(2, $flatIds);
     $this->assertArrayHasKey('leavingFrom', $flatIds);
     $this->assertArrayHasKey('goingTo', $flatIds);
     $this->assertEquals($id['leavingFrom']->getId(), $flatIds['leavingFrom']);
     $this->assertEquals($id['goingTo']->getId(), $flatIds['goingTo']);
 }
Exemplo n.º 3
0
 /**
  * Creates a closure capable of finalizing state a cloned proxy
  *
  * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $classMetadata
  * @param \Doctrine\ORM\Persisters\Entity\EntityPersister    $entityPersister
  *
  * @return \Closure
  *
  * @throws \Doctrine\ORM\EntityNotFoundException
  */
 private function createCloner(ClassMetadata $classMetadata, EntityPersister $entityPersister)
 {
     return function (BaseProxy $proxy) use($entityPersister, $classMetadata) {
         if ($proxy->__isInitialized()) {
             return;
         }
         $proxy->__setInitialized(true);
         $proxy->__setInitializer(null);
         $class = $entityPersister->getClassMetadata();
         $identifier = $classMetadata->getIdentifierValues($proxy);
         $original = $entityPersister->loadById($identifier);
         if (null === $original) {
             throw EntityNotFoundException::fromClassNameAndIdentifier($classMetadata->getName(), $this->identifierFlattener->flattenIdentifier($classMetadata, $identifier));
         }
         foreach ($class->getReflectionClass()->getProperties() as $property) {
             if (!$class->hasField($property->name) && !$class->hasAssociation($property->name)) {
                 continue;
             }
             $property->setAccessible(true);
             $property->setValue($proxy, $property->getValue($original));
         }
     };
 }
Exemplo n.º 4
0
 /**
  * Verifies if two given entities actually are the same based on identifier comparison
  *
  * @param object $entity1
  * @param object $entity2
  *
  * @return bool
  */
 private function isIdentifierEquals($entity1, $entity2)
 {
     if ($entity1 === $entity2) {
         return true;
     }
     $class = $this->em->getClassMetadata(get_class($entity1));
     if ($class !== $this->em->getClassMetadata(get_class($entity2))) {
         return false;
     }
     $oid1 = spl_object_hash($entity1);
     $oid2 = spl_object_hash($entity2);
     $id1 = isset($this->entityIdentifiers[$oid1]) ? $this->entityIdentifiers[$oid1] : $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($entity1));
     $id2 = isset($this->entityIdentifiers[$oid2]) ? $this->entityIdentifiers[$oid2] : $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($entity2));
     return $id1 === $id2 || implode(' ', $id1) === implode(' ', $id2);
 }
 /**
  * Fetches the current version value of a versioned entity.
  *
  * @param \Doctrine\ORM\Mapping\ClassMetadata $versionedClass
  * @param array                               $id
  *
  * @return mixed
  */
 protected function fetchVersionValue($versionedClass, array $id)
 {
     $versionField = $versionedClass->versionField;
     $tableName = $this->quoteStrategy->getTableName($versionedClass, $this->platform);
     $identifier = $this->quoteStrategy->getIdentifierColumnNames($versionedClass, $this->platform);
     $columnName = $this->quoteStrategy->getColumnName($versionField, $versionedClass, $this->platform);
     // FIXME: Order with composite keys might not be correct
     $sql = 'SELECT ' . $columnName . ' FROM ' . $tableName . ' WHERE ' . implode(' = ? AND ', $identifier) . ' = ?';
     $flatId = $this->identifierFlattener->flattenIdentifier($versionedClass, $id);
     $value = $this->conn->fetchColumn($sql, array_values($flatId));
     return Type::getType($versionedClass->fieldMappings[$versionField]['type'])->convertToPHPValue($value, $this->platform);
 }