/**
  * @param array  $definition
  * @param string $entityClass
  *
  * @return bool
  */
 protected function updateRelations(array &$definition, $entityClass)
 {
     $hasChanges = false;
     $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
     foreach ($definition[ConfigUtil::FIELDS] as $fieldName => &$fieldConfig) {
         if (!is_array($fieldConfig) || empty($fieldConfig[ConfigUtil::DEFINITION][ConfigUtil::FIELDS])) {
             continue;
         }
         $fieldDefinition = $fieldConfig[ConfigUtil::DEFINITION];
         if (ConfigUtil::isExclude($fieldDefinition)) {
             continue;
         }
         $propertyPath = ConfigUtil::getPropertyPath($fieldDefinition, $fieldName);
         if (!$metadata->hasAssociation($propertyPath)) {
             continue;
         }
         $mapping = $metadata->getAssociationMapping($propertyPath);
         $targetMetadata = $this->doctrineHelper->getEntityMetadataForClass($mapping['targetEntity']);
         if ($this->isResourceForRelatedEntityAccessible($targetMetadata)) {
             continue;
         }
         $fieldDefinition[ConfigUtil::EXCLUDE] = true;
         $fieldConfig[ConfigUtil::DEFINITION] = $fieldDefinition;
         $hasChanges = true;
     }
     return $hasChanges;
 }
 /**
  * {@inheritdoc}
  */
 public function process(ContextInterface $context)
 {
     /** @var MetadataContext $context */
     if ($context->hasResult()) {
         // metadata is already loaded
         return;
     }
     $entityClass = $context->getClassName();
     if (!$this->doctrineHelper->isManageableEntityClass($entityClass)) {
         // only manageable entities are supported
         return;
     }
     // filter excluded fields on this stage though there is another processor doing the same
     // it is done due to performance reasons
     $allowedFields = $this->getAllowedFields($context->getConfig());
     $classMetadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
     $entityMetadata = $this->entityMetadataFactory->createEntityMetadata($classMetadata);
     $fields = $classMetadata->getFieldNames();
     foreach ($fields as $fieldName) {
         if (!isset($allowedFields[$fieldName])) {
             continue;
         }
         $entityMetadata->addField($this->entityMetadataFactory->createFieldMetadata($classMetadata, $fieldName));
     }
     $associations = $classMetadata->getAssociationNames();
     foreach ($associations as $associationName) {
         if (!isset($allowedFields[$associationName])) {
             continue;
         }
         $entityMetadata->addAssociation($this->entityMetadataFactory->createAssociationMetadata($classMetadata, $associationName));
     }
     $context->setResult($entityMetadata);
 }
 /**
  * @param array    $definition
  * @param string   $entityClass
  * @param string   $version
  * @param string[] $requestType
  * @param array    $extras
  *
  * @return array
  */
 protected function completeDefinition(array $definition, $entityClass, $version, array $requestType, array $extras)
 {
     $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
     $definition = $this->getFields($definition, $metadata, $version, $requestType, $extras);
     $definition = $this->getAssociations($definition, $metadata, $version, $requestType, $extras);
     return $definition;
 }
 /**
  * @param array  $definition
  * @param string $entityClass
  *
  * @return bool
  */
 protected function updateRelations(array &$definition, $entityClass)
 {
     $hasChanges = false;
     $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
     foreach ($definition[ConfigUtil::FIELDS] as $fieldName => &$fieldConfig) {
         if (!is_array($fieldConfig) || empty($fieldConfig[ConfigUtil::DEFINITION][ConfigUtil::FIELDS])) {
             continue;
         }
         $fieldDefinition = $fieldConfig[ConfigUtil::DEFINITION];
         $propertyPath = ConfigUtil::getPropertyPath($fieldDefinition, $fieldName);
         if (!$metadata->hasAssociation($propertyPath)) {
             continue;
         }
         $mapping = $metadata->getAssociationMapping($propertyPath);
         $targetMetadata = $this->doctrineHelper->getEntityMetadataForClass($mapping['targetEntity']);
         if ($targetMetadata->inheritanceType === ClassMetadata::INHERITANCE_TYPE_NONE) {
             continue;
         }
         if (!is_array($fieldDefinition[ConfigUtil::FIELDS])) {
             $fieldDefinition[ConfigUtil::FIELDS] = [$fieldDefinition[ConfigUtil::FIELDS] => null];
         }
         $fieldDefinition[ConfigUtil::FIELDS][ConfigUtil::CLASS_NAME] = null;
         $fieldConfig[ConfigUtil::DEFINITION] = $fieldDefinition;
         $hasChanges = true;
     }
     return $hasChanges;
 }
Exemple #5
0
 /**
  * Checks whether the given field is an identifier of the given entity
  *
  * @param string $entityClass
  * @param string $fieldName
  *
  * @return bool
  */
 protected function isIdentifierField($entityClass, $fieldName)
 {
     $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass, false);
     if (null === $metadata) {
         return false;
     }
     $idFieldNames = $metadata->getIdentifierFieldNames();
     return count($idFieldNames) === 1 && reset($idFieldNames) === $fieldName;
 }
 /**
  * {@inheritdoc}
  */
 public function reverseTransform($entityClass, $value)
 {
     if ($this->doctrineHelper->isManageableEntityClass($entityClass)) {
         $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
         $idFields = $metadata->getIdentifierFieldNames();
         $value = count($idFields) === 1 ? $this->reverseTransformSingleId($value, $metadata->getTypeOfField(reset($idFields))) : $this->reverseTransformCombinedEntityId($value, $idFields, $metadata);
     }
     return $value;
 }
 /**
  * @param array         $definition
  * @param ConfigContext $context
  */
 protected function setCustomizationHandler(array &$definition, ConfigContext $context)
 {
     $entityClass = $context->getClassName();
     $definition[ConfigUtil::POST_SERIALIZE] = $this->getRootCustomizationHandler($context, $entityClass, isset($definition[ConfigUtil::POST_SERIALIZE]) ? $definition[ConfigUtil::POST_SERIALIZE] : null);
     if (!$this->doctrineHelper->isManageableEntityClass($entityClass)) {
         // we can set customization handlers for associations only for manageable entity,
         // because for other types of entities we do not have metadata
         return;
     }
     if (isset($definition[ConfigUtil::FIELDS]) && is_array($definition[ConfigUtil::FIELDS])) {
         $this->processFields($context, $definition[ConfigUtil::FIELDS], $entityClass, $this->doctrineHelper->getEntityMetadataForClass($entityClass));
     }
 }
Exemple #8
0
 /**
  * @param array      $filters
  * @param string     $entityClass
  * @param array|null $config
  *
  * @return array
  */
 protected function completeFilters(array $filters, $entityClass, $config)
 {
     $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
     $filters = $this->getFieldFilters($filters, $metadata);
     $filters = $this->getAssociationFilters($filters, $metadata);
     if (!empty($config)) {
         foreach ($filters as $fieldName => &$fieldConfig) {
             if (ConfigUtil::isExcludedField($config, $fieldName)) {
                 $fieldConfig[ConfigUtil::EXCLUDE] = true;
             }
         }
     }
     return $filters;
 }
 /**
  * @param ClassMetadata $classMetadata
  * @param string        $associationName
  *
  * @return AssociationMetadata
  */
 public function createAssociationMetadata(ClassMetadata $classMetadata, $associationName)
 {
     $targetClass = $classMetadata->getAssociationTargetClass($associationName);
     $associationMetadata = new AssociationMetadata();
     $associationMetadata->setName($associationName);
     $associationMetadata->setTargetClassName($targetClass);
     $associationMetadata->setIsCollection($classMetadata->isCollectionValuedAssociation($associationName));
     $targetMetadata = $this->doctrineHelper->getEntityMetadataForClass($targetClass);
     $targetIdFields = $targetMetadata->getIdentifierFieldNames();
     if (count($targetIdFields) === 1) {
         $associationMetadata->setDataType($targetMetadata->getTypeOfField(reset($targetIdFields)));
     } else {
         $associationMetadata->setDataType(DataType::STRING);
     }
     return $associationMetadata;
 }
Exemple #10
0
 /**
  * @param ApiDoc $annotation
  * @param string $entityClass
  * @param string $requirement
  */
 protected function addIdRequirement(ApiDoc $annotation, $entityClass, $requirement)
 {
     $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
     $idFields = $metadata->getIdentifierFieldNames();
     $dataType = count($idFields) === 1 ? $metadata->getTypeOfField(reset($idFields)) : DataType::STRING;
     $annotation->addRequirement(RestRouteOptionsResolver::ID_ATTRIBUTE, ['dataType' => ApiDocDataTypeConverter::convertToApiDocDataType($dataType), 'requirement' => $requirement, 'description' => self::ID_DESCRIPTION]);
 }
Exemple #11
0
 /**
  * @param array      $sorters
  * @param string     $entityClass
  * @param array|null $config
  *
  * @return array
  */
 protected function completeSorters(array $sorters, $entityClass, $config)
 {
     $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
     $fields = array_merge(array_keys($this->doctrineHelper->getIndexedFields($metadata)), array_keys($this->doctrineHelper->getIndexedAssociations($metadata)));
     foreach ($fields as $fieldName) {
         if (array_key_exists($fieldName, $sorters)) {
             // already defined
             continue;
         }
         $sorters[$fieldName] = null;
     }
     if (!empty($config)) {
         foreach ($sorters as $fieldName => &$fieldConfig) {
             if (ConfigUtil::isExcludedField($config, $fieldName)) {
                 $fieldConfig[ConfigUtil::EXCLUDE] = true;
             }
         }
     }
     return $sorters;
 }
 /**
  * @param ClassMetadata $classMetadata
  * @param string        $associationName
  *
  * @return AssociationMetadata
  */
 public function createAssociationMetadata(ClassMetadata $classMetadata, $associationName)
 {
     $targetClass = $classMetadata->getAssociationTargetClass($associationName);
     $associationMetadata = new AssociationMetadata();
     $associationMetadata->setName($associationName);
     $associationMetadata->setTargetClassName($targetClass);
     $associationMetadata->setIsCollection($classMetadata->isCollectionValuedAssociation($associationName));
     $targetMetadata = $this->doctrineHelper->getEntityMetadataForClass($targetClass);
     $targetIdFields = $targetMetadata->getIdentifierFieldNames();
     if (count($targetIdFields) === 1) {
         $associationMetadata->setDataType($targetMetadata->getTypeOfField(reset($targetIdFields)));
     } else {
         $associationMetadata->setDataType(DataType::STRING);
     }
     if ($targetMetadata->inheritanceType !== ClassMetadata::INHERITANCE_TYPE_NONE) {
         $associationMetadata->setAcceptableTargetClassNames($targetMetadata->subClasses);
     } else {
         $associationMetadata->addAcceptableTargetClassName($targetClass);
     }
     return $associationMetadata;
 }
 /**
  * @param array  $definition
  * @param string $entityClass
  * @param int    $limit
  */
 protected function setLimits(array &$definition, $entityClass, $limit)
 {
     if (isset($definition[ConfigUtil::FIELDS]) && is_array($definition[ConfigUtil::FIELDS])) {
         $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
         foreach ($definition[ConfigUtil::FIELDS] as $fieldName => &$fieldConfig) {
             if (is_array($fieldConfig)) {
                 $propertyPath = ConfigUtil::getPropertyPath($fieldConfig, $fieldName);
                 $path = ConfigUtil::explodePropertyPath($propertyPath);
                 if (count($path) === 1) {
                     $this->setFieldLimit($fieldConfig, $metadata, $propertyPath, $limit);
                 } else {
                     $linkedField = array_pop($path);
                     $linkedMetadata = $this->doctrineHelper->findEntityMetadataByPath($entityClass, $path);
                     if (null !== $linkedMetadata) {
                         $this->setFieldLimit($fieldConfig, $linkedMetadata, $linkedField, $limit);
                     }
                 }
             }
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function process(ContextInterface $context)
 {
     /** @var MetadataContext $context */
     if ($context->hasResult()) {
         // metadata is already loaded
         return;
     }
     $entityClass = $context->getClassName();
     if (!$this->doctrineHelper->isManageableEntityClass($entityClass)) {
         // only manageable entities are supported
         return;
     }
     $classMetadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
     $entityMetadata = $this->entityMetadataFactory->createEntityMetadata($classMetadata);
     $fields = $classMetadata->getFieldNames();
     foreach ($fields as $fieldName) {
         $entityMetadata->addField($this->entityMetadataFactory->createFieldMetadata($classMetadata, $fieldName));
     }
     $associations = $classMetadata->getAssociationNames();
     foreach ($associations as $associationName) {
         $entityMetadata->addAssociation($this->entityMetadataFactory->createAssociationMetadata($classMetadata, $associationName));
     }
     $context->setResult($entityMetadata);
 }
 /**
  * @param Route  $route
  * @param string $entityClass
  */
 protected function setIdRequirement(Route $route, $entityClass)
 {
     $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);
     $idFields = $metadata->getIdentifierFieldNames();
     $idFieldCount = count($idFields);
     if ($idFieldCount === 1) {
         // single identifier
         $route->setRequirement(self::ID_ATTRIBUTE, $this->valueNormalizer->getRequirement($metadata->getTypeOfField(reset($idFields)), [RequestType::REST, RequestType::JSON_API]));
     } elseif ($idFieldCount > 1) {
         // combined identifier
         $requirements = [];
         foreach ($idFields as $field) {
             $requirements[] = $field . '=' . $this->valueNormalizer->getRequirement($metadata->getTypeOfField($field), [RequestType::REST, RequestType::JSON_API]);
         }
         $route->setRequirement(self::ID_ATTRIBUTE, implode(RestRequest::ARRAY_DELIMITER, $requirements));
     }
 }