예제 #1
0
 /**
  * (non-PHPdoc)
  * @see Gedmo\Mapping.Driver::readExtendedMetadata()
  */
 public function readExtendedMetadata(ClassMetadataInfo $meta, array &$config)
 {
     require_once __DIR__ . '/../Annotations.php';
     $reader = new AnnotationReader();
     $reader->setAnnotationNamespaceAlias('Gedmo\\Timestampable\\Mapping\\', 'gedmo');
     $class = $meta->getReflectionClass();
     // property annotations
     foreach ($class->getProperties() as $property) {
         if ($meta->isMappedSuperclass && !$property->isPrivate() || $meta->isInheritedField($property->name) || $meta->isInheritedAssociation($property->name)) {
             continue;
         }
         if ($timestampable = $reader->getPropertyAnnotation($property, self::ANNOTATION_TIMESTAMPABLE)) {
             $field = $property->getName();
             if (!$meta->hasField($field)) {
                 throw MappingException::fieldMustBeMapped($field, $meta->name);
             }
             if (!$this->_isValidField($meta, $field)) {
                 throw MappingException::notValidFieldType($field, $meta->name);
             }
             if (!in_array($timestampable->on, array('update', 'create', 'change'))) {
                 throw MappingException::triggerTypeInvalid($field, $meta->name);
             }
             if ($timestampable->on == 'change') {
                 if (!isset($timestampable->field) || !isset($timestampable->value)) {
                     throw MappingException::parametersMissing($field, $meta->name);
                 }
                 $field = array('field' => $field, 'trackedField' => $timestampable->field, 'value' => $timestampable->value);
             }
             // properties are unique and mapper checks that, no risk here
             $config[$timestampable->on][] = $field;
         }
     }
 }
예제 #2
0
 /**
  * (non-PHPdoc)
  * @see Gedmo\Mapping.Driver::readExtendedMetadata()
  */
 public function readExtendedMetadata(ClassMetadataInfo $meta, array &$config)
 {
     require_once __DIR__ . '/../Annotations.php';
     $reader = new AnnotationReader();
     $reader->setAnnotationNamespaceAlias('Gedmo\\Tree\\Mapping\\', 'gedmo');
     $class = $meta->getReflectionClass();
     // property annotations
     foreach ($class->getProperties() as $property) {
         if ($meta->isMappedSuperclass && !$property->isPrivate() || $meta->isInheritedField($property->name) || $meta->isInheritedAssociation($property->name)) {
             continue;
         }
         // left
         if ($left = $reader->getPropertyAnnotation($property, self::ANNOTATION_LEFT)) {
             $field = $property->getName();
             if (!$meta->hasField($field)) {
                 throw MappingException::fieldMustBeMapped($field, $meta->name);
             }
             if (!$this->_isValidField($meta, $field)) {
                 throw MappingException::notValidFieldType($field, $meta->name);
             }
             $config['left'] = $field;
         }
         // right
         if ($right = $reader->getPropertyAnnotation($property, self::ANNOTATION_RIGHT)) {
             $field = $property->getName();
             if (!$meta->hasField($field)) {
                 throw MappingException::fieldMustBeMapped($field, $meta->name);
             }
             if (!$this->_isValidField($meta, $field)) {
                 throw MappingException::notValidFieldType($field, $meta->name);
             }
             $config['right'] = $field;
         }
         // ancestor/parent
         if ($parent = $reader->getPropertyAnnotation($property, self::ANNOTATION_PARENT)) {
             $field = $property->getName();
             if (!$meta->isSingleValuedAssociation($field)) {
                 throw MappingException::parentFieldNotMappedOrRelated($field, $meta->name);
             }
             $config['parent'] = $field;
         }
         // level
         if ($parent = $reader->getPropertyAnnotation($property, self::ANNOTATION_LEVEL)) {
             $field = $property->getName();
             if (!$meta->hasField($field)) {
                 throw MappingException::fieldMustBeMapped($field, $meta->name);
             }
             if (!$this->_isValidField($meta, $field)) {
                 throw MappingException::notValidFieldType($field, $meta->name);
             }
             $config['level'] = $field;
         }
     }
 }
예제 #3
0
 /**
  * (non-PHPdoc)
  * @see Gedmo\Mapping.Driver::readExtendedMetadata()
  */
 public function readExtendedMetadata(ClassMetadataInfo $meta, array &$config)
 {
     require_once __DIR__ . '/../Annotations.php';
     $reader = new AnnotationReader();
     $reader->setAnnotationNamespaceAlias('Gedmo\\Translatable\\Mapping\\', 'gedmo');
     $class = $meta->getReflectionClass();
     // class annotations
     $classAnnotations = $reader->getClassAnnotations($class);
     if (isset($classAnnotations[self::ANNOTATION_ENTITY_CLASS])) {
         $annot = $classAnnotations[self::ANNOTATION_ENTITY_CLASS];
         if (!class_exists($annot->class)) {
             throw MappingException::translationClassNotFound($annot->class);
         }
         $config['translationClass'] = $annot->class;
     }
     // property annotations
     foreach ($class->getProperties() as $property) {
         if ($meta->isMappedSuperclass && !$property->isPrivate() || $meta->isInheritedField($property->name) || $meta->isInheritedAssociation($property->name)) {
             continue;
         }
         // translatable property
         if ($translatable = $reader->getPropertyAnnotation($property, self::ANNOTATION_TRANSLATABLE)) {
             $field = $property->getName();
             if (!$meta->hasField($field)) {
                 throw MappingException::fieldMustBeMapped($field, $meta->name);
             }
             if (!$this->_isValidField($meta, $field)) {
                 throw MappingException::notValidFieldType($field, $meta->name);
             }
             // fields cannot be overrided and throws mapping exception
             $config['fields'][] = $field;
         }
         // locale property
         if ($locale = $reader->getPropertyAnnotation($property, self::ANNOTATION_LOCALE)) {
             $field = $property->getName();
             if ($meta->hasField($field)) {
                 throw MappingException::fieldMustNotBeMapped($field, $meta->name);
             }
             $config['locale'] = $field;
         } elseif ($language = $reader->getPropertyAnnotation($property, self::ANNOTATION_LANGUAGE)) {
             $field = $property->getName();
             if ($meta->hasField($field)) {
                 throw MappingException::fieldMustNotBeMapped($field, $meta->name);
             }
             $config['locale'] = $field;
         }
     }
 }
예제 #4
0
 /**
  * (non-PHPdoc)
  * @see Gedmo\Mapping.Driver::readExtendedMetadata()
  */
 public function readExtendedMetadata(ClassMetadataInfo $meta, array &$config)
 {
     require_once __DIR__ . '/../Annotations.php';
     $reader = new AnnotationReader();
     $reader->setAnnotationNamespaceAlias('Gedmo\\Sluggable\\Mapping\\', 'gedmo');
     $class = $meta->getReflectionClass();
     // property annotations
     foreach ($class->getProperties() as $property) {
         if ($meta->isMappedSuperclass && !$property->isPrivate() || $meta->isInheritedField($property->name) || $meta->isInheritedAssociation($property->name)) {
             continue;
         }
         // sluggable property
         if ($sluggable = $reader->getPropertyAnnotation($property, self::ANNOTATION_SLUGGABLE)) {
             $field = $property->getName();
             if (!$meta->hasField($field)) {
                 throw MappingException::fieldMustBeMapped($field, $meta->name);
             }
             if (!$this->_isValidField($meta, $field)) {
                 throw MappingException::notValidFieldType($field, $meta->name);
             }
             $config['fields'][] = $field;
         }
         // slug property
         if ($slug = $reader->getPropertyAnnotation($property, self::ANNOTATION_SLUG)) {
             $field = $property->getName();
             if (!$meta->hasField($field)) {
                 throw MappingException::slugFieldMustBeMapped($field, $meta->name);
             }
             if (!$this->_isValidField($meta, $field)) {
                 throw MappingException::notValidFieldType($field, $meta->name);
             }
             if (isset($config['slug'])) {
                 throw MappingException::slugFieldIsDuplicate($field, $meta->name);
             }
             $config['slug'] = $field;
             $config['style'] = $slug->style;
             $config['updatable'] = $slug->updatable;
             $config['unique'] = $slug->unique;
             $config['separator'] = $slug->separator;
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
 {
     $class = $metadata->getReflectionClass();
     if (!$class) {
         // this happens when running annotation driver in combination with
         // static reflection services. This is not the nicest fix
         $class = new \ReflectionClass($metadata->name);
     }
     $classAnnotations = $this->_reader->getClassAnnotations($class);
     // Compatibility with Doctrine Common 3.x
     if ($classAnnotations && is_int(key($classAnnotations))) {
         foreach ($classAnnotations as $annot) {
             $classAnnotations[get_class($annot)] = $annot;
         }
     }
     // Evaluate Entity annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\Entity'])) {
         $entityAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\Entity'];
         if ($entityAnnot->repositoryClass !== null) {
             $metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
         }
         if ($entityAnnot->readOnly) {
             $metadata->markReadOnly();
         }
     } else {
         if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\MappedSuperclass'])) {
             $mappedSuperclassAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\MappedSuperclass'];
             $metadata->setCustomRepositoryClass($mappedSuperclassAnnot->repositoryClass);
             $metadata->isMappedSuperclass = true;
         } else {
             throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
         }
     }
     // Evaluate Table annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\Table'])) {
         $tableAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\Table'];
         $primaryTable = array('name' => $tableAnnot->name, 'schema' => $tableAnnot->schema);
         if ($tableAnnot->indexes !== null) {
             foreach ($tableAnnot->indexes as $indexAnnot) {
                 $primaryTable['indexes'][$indexAnnot->name] = array('columns' => $indexAnnot->columns);
             }
         }
         if ($tableAnnot->uniqueConstraints !== null) {
             foreach ($tableAnnot->uniqueConstraints as $uniqueConstraint) {
                 $primaryTable['uniqueConstraints'][$uniqueConstraint->name] = array('columns' => $uniqueConstraint->columns);
             }
         }
         if ($tableAnnot->options !== null) {
             $primaryTable['options'] = $tableAnnot->options;
         }
         $metadata->setPrimaryTable($primaryTable);
     }
     // Evaluate NamedQueries annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\NamedQueries'])) {
         $namedQueriesAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\NamedQueries'];
         if (!is_array($namedQueriesAnnot->value)) {
             throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
         }
         foreach ($namedQueriesAnnot->value as $namedQuery) {
             if (!$namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery) {
                 throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
             }
             $metadata->addNamedQuery(array('name' => $namedQuery->name, 'query' => $namedQuery->query));
         }
     }
     // Evaluate InheritanceType annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\InheritanceType'])) {
         $inheritanceTypeAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\InheritanceType'];
         $metadata->setInheritanceType(constant('Doctrine\\ORM\\Mapping\\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceTypeAnnot->value));
         if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) {
             // Evaluate DiscriminatorColumn annotation
             if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorColumn'])) {
                 $discrColumnAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorColumn'];
                 $metadata->setDiscriminatorColumn(array('name' => $discrColumnAnnot->name, 'type' => $discrColumnAnnot->type, 'length' => $discrColumnAnnot->length, 'columnDefinition' => $discrColumnAnnot->columnDefinition));
             } else {
                 $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
             }
             // Evaluate DiscriminatorMap annotation
             if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorMap'])) {
                 $discrMapAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorMap'];
                 $metadata->setDiscriminatorMap($discrMapAnnot->value);
             }
         }
     }
     // Evaluate DoctrineChangeTrackingPolicy annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\ChangeTrackingPolicy'])) {
         $changeTrackingAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\ChangeTrackingPolicy'];
         $metadata->setChangeTrackingPolicy(constant('Doctrine\\ORM\\Mapping\\ClassMetadata::CHANGETRACKING_' . $changeTrackingAnnot->value));
     }
     // Evaluate annotations on properties/fields
     foreach ($class->getProperties() as $property) {
         if ($metadata->isMappedSuperclass && !$property->isPrivate() || $metadata->isInheritedField($property->name) || $metadata->isInheritedAssociation($property->name)) {
             continue;
         }
         $mapping = array();
         $mapping['fieldName'] = $property->getName();
         // Check for JoinColummn/JoinColumns annotations
         $joinColumns = array();
         if ($joinColumnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\JoinColumn')) {
             $joinColumns[] = array('name' => $joinColumnAnnot->name, 'referencedColumnName' => $joinColumnAnnot->referencedColumnName, 'unique' => $joinColumnAnnot->unique, 'nullable' => $joinColumnAnnot->nullable, 'onDelete' => $joinColumnAnnot->onDelete, 'columnDefinition' => $joinColumnAnnot->columnDefinition);
         } else {
             if ($joinColumnsAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\JoinColumns')) {
                 foreach ($joinColumnsAnnot->value as $joinColumn) {
                     $joinColumns[] = array('name' => $joinColumn->name, 'referencedColumnName' => $joinColumn->referencedColumnName, 'unique' => $joinColumn->unique, 'nullable' => $joinColumn->nullable, 'onDelete' => $joinColumn->onDelete, 'columnDefinition' => $joinColumn->columnDefinition);
                 }
             }
         }
         // Field can only be annotated with one of:
         // @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany
         if ($columnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Column')) {
             if ($columnAnnot->type == null) {
                 throw MappingException::propertyTypeIsRequired($className, $property->getName());
             }
             $mapping['type'] = $columnAnnot->type;
             $mapping['length'] = $columnAnnot->length;
             $mapping['precision'] = $columnAnnot->precision;
             $mapping['scale'] = $columnAnnot->scale;
             $mapping['nullable'] = $columnAnnot->nullable;
             $mapping['unique'] = $columnAnnot->unique;
             if ($columnAnnot->options) {
                 $mapping['options'] = $columnAnnot->options;
             }
             if (isset($columnAnnot->name)) {
                 $mapping['columnName'] = $columnAnnot->name;
             }
             if (isset($columnAnnot->columnDefinition)) {
                 $mapping['columnDefinition'] = $columnAnnot->columnDefinition;
             }
             if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Id')) {
                 $mapping['id'] = true;
             }
             if ($generatedValueAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\GeneratedValue')) {
                 $metadata->setIdGeneratorType(constant('Doctrine\\ORM\\Mapping\\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy));
             }
             if ($versionAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Version')) {
                 $metadata->setVersionMapping($mapping);
             }
             $metadata->mapField($mapping);
             // Check for SequenceGenerator/TableGenerator definition
             if ($seqGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\SequenceGenerator')) {
                 $metadata->setSequenceGeneratorDefinition(array('sequenceName' => $seqGeneratorAnnot->sequenceName, 'allocationSize' => $seqGeneratorAnnot->allocationSize, 'initialValue' => $seqGeneratorAnnot->initialValue));
             } else {
                 if ($tblGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\TableGenerator')) {
                     throw MappingException::tableIdGeneratorNotImplemented($className);
                 }
             }
         } else {
             if ($oneToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\OneToOne')) {
                 if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Id')) {
                     $mapping['id'] = true;
                 }
                 $mapping['targetEntity'] = $oneToOneAnnot->targetEntity;
                 $mapping['joinColumns'] = $joinColumns;
                 $mapping['mappedBy'] = $oneToOneAnnot->mappedBy;
                 $mapping['inversedBy'] = $oneToOneAnnot->inversedBy;
                 $mapping['cascade'] = $oneToOneAnnot->cascade;
                 $mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval;
                 $mapping['fetch'] = $this->getFetchMode($className, $oneToOneAnnot->fetch);
                 $metadata->mapOneToOne($mapping);
             } else {
                 if ($oneToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\OneToMany')) {
                     $mapping['mappedBy'] = $oneToManyAnnot->mappedBy;
                     $mapping['targetEntity'] = $oneToManyAnnot->targetEntity;
                     $mapping['cascade'] = $oneToManyAnnot->cascade;
                     $mapping['indexBy'] = $oneToManyAnnot->indexBy;
                     $mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval;
                     $mapping['fetch'] = $this->getFetchMode($className, $oneToManyAnnot->fetch);
                     if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\OrderBy')) {
                         $mapping['orderBy'] = $orderByAnnot->value;
                     }
                     $metadata->mapOneToMany($mapping);
                 } else {
                     if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\ManyToOne')) {
                         if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Id')) {
                             $mapping['id'] = true;
                         }
                         $mapping['joinColumns'] = $joinColumns;
                         $mapping['cascade'] = $manyToOneAnnot->cascade;
                         $mapping['inversedBy'] = $manyToOneAnnot->inversedBy;
                         $mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
                         $mapping['fetch'] = $this->getFetchMode($className, $manyToOneAnnot->fetch);
                         $metadata->mapManyToOne($mapping);
                     } else {
                         if ($manyToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\ManyToMany')) {
                             $joinTable = array();
                             if ($joinTableAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\JoinTable')) {
                                 $joinTable = array('name' => $joinTableAnnot->name, 'schema' => $joinTableAnnot->schema);
                                 foreach ($joinTableAnnot->joinColumns as $joinColumn) {
                                     $joinTable['joinColumns'][] = array('name' => $joinColumn->name, 'referencedColumnName' => $joinColumn->referencedColumnName, 'unique' => $joinColumn->unique, 'nullable' => $joinColumn->nullable, 'onDelete' => $joinColumn->onDelete, 'columnDefinition' => $joinColumn->columnDefinition);
                                 }
                                 foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
                                     $joinTable['inverseJoinColumns'][] = array('name' => $joinColumn->name, 'referencedColumnName' => $joinColumn->referencedColumnName, 'unique' => $joinColumn->unique, 'nullable' => $joinColumn->nullable, 'onDelete' => $joinColumn->onDelete, 'columnDefinition' => $joinColumn->columnDefinition);
                                 }
                             }
                             $mapping['joinTable'] = $joinTable;
                             $mapping['targetEntity'] = $manyToManyAnnot->targetEntity;
                             $mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
                             $mapping['inversedBy'] = $manyToManyAnnot->inversedBy;
                             $mapping['cascade'] = $manyToManyAnnot->cascade;
                             $mapping['indexBy'] = $manyToManyAnnot->indexBy;
                             $mapping['orphanRemoval'] = $manyToManyAnnot->orphanRemoval;
                             $mapping['fetch'] = $this->getFetchMode($className, $manyToManyAnnot->fetch);
                             if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\OrderBy')) {
                                 $mapping['orderBy'] = $orderByAnnot->value;
                             }
                             $metadata->mapManyToMany($mapping);
                         }
                     }
                 }
             }
         }
     }
     // Evaluate @HasLifecycleCallbacks annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\HasLifecycleCallbacks'])) {
         foreach ($class->getMethods() as $method) {
             // filter for the declaring class only, callbacks from parents will already be registered.
             if ($method->isPublic() && $method->getDeclaringClass()->getName() == $class->name) {
                 $annotations = $this->_reader->getMethodAnnotations($method);
                 // Compatibility with Doctrine Common 3.x
                 if ($annotations && is_int(key($annotations))) {
                     foreach ($annotations as $annot) {
                         $annotations[get_class($annot)] = $annot;
                     }
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PrePersist'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PostPersist'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postPersist);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PreUpdate'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preUpdate);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PostUpdate'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postUpdate);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PreRemove'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preRemove);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PostRemove'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postRemove);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PostLoad'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PreFlush'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preFlush);
                 }
             }
         }
     }
 }
 /**
  * Evaluate the property annotations and amend the metadata accordingly.
  *
  * @param ClassMetadataInfo $metadata
  * @return void
  * @throws MappingException
  */
 protected function evaluatePropertyAnnotations(ClassMetadataInfo $metadata)
 {
     $className = $metadata->name;
     $class = $metadata->getReflectionClass();
     $classSchema = $this->getClassSchema($className);
     foreach ($class->getProperties() as $property) {
         if (!$classSchema->hasProperty($property->getName()) || $classSchema->isPropertyTransient($property->getName()) || $metadata->isMappedSuperclass && !$property->isPrivate() || $metadata->isInheritedField($property->getName()) || $metadata->isInheritedAssociation($property->getName())) {
             continue;
         }
         $propertyMetaData = $classSchema->getProperty($property->getName());
         $mapping = array();
         $mapping['fieldName'] = $property->getName();
         $mapping['columnName'] = strtolower($property->getName());
         $mapping['targetEntity'] = $propertyMetaData['type'];
         $joinColumns = $this->evaluateJoinColumnAnnotations($property);
         // Field can only be annotated with one of:
         // @OneToOne, @OneToMany, @ManyToOne, @ManyToMany, @Column (optional)
         if ($oneToOneAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\OneToOne')) {
             if ($oneToOneAnnotation->targetEntity) {
                 $mapping['targetEntity'] = $oneToOneAnnotation->targetEntity;
             }
             if ($oneToOneAnnotation->inversedBy !== null || $oneToOneAnnotation->mappedBy === null) {
                 $mapping['joinColumns'] = $this->buildJoinColumnsIfNeeded($joinColumns, $mapping, $property);
             }
             $mapping['mappedBy'] = $oneToOneAnnotation->mappedBy;
             $mapping['inversedBy'] = $oneToOneAnnotation->inversedBy;
             if ($oneToOneAnnotation->cascade) {
                 $mapping['cascade'] = $oneToOneAnnotation->cascade;
             } elseif ($this->isValueObject($mapping['targetEntity'], $className)) {
                 $mapping['cascade'] = array('persist');
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false) {
                 $mapping['cascade'] = array('all');
             }
             if ($oneToOneAnnotation->orphanRemoval) {
                 $mapping['orphanRemoval'] = $oneToOneAnnotation->orphanRemoval;
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false && $this->isValueObject($mapping['targetEntity'], $className) === false) {
                 $mapping['orphanRemoval'] = true;
             }
             $mapping['fetch'] = $this->getFetchMode($className, $oneToOneAnnotation->fetch);
             $metadata->mapOneToOne($mapping);
         } elseif ($oneToManyAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\OneToMany')) {
             $mapping['mappedBy'] = $oneToManyAnnotation->mappedBy;
             if ($oneToManyAnnotation->targetEntity) {
                 $mapping['targetEntity'] = $oneToManyAnnotation->targetEntity;
             } elseif (isset($propertyMetaData['elementType'])) {
                 $mapping['targetEntity'] = $propertyMetaData['elementType'];
             }
             if ($oneToManyAnnotation->cascade) {
                 $mapping['cascade'] = $oneToManyAnnotation->cascade;
             } elseif ($this->isValueObject($mapping['targetEntity'], $className)) {
                 $mapping['cascade'] = array('persist');
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false) {
                 $mapping['cascade'] = array('all');
             }
             $mapping['indexBy'] = $oneToManyAnnotation->indexBy;
             if ($oneToManyAnnotation->orphanRemoval) {
                 $mapping['orphanRemoval'] = $oneToManyAnnotation->orphanRemoval;
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false && $this->isValueObject($mapping['targetEntity'], $className) === false) {
                 $mapping['orphanRemoval'] = true;
             }
             $mapping['fetch'] = $this->getFetchMode($className, $oneToManyAnnotation->fetch);
             if ($orderByAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\OrderBy')) {
                 $mapping['orderBy'] = $orderByAnnotation->value;
             }
             $metadata->mapOneToMany($mapping);
         } elseif ($manyToOneAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\ManyToOne')) {
             if ($manyToOneAnnotation->targetEntity) {
                 $mapping['targetEntity'] = $manyToOneAnnotation->targetEntity;
             }
             $mapping['joinColumns'] = $this->buildJoinColumnsIfNeeded($joinColumns, $mapping, $property);
             if ($manyToOneAnnotation->cascade) {
                 $mapping['cascade'] = $manyToOneAnnotation->cascade;
             } elseif ($this->isValueObject($mapping['targetEntity'], $className)) {
                 $mapping['cascade'] = array('persist');
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false) {
                 $mapping['cascade'] = array('all');
             }
             $mapping['inversedBy'] = $manyToOneAnnotation->inversedBy;
             $mapping['fetch'] = $this->getFetchMode($className, $manyToOneAnnotation->fetch);
             $metadata->mapManyToOne($mapping);
         } elseif ($manyToManyAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\ManyToMany')) {
             if ($manyToManyAnnotation->targetEntity) {
                 $mapping['targetEntity'] = $manyToManyAnnotation->targetEntity;
             } elseif (isset($propertyMetaData['elementType'])) {
                 $mapping['targetEntity'] = $propertyMetaData['elementType'];
             }
             /** @var JoinTable $joinTableAnnotation */
             if ($joinTableAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\JoinTable')) {
                 $joinTable = $this->evaluateJoinTableAnnotation($joinTableAnnotation, $property, $className, $mapping);
             } else {
                 $joinColumns = array(array('name' => null, 'referencedColumnName' => null));
                 $joinTable = array('name' => $this->inferJoinTableNameFromClassAndPropertyName($className, $property->getName()), 'joinColumns' => $this->buildJoinColumnsIfNeeded($joinColumns, $mapping, $property, self::MAPPING_MM_REGULAR), 'inverseJoinColumns' => $this->buildJoinColumnsIfNeeded($joinColumns, $mapping, $property));
             }
             $mapping['joinTable'] = $joinTable;
             $mapping['mappedBy'] = $manyToManyAnnotation->mappedBy;
             $mapping['inversedBy'] = $manyToManyAnnotation->inversedBy;
             if ($manyToManyAnnotation->cascade) {
                 $mapping['cascade'] = $manyToManyAnnotation->cascade;
             } elseif ($this->isValueObject($mapping['targetEntity'], $className)) {
                 $mapping['cascade'] = array('persist');
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false) {
                 $mapping['cascade'] = array('all');
             }
             $mapping['indexBy'] = $manyToManyAnnotation->indexBy;
             $mapping['orphanRemoval'] = $manyToManyAnnotation->orphanRemoval;
             $mapping['fetch'] = $this->getFetchMode($className, $manyToManyAnnotation->fetch);
             if ($orderByAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\OrderBy')) {
                 $mapping['orderBy'] = $orderByAnnotation->value;
             }
             $metadata->mapManyToMany($mapping);
         } else {
             $mapping['nullable'] = false;
             /** @var Column $columnAnnotation */
             if ($columnAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Column')) {
                 $mapping = $this->addColumnToMappingArray($columnAnnotation, $mapping);
             }
             if (!isset($mapping['type'])) {
                 switch ($propertyMetaData['type']) {
                     case 'DateTime':
                         $mapping['type'] = 'datetime';
                         break;
                     case 'string':
                     case 'integer':
                     case 'boolean':
                     case 'float':
                     case 'array':
                         $mapping['type'] = $propertyMetaData['type'];
                         break;
                     default:
                         if (strpos($propertyMetaData['type'], '\\') !== false) {
                             if ($this->reflectionService->isClassAnnotatedWith($propertyMetaData['type'], \TYPO3\Flow\Annotations\ValueObject::class)) {
                                 $mapping['type'] = 'object';
                             } elseif (class_exists($propertyMetaData['type'])) {
                                 throw MappingException::missingRequiredOption($property->getName(), 'OneToOne', sprintf('The property "%s" in class "%s" has a non standard data type and doesn\'t define the type of the relation. You have to use one of these annotations: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany', $property->getName(), $className));
                             }
                         } else {
                             throw MappingException::propertyTypeIsRequired($className, $property->getName());
                         }
                 }
             }
             if ($this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Id') !== null) {
                 $mapping['id'] = true;
             }
             if ($generatedValueAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\GeneratedValue')) {
                 $metadata->setIdGeneratorType(constant('Doctrine\\ORM\\Mapping\\ClassMetadata::GENERATOR_TYPE_' . strtoupper($generatedValueAnnotation->strategy)));
             }
             if ($this->reflectionService->isPropertyAnnotatedWith($className, $property->getName(), 'Doctrine\\ORM\\Mapping\\Version')) {
                 $metadata->setVersionMapping($mapping);
             }
             $metadata->mapField($mapping);
             // Check for SequenceGenerator/TableGenerator definition
             if ($seqGeneratorAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\SequenceGenerator')) {
                 $metadata->setSequenceGeneratorDefinition(array('sequenceName' => $seqGeneratorAnnotation->sequenceName, 'allocationSize' => $seqGeneratorAnnotation->allocationSize, 'initialValue' => $seqGeneratorAnnotation->initialValue));
             } elseif ($this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\TableGenerator') !== null) {
                 throw MappingException::tableIdGeneratorNotImplemented($className);
             } elseif ($customGeneratorAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\CustomIdGenerator')) {
                 $metadata->setCustomGeneratorDefinition(array('class' => $customGeneratorAnnotation->class));
             }
         }
     }
 }
 /**
  * Evaluate the property annotations and amend the metadata accordingly.
  *
  * @param ORM\ClassMetadataInfo $metadata
  * @return void
  * @throws ORM\MappingException
  */
 protected function evaluatePropertyAnnotations(ORM\ClassMetadataInfo $metadata)
 {
     $className = $metadata->name;
     $class = $metadata->getReflectionClass();
     $classSchema = $this->getClassSchema($className);
     foreach ($class->getProperties() as $property) {
         if (!$classSchema->hasProperty($property->getName()) || $classSchema->isPropertyTransient($property->getName()) || $metadata->isMappedSuperclass && !$property->isPrivate() || $metadata->isInheritedField($property->getName()) || $metadata->isInheritedAssociation($property->getName()) || $metadata->isInheritedEmbeddedClass($property->getName())) {
             continue;
         }
         $propertyMetaData = $classSchema->getProperty($property->getName());
         $mapping = [];
         $mapping['fieldName'] = $property->getName();
         $mapping['columnName'] = strtolower($property->getName());
         $mapping['targetEntity'] = $propertyMetaData['type'];
         $joinColumns = $this->evaluateJoinColumnAnnotations($property);
         // Field can only be annotated with one of:
         // @OneToOne, @OneToMany, @ManyToOne, @ManyToMany, @Column (optional)
         if ($oneToOneAnnotation = $this->reader->getPropertyAnnotation($property, ORM\OneToOne::class)) {
             if ($this->reader->getPropertyAnnotation($property, ORM\Id::class) !== null) {
                 $mapping['id'] = true;
             }
             if ($oneToOneAnnotation->targetEntity) {
                 $mapping['targetEntity'] = $oneToOneAnnotation->targetEntity;
             }
             if ($oneToOneAnnotation->inversedBy !== null || $oneToOneAnnotation->mappedBy === null) {
                 $mapping['joinColumns'] = $this->buildJoinColumnsIfNeeded($joinColumns, $mapping, $property);
             }
             $mapping['mappedBy'] = $oneToOneAnnotation->mappedBy;
             $mapping['inversedBy'] = $oneToOneAnnotation->inversedBy;
             if ($oneToOneAnnotation->cascade) {
                 $mapping['cascade'] = $oneToOneAnnotation->cascade;
             } elseif ($this->isValueObject($mapping['targetEntity'], $className)) {
                 $mapping['cascade'] = ['persist'];
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false) {
                 $mapping['cascade'] = ['all'];
             }
             if ($oneToOneAnnotation->orphanRemoval) {
                 $mapping['orphanRemoval'] = $oneToOneAnnotation->orphanRemoval;
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false && $this->isValueObject($mapping['targetEntity'], $className) === false) {
                 $mapping['orphanRemoval'] = true;
             }
             $mapping['fetch'] = $this->getFetchMode($className, $oneToOneAnnotation->fetch);
             $metadata->mapOneToOne($mapping);
         } elseif ($oneToManyAnnotation = $this->reader->getPropertyAnnotation($property, ORM\OneToMany::class)) {
             $mapping['mappedBy'] = $oneToManyAnnotation->mappedBy;
             if ($oneToManyAnnotation->targetEntity) {
                 $mapping['targetEntity'] = $oneToManyAnnotation->targetEntity;
             } elseif (isset($propertyMetaData['elementType'])) {
                 $mapping['targetEntity'] = $propertyMetaData['elementType'];
             }
             if ($oneToManyAnnotation->cascade) {
                 $mapping['cascade'] = $oneToManyAnnotation->cascade;
             } elseif ($this->isValueObject($mapping['targetEntity'], $className)) {
                 $mapping['cascade'] = ['persist'];
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false) {
                 $mapping['cascade'] = ['all'];
             }
             $mapping['indexBy'] = $oneToManyAnnotation->indexBy;
             if ($oneToManyAnnotation->orphanRemoval) {
                 $mapping['orphanRemoval'] = $oneToManyAnnotation->orphanRemoval;
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false && $this->isValueObject($mapping['targetEntity'], $className) === false) {
                 $mapping['orphanRemoval'] = true;
             }
             $mapping['fetch'] = $this->getFetchMode($className, $oneToManyAnnotation->fetch);
             if ($orderByAnnotation = $this->reader->getPropertyAnnotation($property, ORM\OrderBy::class)) {
                 $mapping['orderBy'] = $orderByAnnotation->value;
             }
             $metadata->mapOneToMany($mapping);
         } elseif ($manyToOneAnnotation = $this->reader->getPropertyAnnotation($property, ORM\ManyToOne::class)) {
             if ($this->reader->getPropertyAnnotation($property, ORM\Id::class) !== null) {
                 $mapping['id'] = true;
             }
             if ($manyToOneAnnotation->targetEntity) {
                 $mapping['targetEntity'] = $manyToOneAnnotation->targetEntity;
             }
             $mapping['joinColumns'] = $this->buildJoinColumnsIfNeeded($joinColumns, $mapping, $property);
             if ($manyToOneAnnotation->cascade) {
                 $mapping['cascade'] = $manyToOneAnnotation->cascade;
             } elseif ($this->isValueObject($mapping['targetEntity'], $className)) {
                 $mapping['cascade'] = ['persist'];
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false) {
                 $mapping['cascade'] = ['all'];
             }
             $mapping['inversedBy'] = $manyToOneAnnotation->inversedBy;
             $mapping['fetch'] = $this->getFetchMode($className, $manyToOneAnnotation->fetch);
             $metadata->mapManyToOne($mapping);
         } elseif ($manyToManyAnnotation = $this->reader->getPropertyAnnotation($property, ORM\ManyToMany::class)) {
             if ($manyToManyAnnotation->targetEntity) {
                 $mapping['targetEntity'] = $manyToManyAnnotation->targetEntity;
             } elseif (isset($propertyMetaData['elementType'])) {
                 $mapping['targetEntity'] = $propertyMetaData['elementType'];
             }
             /** @var ORM\JoinTable $joinTableAnnotation */
             if ($joinTableAnnotation = $this->reader->getPropertyAnnotation($property, ORM\JoinTable::class)) {
                 $joinTable = $this->evaluateJoinTableAnnotation($joinTableAnnotation, $property, $className, $mapping);
             } else {
                 $joinColumns = [['name' => null, 'referencedColumnName' => null]];
                 $joinTable = ['name' => $this->inferJoinTableNameFromClassAndPropertyName($className, $property->getName()), 'joinColumns' => $this->buildJoinColumnsIfNeeded($joinColumns, $mapping, $property, self::MAPPING_MM_REGULAR), 'inverseJoinColumns' => $this->buildJoinColumnsIfNeeded($joinColumns, $mapping, $property)];
             }
             $mapping['joinTable'] = $joinTable;
             $mapping['mappedBy'] = $manyToManyAnnotation->mappedBy;
             $mapping['inversedBy'] = $manyToManyAnnotation->inversedBy;
             if ($manyToManyAnnotation->cascade) {
                 $mapping['cascade'] = $manyToManyAnnotation->cascade;
             } elseif ($this->isValueObject($mapping['targetEntity'], $className)) {
                 $mapping['cascade'] = ['persist'];
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === false) {
                 $mapping['cascade'] = ['all'];
             }
             $mapping['indexBy'] = $manyToManyAnnotation->indexBy;
             $mapping['orphanRemoval'] = $manyToManyAnnotation->orphanRemoval;
             $mapping['fetch'] = $this->getFetchMode($className, $manyToManyAnnotation->fetch);
             if ($orderByAnnotation = $this->reader->getPropertyAnnotation($property, ORM\OrderBy::class)) {
                 $mapping['orderBy'] = $orderByAnnotation->value;
             }
             $metadata->mapManyToMany($mapping);
         } elseif ($embeddedAnnotation = $this->reader->getPropertyAnnotation($property, ORM\Embedded::class)) {
             if ($embeddedAnnotation->class) {
                 $mapping['class'] = $embeddedAnnotation->class;
             } else {
                 // This will not happen currently, because "class" argument is required. It would be nice if that could be changed though.
                 $mapping['class'] = $mapping['targetEntity'];
             }
             $mapping['columnPrefix'] = $embeddedAnnotation->columnPrefix;
             $metadata->mapEmbedded($mapping);
         } else {
             $mapping['nullable'] = false;
             /** @var ORM\Column $columnAnnotation */
             if ($columnAnnotation = $this->reader->getPropertyAnnotation($property, ORM\Column::class)) {
                 $mapping = $this->addColumnToMappingArray($columnAnnotation, $mapping);
             }
             if (!isset($mapping['type'])) {
                 switch ($propertyMetaData['type']) {
                     case 'DateTime':
                         $mapping['type'] = 'datetime';
                         break;
                     case 'string':
                     case 'integer':
                     case 'boolean':
                     case 'float':
                     case 'array':
                         $mapping['type'] = $propertyMetaData['type'];
                         break;
                     default:
                         if (strpos($propertyMetaData['type'], '\\') !== false) {
                             if ($this->reflectionService->isClassAnnotatedWith($propertyMetaData['type'], Flow\ValueObject::class)) {
                                 $valueObjectAnnotation = $this->reflectionService->getClassAnnotation($propertyMetaData['type'], Flow\ValueObject::class);
                                 if ($valueObjectAnnotation->embedded === true) {
                                     $mapping['class'] = $propertyMetaData['type'];
                                     $mapping['columnPrefix'] = $mapping['columnName'];
                                     $metadata->mapEmbedded($mapping);
                                     // Leave switch and continue with next property
                                     continue 2;
                                 }
                                 $mapping['type'] = 'object';
                             } elseif (class_exists($propertyMetaData['type'])) {
                                 throw ORM\MappingException::missingRequiredOption($property->getName(), 'OneToOne', sprintf('The property "%s" in class "%s" has a non standard data type and doesn\'t define the type of the relation. You have to use one of these annotations: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany', $property->getName(), $className));
                             }
                         } else {
                             throw ORM\MappingException::propertyTypeIsRequired($className, $property->getName());
                         }
                 }
             }
             if ($this->reader->getPropertyAnnotation($property, ORM\Id::class) !== null) {
                 $mapping['id'] = true;
             }
             if ($generatedValueAnnotation = $this->reader->getPropertyAnnotation($property, ORM\GeneratedValue::class)) {
                 $metadata->setIdGeneratorType(constant('Doctrine\\ORM\\Mapping\\ClassMetadata::GENERATOR_TYPE_' . strtoupper($generatedValueAnnotation->strategy)));
             }
             if ($this->reflectionService->isPropertyAnnotatedWith($className, $property->getName(), ORM\Version::class)) {
                 $metadata->setVersionMapping($mapping);
             }
             $metadata->mapField($mapping);
             // Check for SequenceGenerator/TableGenerator definition
             if ($seqGeneratorAnnotation = $this->reader->getPropertyAnnotation($property, ORM\SequenceGenerator::class)) {
                 $metadata->setSequenceGeneratorDefinition(['sequenceName' => $seqGeneratorAnnotation->sequenceName, 'allocationSize' => $seqGeneratorAnnotation->allocationSize, 'initialValue' => $seqGeneratorAnnotation->initialValue]);
             } elseif ($this->reader->getPropertyAnnotation($property, ORM\TableGenerator::class) !== null) {
                 throw ORM\MappingException::tableIdGeneratorNotImplemented($className);
             } elseif ($customGeneratorAnnotation = $this->reader->getPropertyAnnotation($property, ORM\CustomIdGenerator::class)) {
                 $metadata->setCustomGeneratorDefinition(['class' => $customGeneratorAnnotation->class]);
             }
         }
         // Evaluate @Cache annotation
         if (($cacheAnnotation = $this->reader->getPropertyAnnotation($property, ORM\Cache::class)) !== null) {
             $metadata->enableAssociationCache($mapping['fieldName'], array('usage' => constant('Doctrine\\ORM\\Mapping\\ClassMetadata::CACHE_USAGE_' . $cacheAnnotation->usage), 'region' => $cacheAnnotation->region));
         }
     }
 }
예제 #8
0
 /**
  * {@inheritdoc}
  */
 public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
 {
     $class = $metadata->getReflectionClass();
     $classAnnotations = $this->_reader->getClassAnnotations($class);
     // Evaluate Entity annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\Entity'])) {
         $entityAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\Entity'];
         $metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
     } else {
         if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\MappedSuperclass'])) {
             $metadata->isMappedSuperclass = true;
         } else {
             throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
         }
     }
     // Evaluate DoctrineTable annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\Table'])) {
         $tableAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\Table'];
         $primaryTable = array('name' => $tableAnnot->name, 'schema' => $tableAnnot->schema);
         if ($tableAnnot->indexes !== null) {
             foreach ($tableAnnot->indexes as $indexAnnot) {
                 $primaryTable['indexes'][$indexAnnot->name] = array('columns' => $indexAnnot->columns);
             }
         }
         if ($tableAnnot->uniqueConstraints !== null) {
             foreach ($tableAnnot->uniqueConstraints as $uniqueConstraint) {
                 $primaryTable['uniqueConstraints'][$uniqueConstraint->name] = array('columns' => $uniqueConstraint->columns);
             }
         }
         $metadata->setPrimaryTable($primaryTable);
     }
     // Evaluate InheritanceType annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\InheritanceType'])) {
         $inheritanceTypeAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\InheritanceType'];
         $metadata->setInheritanceType(constant('\\Doctrine\\ORM\\Mapping\\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceTypeAnnot->value));
     }
     // Evaluate DiscriminatorColumn annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorColumn'])) {
         $discrColumnAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorColumn'];
         $metadata->setDiscriminatorColumn(array('name' => $discrColumnAnnot->name, 'type' => $discrColumnAnnot->type, 'length' => $discrColumnAnnot->length));
     }
     // Evaluate DiscriminatorMap annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorMap'])) {
         $discrMapAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorMap'];
         $metadata->setDiscriminatorMap($discrMapAnnot->value);
     }
     // Evaluate DoctrineChangeTrackingPolicy annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\ChangeTrackingPolicy'])) {
         $changeTrackingAnnot = $classAnnotations['Doctrine\\ORM\\Mapping\\ChangeTrackingPolicy'];
         $metadata->setChangeTrackingPolicy($changeTrackingAnnot->value);
     }
     // Evaluate annotations on properties/fields
     foreach ($class->getProperties() as $property) {
         if ($metadata->isMappedSuperclass && !$property->isPrivate() || $metadata->isInheritedField($property->name) || $metadata->isInheritedAssociation($property->name)) {
             continue;
         }
         $mapping = array();
         $mapping['fieldName'] = $property->getName();
         // Check for JoinColummn/JoinColumns annotations
         $joinColumns = array();
         if ($joinColumnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\JoinColumn')) {
             $joinColumns[] = array('name' => $joinColumnAnnot->name, 'referencedColumnName' => $joinColumnAnnot->referencedColumnName, 'unique' => $joinColumnAnnot->unique, 'nullable' => $joinColumnAnnot->nullable, 'onDelete' => $joinColumnAnnot->onDelete, 'onUpdate' => $joinColumnAnnot->onUpdate, 'columnDefinition' => $joinColumnAnnot->columnDefinition);
         } else {
             if ($joinColumnsAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\JoinColumns')) {
                 foreach ($joinColumnsAnnot->value as $joinColumn) {
                     $joinColumns[] = array('name' => $joinColumn->name, 'referencedColumnName' => $joinColumn->referencedColumnName, 'unique' => $joinColumn->unique, 'nullable' => $joinColumn->nullable, 'onDelete' => $joinColumn->onDelete, 'onUpdate' => $joinColumn->onUpdate, 'columnDefinition' => $joinColumn->columnDefinition);
                 }
             }
         }
         // Field can only be annotated with one of:
         // @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany
         if ($columnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Column')) {
             if ($columnAnnot->type == null) {
                 throw MappingException::propertyTypeIsRequired($className, $property->getName());
             }
             $mapping['type'] = $columnAnnot->type;
             $mapping['length'] = $columnAnnot->length;
             $mapping['precision'] = $columnAnnot->precision;
             $mapping['scale'] = $columnAnnot->scale;
             $mapping['nullable'] = $columnAnnot->nullable;
             $mapping['unique'] = $columnAnnot->unique;
             if ($columnAnnot->options) {
                 $mapping['options'] = $columnAnnot->options;
             }
             if (isset($columnAnnot->name)) {
                 $mapping['columnName'] = $columnAnnot->name;
             }
             if (isset($columnAnnot->columnDefinition)) {
                 $mapping['columnDefinition'] = $columnAnnot->columnDefinition;
             }
             if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Id')) {
                 $mapping['id'] = true;
             }
             if ($generatedValueAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\GeneratedValue')) {
                 $metadata->setIdGeneratorType(constant('Doctrine\\ORM\\Mapping\\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy));
             }
             if ($versionAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Version')) {
                 $metadata->setVersionMapping($mapping);
             }
             $metadata->mapField($mapping);
             // Check for SequenceGenerator/TableGenerator definition
             if ($seqGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\SequenceGenerator')) {
                 $metadata->setSequenceGeneratorDefinition(array('sequenceName' => $seqGeneratorAnnot->sequenceName, 'allocationSize' => $seqGeneratorAnnot->allocationSize, 'initialValue' => $seqGeneratorAnnot->initialValue));
             } else {
                 if ($tblGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\TableGenerator')) {
                     throw MappingException::tableIdGeneratorNotImplemented($className);
                 }
             }
         } else {
             if ($oneToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\OneToOne')) {
                 $mapping['targetEntity'] = $oneToOneAnnot->targetEntity;
                 $mapping['joinColumns'] = $joinColumns;
                 $mapping['mappedBy'] = $oneToOneAnnot->mappedBy;
                 $mapping['cascade'] = $oneToOneAnnot->cascade;
                 $mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval;
                 $mapping['fetch'] = constant('Doctrine\\ORM\\Mapping\\AssociationMapping::FETCH_' . $oneToOneAnnot->fetch);
                 $metadata->mapOneToOne($mapping);
             } else {
                 if ($oneToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\OneToMany')) {
                     $mapping['mappedBy'] = $oneToManyAnnot->mappedBy;
                     $mapping['targetEntity'] = $oneToManyAnnot->targetEntity;
                     $mapping['cascade'] = $oneToManyAnnot->cascade;
                     $mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval;
                     $mapping['fetch'] = constant('Doctrine\\ORM\\Mapping\\AssociationMapping::FETCH_' . $oneToManyAnnot->fetch);
                     $metadata->mapOneToMany($mapping);
                 } else {
                     if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\ManyToOne')) {
                         $mapping['joinColumns'] = $joinColumns;
                         $mapping['cascade'] = $manyToOneAnnot->cascade;
                         $mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
                         $mapping['fetch'] = constant('Doctrine\\ORM\\Mapping\\AssociationMapping::FETCH_' . $manyToOneAnnot->fetch);
                         $metadata->mapManyToOne($mapping);
                     } else {
                         if ($manyToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\ManyToMany')) {
                             $joinTable = array();
                             if ($joinTableAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\JoinTable')) {
                                 $joinTable = array('name' => $joinTableAnnot->name, 'schema' => $joinTableAnnot->schema);
                                 foreach ($joinTableAnnot->joinColumns as $joinColumn) {
                                     $joinTable['joinColumns'][] = array('name' => $joinColumn->name, 'referencedColumnName' => $joinColumn->referencedColumnName, 'unique' => $joinColumn->unique, 'nullable' => $joinColumn->nullable, 'onDelete' => $joinColumn->onDelete, 'onUpdate' => $joinColumn->onUpdate, 'columnDefinition' => $joinColumn->columnDefinition);
                                 }
                                 foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
                                     $joinTable['inverseJoinColumns'][] = array('name' => $joinColumn->name, 'referencedColumnName' => $joinColumn->referencedColumnName, 'unique' => $joinColumn->unique, 'nullable' => $joinColumn->nullable, 'onDelete' => $joinColumn->onDelete, 'onUpdate' => $joinColumn->onUpdate, 'columnDefinition' => $joinColumn->columnDefinition);
                                 }
                             }
                             $mapping['joinTable'] = $joinTable;
                             $mapping['targetEntity'] = $manyToManyAnnot->targetEntity;
                             $mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
                             $mapping['cascade'] = $manyToManyAnnot->cascade;
                             $mapping['fetch'] = constant('Doctrine\\ORM\\Mapping\\AssociationMapping::FETCH_' . $manyToManyAnnot->fetch);
                             $metadata->mapManyToMany($mapping);
                         }
                     }
                 }
             }
         }
     }
     // Evaluate HasLifecycleCallbacks annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\HasLifecycleCallbacks'])) {
         foreach ($class->getMethods() as $method) {
             if ($method->isPublic()) {
                 $annotations = $this->_reader->getMethodAnnotations($method);
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PrePersist'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PostPersist'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postPersist);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PreUpdate'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preUpdate);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PostUpdate'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postUpdate);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PreRemove'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preRemove);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PostRemove'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postRemove);
                 }
                 if (isset($annotations['Doctrine\\ORM\\Mapping\\PostLoad'])) {
                     $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad);
                 }
             }
         }
     }
 }