Beispiel #1
0
 /**
  * Evaluate the property annotations and amend the metadata accordingly.
  *
  * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $metadata
  * @return void
  * @throws \Doctrine\ORM\Mapping\MappingException
  */
 protected function evaluatePropertyAnnotations(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata)
 {
     $className = $metadata->name;
     $class = $metadata->getReflectionClass();
     $classSchema = $this->getClassSchema($className);
     foreach ($class->getProperties() as $property) {
         if (!$classSchema->hasProperty($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;
             }
             $mapping['joinColumns'] = $this->buildJoinColumnsIfNeeded($joinColumns, $mapping, $property);
             $mapping['mappedBy'] = $oneToOneAnnotation->mappedBy;
             $mapping['inversedBy'] = $oneToOneAnnotation->inversedBy;
             if ($oneToOneAnnotation->cascade) {
                 $mapping['cascade'] = $oneToOneAnnotation->cascade;
             } 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) {
                 $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->isAggregateRoot($mapping['targetEntity'], $className) === FALSE) {
                 $mapping['cascade'] = array('all');
             }
             if ($oneToManyAnnotation->orphanRemoval) {
                 $mapping['orphanRemoval'] = $oneToManyAnnotation->orphanRemoval;
             } elseif ($this->isAggregateRoot($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->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'];
             }
             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_INVERSE), '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->isAggregateRoot($mapping['targetEntity'], $className) === FALSE) {
                 $mapping['cascade'] = array('all');
             }
             if ($manyToManyAnnotation->orphanRemoval) {
                 $mapping['orphanRemoval'] = $manyToManyAnnotation->orphanRemoval;
             } elseif ($this->isAggregateRoot($mapping['targetEntity'], $className) === FALSE) {
                 $mapping['orphanRemoval'] = TRUE;
             }
             $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;
             if ($columnAnnotation = $this->reader->getPropertyAnnotation($property, 'Doctrine\\ORM\\Mapping\\Column')) {
                 $mapping['type'] = $columnAnnotation->type === 'string' ? NULL : $columnAnnotation->type;
                 $mapping['length'] = $columnAnnotation->length;
                 $mapping['precision'] = $columnAnnotation->precision;
                 $mapping['scale'] = $columnAnnotation->scale;
                 $mapping['nullable'] = $columnAnnotation->nullable;
                 $mapping['unique'] = $columnAnnotation->unique;
                 if ($columnAnnotation->options) {
                     $mapping['options'] = $columnAnnotation->options;
                 }
                 if (isset($columnAnnotation->name)) {
                     $mapping['columnName'] = $columnAnnotation->name;
                 }
                 if (isset($columnAnnotation->columnDefinition)) {
                     $mapping['columnDefinition'] = $columnAnnotation->columnDefinition;
                 }
             }
             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\\FLOW3\\Annotations\\ValueObject')) {
                                 $mapping['type'] = 'object';
                             } elseif (class_exists($propertyMetaData['type'])) {
                                 throw \Doctrine\ORM\Mapping\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 \Doctrine\ORM\Mapping\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 \Doctrine\ORM\Mapping\MappingException::tableIdGeneratorNotImplemented($className);
             }
         }
     }
 }