Esempio n. 1
0
 public function testMissingInterfaceName()
 {
     $metadata = new Entity('', '', [], [], [], [], []);
     $this->assertFalse($metadata->hasInterfaceName());
     $this->expectException(InvalidArgumentException::class);
     $metadata->getInterfaceName();
 }
 private function extractWithMetadata($entity, Entity $metadata) : array
 {
     if ($entity instanceof ProxyInterface) {
         $entity = $entity->__getRealEntity();
     }
     Assertion::isInstanceOf($entity, $metadata->getClassName());
     $data = [];
     $reflectionClass = new ReflectionClass($entity);
     foreach ($metadata->getFields() as $fieldMetadata) {
         if ($fieldMetadata->isReadOnly()) {
             continue;
         }
         $fieldName = $fieldMetadata->getFieldName();
         try {
             $type = $fieldMetadata->getType();
             $value = $this->getProperty($reflectionClass, $entity, $fieldMetadata->getPropertyName());
             if (!$fieldMetadata->isRepeatable()) {
                 $data[$fieldName] = $type->toFileMakerValue($value);
                 continue;
             }
             Assertion::isArray($value);
             $index = 0;
             foreach ($value as $individualValue) {
                 $data[sprintf('%s(%d)', $fieldName, ++$index)] = $type->toFileMakerValue($individualValue);
             }
         } catch (Exception $e) {
             throw ExtractionException::fromInvalidField($metadata, $fieldMetadata, $e);
         }
     }
     foreach ($metadata->getEmbeddables() as $embeddableMetadata) {
         $prefix = $embeddableMetadata->getFieldNamePrefix();
         $embeddableData = $this->extractWithMetadata($this->getProperty($reflectionClass, $entity, $embeddableMetadata->getPropertyName()), $embeddableMetadata->getMetadata());
         foreach ($embeddableData as $key => $value) {
             $data[$prefix . $key] = $value;
         }
     }
     $toOne = array_filter($metadata->getManyToOne(), function (ManyToOne $manyToOneMetadata) {
         return !$manyToOneMetadata->isReadOnly();
     }) + array_filter($metadata->getOneToOne(), function (OneToOne $oneToOneMetadata) {
         return $oneToOneMetadata->isOwningSide() && !$oneToOneMetadata->isReadOnly();
     });
     foreach ($toOne as $relationMetadata) {
         $relation = $this->getProperty($reflectionClass, $entity, $relationMetadata->getPropertyName());
         if (null === $relation) {
             $data[$relationMetadata->getFieldName()] = null;
             continue;
         }
         if ($relation instanceof ProxyInterface) {
             Assertion::isInstanceOf($relation->__getRealEntity(), $relationMetadata->getTargetEntity());
             $relationId = $relation->__getRelationId();
         } else {
             Assertion::isInstanceOf($relation, $relationMetadata->getTargetEntity());
             $relationId = $this->getProperty(new ReflectionClass($relation), $relation, $relationMetadata->getTargetPropertyName());
         }
         $data[$relationMetadata->getFieldName()] = $relationId;
     }
     return $data;
 }
 public static function fromInvalidField(Entity $entityMetadata, Field $fieldMetadata, Exception $previousException) : self
 {
     return new self(sprintf('Could not extract field "%s" from entity "%s", reason: %s', $fieldMetadata->getPropertyName(), $entityMetadata->getClassName(), $previousException->getMessage()), 0, $previousException);
 }
 private function hydrateWithMetadata(array $data, $entity, Entity $metadata)
 {
     Assertion::isInstanceOf($entity, $metadata->getClassName());
     $reflectionClass = new ReflectionClass($entity);
     foreach ($metadata->getFields() as $fieldMetadata) {
         try {
             $type = $fieldMetadata->getType();
             $value = $data[$fieldMetadata->getFieldName()];
             if ($fieldMetadata->isRepeatable()) {
                 Assertion::isArray($value);
                 $value = array_map(function ($value) use($type) {
                     return $type->fromFileMakerValue($value);
                 }, $value);
             } else {
                 $value = $type->fromFileMakerValue($value);
             }
             $this->setProperty($reflectionClass, $entity, $fieldMetadata->getPropertyName(), $value);
         } catch (Exception $e) {
             throw HydrationException::fromInvalidField($metadata, $fieldMetadata, $e);
         }
     }
     foreach ($metadata->getEmbeddables() as $embeddableMetadata) {
         $prefix = $embeddableMetadata->getFieldNamePrefix();
         if ('' === $prefix) {
             $embeddableData = $data;
         } else {
             $prefixLength = strlen($prefix);
             foreach ($data as $key => $value) {
                 if (0 !== strpos($key, $prefix)) {
                     continue;
                 }
                 $embeddableData[substr($key, $prefixLength)] = $value;
             }
         }
         $reflectionProperty = $reflectionClass->getProperty($embeddableMetadata->getPropertyName());
         $reflectionProperty->setAccessible(true);
         $embeddable = $reflectionProperty->getValue($entity);
         if (null === $embeddable) {
             $embeddable = (new ReflectionClass($embeddableMetadata->getMetadata()->getClassName()))->newInstanceWithoutConstructor();
         }
         $reflectionProperty->setValue($entity, $this->hydrateWithMetadata($embeddableData, $embeddable, $embeddableMetadata->getMetadata()));
     }
     foreach ($metadata->getOneToMany() as $relationMetadata) {
         $repository = $this->repositoryBuilder->buildRepository($relationMetadata->getTargetEntity());
         if ($relationMetadata->hasEagerHydration()) {
             $items = [];
             foreach ($data[$relationMetadata->getTargetTable()] as $record) {
                 $items[] = $repository->createEntity($record);
             }
             $collection = new ItemCollection($items, count($items));
         } else {
             $collection = new LazyLoadedCollection($repository, $relationMetadata->getTargetFieldName(), $data[$relationMetadata->getTargetTable()]);
         }
         $this->setProperty($reflectionClass, $entity, $relationMetadata->getPropertyName(), $collection);
     }
     $toOne = $metadata->getManyToOne() + $metadata->getOneToOne();
     foreach ($toOne as $relationMetadata) {
         if (empty($data[$relationMetadata->getTargetTable()])) {
             $this->setProperty($reflectionClass, $entity, $relationMetadata->getPropertyName(), null);
             continue;
         }
         $repository = $this->repositoryBuilder->buildRepository($relationMetadata->getTargetEntity());
         if ($relationMetadata->hasEagerHydration()) {
             $this->setProperty($reflectionClass, $entity, $relationMetadata->getPropertyName(), $repository->createEntity($data[$relationMetadata->getTargetTable()][0]));
             continue;
         }
         Assertion::true($metadata->hasInterfaceName(), sprintf('Entity "%s" has no interface name definied', $metadata->getClassName()));
         $fieldName = $relationMetadata->getTargetFieldName();
         $fieldValue = (string) $data[$relationMetadata->getTargetTable()][0][$fieldName];
         $proxy = $this->proxyBuilder->createProxy($relationMetadata->getTargetInterfaceName(), function () use($repository, $fieldName, $fieldValue) {
             return $repository->findOneBy([$fieldName => $repository->quoteString($fieldValue)]);
         }, $fieldValue);
         $this->setProperty($reflectionClass, $entity, $relationMetadata->getPropertyName(), $proxy);
     }
     if ($metadata->hasRecordId()) {
         $recordIdMetadata = $metadata->getRecordId();
         $this->setProperty($reflectionClass, $entity, $recordIdMetadata->getPropertyName(), $data['record-id']);
     }
     return $entity;
 }