public function loadMetadataForClass($className, ClassMetadata $metadata)
{
/**
* This is the actual type we have at this point, but we cannot change the
* signature due to inheritance.
*
* @var ORM\ClassMetadata $metadata
*/
$class = $metadata->getReflectionClass();
$classSchema = $this->getClassSchema($class->getName());
$classAnnotations = $this->reader->getClassAnnotations($class);
// Evaluate Entity annotation
if (isset($classAnnotations[ORM\MappedSuperclass::class])) {
$mappedSuperclassAnnotation = $classAnnotations[ORM\MappedSuperclass::class];
if ($mappedSuperclassAnnotation->repositoryClass !== null) {
$metadata->setCustomRepositoryClass($mappedSuperclassAnnotation->repositoryClass);
}
$metadata->isMappedSuperclass = true;
} elseif (isset($classAnnotations[Flow\Entity::class]) || isset($classAnnotations[ORM\Entity::class])) {
$entityAnnotation = isset($classAnnotations[Flow\Entity::class]) ? $classAnnotations[Flow\Entity::class] : $classAnnotations[ORM\Entity::class];
if ($entityAnnotation->repositoryClass !== null) {
$metadata->setCustomRepositoryClass($entityAnnotation->repositoryClass);
} elseif ($classSchema->getRepositoryClassName() !== null) {
if ($this->reflectionService->isClassImplementationOf($classSchema->getRepositoryClassName(), \Doctrine\ORM\EntityRepository::class)) {
$metadata->setCustomRepositoryClass($classSchema->getRepositoryClassName());
}
}
if ($entityAnnotation->readOnly) {
$metadata->markReadOnly();
}
} elseif (isset($classAnnotations[Flow\ValueObject::class])) {
$valueObjectAnnotation = $classAnnotations[Flow\ValueObject::class];
if ($valueObjectAnnotation->embedded === true) {
$metadata->isEmbeddedClass = true;
} else {
// also ok... but we make it read-only
$metadata->markReadOnly();
}
} elseif (isset($classAnnotations[ORM\Embeddable::class])) {
$metadata->isEmbeddedClass = true;
} else {
throw ORM\MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
}
// Evaluate Table annotation
$primaryTable = [];
if (isset($classAnnotations[ORM\Table::class])) {
$tableAnnotation = $classAnnotations[ORM\Table::class];
$primaryTable = ['name' => $tableAnnotation->name, 'schema' => $tableAnnotation->schema];
if ($tableAnnotation->indexes !== null) {
foreach ($tableAnnotation->indexes as $indexAnnotation) {
$index = ['columns' => $indexAnnotation->columns];
if (!empty($indexAnnotation->flags)) {
$index['flags'] = $indexAnnotation->flags;
}
if (!empty($indexAnnotation->options)) {
$index['options'] = $indexAnnotation->flags;
}
if (!empty($indexAnnotation->name)) {
$primaryTable['indexes'][$indexAnnotation->name] = $index;
} else {
$primaryTable['indexes'][] = $index;
}
}
}
if ($tableAnnotation->uniqueConstraints !== null) {
foreach ($tableAnnotation->uniqueConstraints as $uniqueConstraint) {
$uniqueConstraint = ['columns' => $uniqueConstraint->columns];
if (!empty($uniqueConstraint->options)) {
$uniqueConstraint['options'] = $uniqueConstraint->options;
}
if (!empty($uniqueConstraint->name)) {
$primaryTable['uniqueConstraints'][$uniqueConstraint->name] = $uniqueConstraint;
} else {
$primaryTable['uniqueConstraints'][] = $uniqueConstraint;
}
}
}
if ($tableAnnotation->options !== null) {
$primaryTable['options'] = $tableAnnotation->options;
}
}
if (!isset($classAnnotations[ORM\Embeddable::class]) && !isset($primaryTable['name'])) {
$className = $classSchema->getClassName();
$primaryTable['name'] = $this->inferTableNameFromClassName($className);
}
// Evaluate @Cache annotation
if (isset($classAnnotations[ORM\Cache::class])) {
$cacheAnnotation = $classAnnotations[ORM\Cache::class];
$cacheMap = array('region' => $cacheAnnotation->region, 'usage' => constant('Doctrine\\ORM\\Mapping\\ClassMetadata::CACHE_USAGE_' . $cacheAnnotation->usage));
$metadata->enableCache($cacheMap);
}
// Evaluate NamedNativeQueries annotation
if (isset($classAnnotations[ORM\NamedNativeQueries::class])) {
$namedNativeQueriesAnnotation = $classAnnotations[ORM\NamedNativeQueries::class];
foreach ($namedNativeQueriesAnnotation->value as $namedNativeQuery) {
$metadata->addNamedNativeQuery(['name' => $namedNativeQuery->name, 'query' => $namedNativeQuery->query, 'resultClass' => $namedNativeQuery->resultClass, 'resultSetMapping' => $namedNativeQuery->resultSetMapping]);
}
}
// Evaluate SqlResultSetMappings annotation
if (isset($classAnnotations[ORM\SqlResultSetMappings::class])) {
$sqlResultSetMappingsAnnotation = $classAnnotations[ORM\SqlResultSetMappings::class];
foreach ($sqlResultSetMappingsAnnotation->value as $resultSetMapping) {
$entities = [];
$columns = [];
foreach ($resultSetMapping->entities as $entityResultAnnotation) {
$entityResult = ['fields' => [], 'entityClass' => $entityResultAnnotation->entityClass, 'discriminatorColumn' => $entityResultAnnotation->discriminatorColumn];
foreach ($entityResultAnnotation->fields as $fieldResultAnnotation) {
$entityResult['fields'][] = ['name' => $fieldResultAnnotation->name, 'column' => $fieldResultAnnotation->column];
}
$entities[] = $entityResult;
}
foreach ($resultSetMapping->columns as $columnResultAnnotation) {
$columns[] = ['name' => $columnResultAnnotation->name];
}
$metadata->addSqlResultSetMapping(['name' => $resultSetMapping->name, 'entities' => $entities, 'columns' => $columns]);
}
}
// Evaluate NamedQueries annotation
if (isset($classAnnotations[ORM\NamedQueries::class])) {
$namedQueriesAnnotation = $classAnnotations[ORM\NamedQueries::class];
if (!is_array($namedQueriesAnnotation->value)) {
throw new \UnexpectedValueException('@ORM\\NamedQueries should contain an array of @ORM\\NamedQuery annotations.');
}
foreach ($namedQueriesAnnotation->value as $namedQuery) {
if (!$namedQuery instanceof ORM\NamedQuery) {
throw new \UnexpectedValueException('@ORM\\NamedQueries should contain an array of @ORM\\NamedQuery annotations.');
}
$metadata->addNamedQuery(['name' => $namedQuery->name, 'query' => $namedQuery->query]);
}
}
// Evaluate InheritanceType annotation
if (isset($classAnnotations[ORM\InheritanceType::class])) {
$inheritanceTypeAnnotation = $classAnnotations[ORM\InheritanceType::class];
$inheritanceType = constant('Doctrine\\ORM\\Mapping\\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($inheritanceTypeAnnotation->value));
if ($inheritanceType !== ORM\ClassMetadata::INHERITANCE_TYPE_NONE) {
// Evaluate DiscriminatorColumn annotation
if (isset($classAnnotations[ORM\DiscriminatorColumn::class])) {
$discriminatorColumnAnnotation = $classAnnotations[ORM\DiscriminatorColumn::class];
$discriminatorColumn = ['name' => $discriminatorColumnAnnotation->name, 'type' => $discriminatorColumnAnnotation->type, 'length' => $discriminatorColumnAnnotation->length, 'columnDefinition' => $discriminatorColumnAnnotation->columnDefinition];
} else {
$discriminatorColumn = ['name' => 'dtype', 'type' => 'string', 'length' => 255];
}
// Evaluate DiscriminatorMap annotation
if (isset($classAnnotations[ORM\DiscriminatorMap::class])) {
$discriminatorMapAnnotation = $classAnnotations[ORM\DiscriminatorMap::class];
$discriminatorMap = $discriminatorMapAnnotation->value;
} else {
$discriminatorMap = [];
$subclassNames = $this->reflectionService->getAllSubClassNamesForClass($className);
if (!$this->reflectionService->isClassAbstract($className)) {
$mappedClassName = strtolower(str_replace('Domain_Model_', '', str_replace('\\', '_', $className)));
$discriminatorMap[$mappedClassName] = $className;
}
foreach ($subclassNames as $subclassName) {
$mappedSubclassName = strtolower(str_replace('Domain_Model_', '', str_replace('\\', '_', $subclassName)));
$discriminatorMap[$mappedSubclassName] = $subclassName;
}
}
if ($discriminatorMap !== []) {
$metadata->setDiscriminatorColumn($discriminatorColumn);
$metadata->setDiscriminatorMap($discriminatorMap);
} else {
$inheritanceType = ORM\ClassMetadata::INHERITANCE_TYPE_NONE;
}
}
$metadata->setInheritanceType($inheritanceType);
}
// Evaluate DoctrineChangeTrackingPolicy annotation
if (isset($classAnnotations[ORM\ChangeTrackingPolicy::class])) {
$changeTrackingAnnotation = $classAnnotations[ORM\ChangeTrackingPolicy::class];
$metadata->setChangeTrackingPolicy(constant('Doctrine\\ORM\\Mapping\\ClassMetadata::CHANGETRACKING_' . strtoupper($changeTrackingAnnotation->value)));
} else {
$metadata->setChangeTrackingPolicy(ORM\ClassMetadata::CHANGETRACKING_DEFERRED_EXPLICIT);
}
// Evaluate annotations on properties/fields
try {
$this->evaluatePropertyAnnotations($metadata);
} catch (ORM\MappingException $exception) {
throw new ORM\MappingException(sprintf('Failure while evaluating property annotations for class "%s": %s', $metadata->getName(), $exception->getMessage()), 1382003497, $exception);
}
// build unique index for table
if (!isset($classAnnotations[ORM\Embeddable::class]) && !isset($primaryTable['uniqueConstraints'])) {
$idProperties = array_keys($classSchema->getIdentityProperties());
if (array_diff($idProperties, $metadata->getIdentifierFieldNames()) !== []) {
$uniqueIndexName = $this->truncateIdentifier('flow_identity_' . $primaryTable['name']);
foreach ($idProperties as $idProperty) {
$primaryTable['uniqueConstraints'][$uniqueIndexName]['columns'][] = isset($metadata->columnNames[$idProperty]) ? $metadata->columnNames[$idProperty] : strtolower($idProperty);
}
}
}
$metadata->setPrimaryTable($primaryTable);
// Evaluate AssociationOverrides annotation
$this->evaluateOverridesAnnotations($classAnnotations, $metadata);
// Evaluate EntityListeners annotation
$this->evaluateEntityListenersAnnotation($class, $metadata, $classAnnotations);
// Evaluate @HasLifecycleCallbacks annotation
$this->evaluateLifeCycleAnnotations($class, $metadata);
}