/** * @param object $entity * * @return int * * @throws \InvalidArgumentException */ public function getEntityId($entity) { $className = $this->class; if (!$entity instanceof $className) { throw new \InvalidArgumentException('Expected instance of ' . $this->class); } $idField = $this->metadata->getSingleIdentifierFieldName(); $entityIds = $this->metadata->getIdentifierValues($entity); return $entityIds[$idField]; }
/** * Converts a single ClassMetadata instance to the exported format * and returns it * * TODO: Should this code be pulled out in to a toArray() method in ClassMetadata * * @param ClassMetadataInfo $metadata * @return mixed $exported */ public function exportClassMetadata(ClassMetadataInfo $metadata) { $array = array(); if ($metadata->isMappedSuperclass) { $array['type'] = 'mappedSuperclass'; } else { $array['type'] = 'entity'; } $array['table'] = $metadata->table['name']; if (isset($metadata->table['schema'])) { $array['schema'] = $metadata->table['schema']; } $inheritanceType = $metadata->inheritanceType; if ($inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) { $array['inheritanceType'] = $this->_getInheritanceTypeString($inheritanceType); } if ($column = $metadata->discriminatorColumn) { $array['discriminatorColumn'] = $column; } if ($map = $metadata->discriminatorMap) { $array['discriminatorMap'] = $map; } if ($metadata->changeTrackingPolicy !== ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT) { $array['changeTrackingPolicy'] = $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy); } if (isset($metadata->table['indexes'])) { $array['indexes'] = $metadata->table['indexes']; } if ($metadata->customRepositoryClassName) { $array['repositoryClass'] = $metadata->customRepositoryClassName; } if (isset($metadata->table['uniqueConstraints'])) { $array['uniqueConstraints'] = $metadata->table['uniqueConstraints']; } $fieldMappings = $metadata->fieldMappings; $ids = array(); foreach ($fieldMappings as $name => $fieldMapping) { $fieldMapping['column'] = $fieldMapping['columnName']; unset($fieldMapping['columnName'], $fieldMapping['fieldName']); if ($fieldMapping['column'] == $name) { unset($fieldMapping['column']); } if (isset($fieldMapping['id']) && $fieldMapping['id']) { $ids[$name] = $fieldMapping; unset($fieldMappings[$name]); continue; } $fieldMappings[$name] = $fieldMapping; } if (!$metadata->isIdentifierComposite && ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType))) { $ids[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType; } if ($ids) { $array['fields'] = $ids; } if ($fieldMappings) { if (!isset($array['fields'])) { $array['fields'] = array(); } $array['fields'] = array_merge($array['fields'], $fieldMappings); } $associations = array(); foreach ($metadata->associationMappings as $name => $associationMapping) { $cascade = array(); if ($associationMapping['isCascadeRemove']) { $cascade[] = 'remove'; } if ($associationMapping['isCascadePersist']) { $cascade[] = 'persist'; } if ($associationMapping['isCascadeRefresh']) { $cascade[] = 'refresh'; } if ($associationMapping['isCascadeMerge']) { $cascade[] = 'merge'; } if ($associationMapping['isCascadeDetach']) { $cascade[] = 'detach'; } if (count($cascade) === 5) { $cascade = array('all'); } $associationMappingArray = array('targetEntity' => $associationMapping['targetEntity'], 'cascade' => $cascade); if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) { $joinColumns = $associationMapping['joinColumns']; $newJoinColumns = array(); foreach ($joinColumns as $joinColumn) { $newJoinColumns[$joinColumn['name']]['referencedColumnName'] = $joinColumn['referencedColumnName']; if (isset($joinColumn['onDelete'])) { $newJoinColumns[$joinColumn['name']]['onDelete'] = $joinColumn['onDelete']; } } $oneToOneMappingArray = array('mappedBy' => $associationMapping['mappedBy'], 'inversedBy' => $associationMapping['inversedBy'], 'joinColumns' => $newJoinColumns, 'orphanRemoval' => $associationMapping['orphanRemoval']); $associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray); if ($associationMapping['type'] & ClassMetadataInfo::ONE_TO_ONE) { $array['oneToOne'][$name] = $associationMappingArray; } else { $array['manyToOne'][$name] = $associationMappingArray; } } else { if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) { $oneToManyMappingArray = array('mappedBy' => $associationMapping['mappedBy'], 'inversedBy' => $associationMapping['inversedBy'], 'orphanRemoval' => $associationMapping['orphanRemoval'], 'orderBy' => isset($associationMapping['orderBy']) ? $associationMapping['orderBy'] : null); $associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray); $array['oneToMany'][$name] = $associationMappingArray; } else { if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) { $manyToManyMappingArray = array('mappedBy' => $associationMapping['mappedBy'], 'inversedBy' => $associationMapping['inversedBy'], 'joinTable' => isset($associationMapping['joinTable']) ? $associationMapping['joinTable'] : null, 'orderBy' => isset($associationMapping['orderBy']) ? $associationMapping['orderBy'] : null); $associationMappingArray = array_merge($associationMappingArray, $manyToManyMappingArray); $array['manyToMany'][$name] = $associationMappingArray; } } } } if (isset($metadata->lifecycleCallbacks)) { $array['lifecycleCallbacks'] = $metadata->lifecycleCallbacks; } return \Symfony\Component\Yaml\Yaml::dump(array($metadata->name => $array), 10); }
/** * Converts a single ClassMetadata instance to the exported format * and returns it * * @param ClassMetadataInfo $metadata * @return mixed $exported */ public function exportClassMetadata(ClassMetadataInfo $metadata) { $xml = new \SimpleXmlElement("<?xml version=\"1.0\" encoding=\"utf-8\"?><doctrine-mapping " . "xmlns=\"http://doctrine-project.org/schemas/orm/doctrine-mapping\" " . "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " . "xsi:schemaLocation=\"http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd\" />"); /*$xml->addAttribute('xmlns', 'http://doctrine-project.org/schemas/orm/doctrine-mapping'); $xml->addAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $xml->addAttribute('xsi:schemaLocation', 'http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd');*/ if ($metadata->isMappedSuperclass) { $root = $xml->addChild('mapped-superclass'); } else { $root = $xml->addChild('entity'); } if ($metadata->customRepositoryClassName) { $root->addAttribute('repository-class', $metadata->customRepositoryClassName); } $root->addAttribute('name', $metadata->name); if (isset($metadata->table['name'])) { $root->addAttribute('table', $metadata->table['name']); } if (isset($metadata->table['schema'])) { $root->addAttribute('schema', $metadata->table['schema']); } if (isset($metadata->table['inheritance-type'])) { $root->addAttribute('inheritance-type', $metadata->table['inheritance-type']); } if ($metadata->discriminatorColumn) { $discriminatorColumnXml = $root->addChild('discriminator-column'); $discriminatorColumnXml->addAttribute('name', $metadata->discriminatorColumn['name']); $discriminatorColumnXml->addAttribute('type', $metadata->discriminatorColumn['type']); if (isset($metadata->discriminatorColumn['length'])) { $discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']); } } if ($metadata->discriminatorMap) { $discriminatorMapXml = $root->addChild('discriminator-map'); foreach ($metadata->discriminatorMap as $value => $className) { $discriminatorMappingXml = $discriminatorMapXml->addChild('discriminator-mapping'); $discriminatorMappingXml->addAttribute('value', $value); $discriminatorMappingXml->addAttribute('class', $className); } } $trackingPolicy = $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy); if ($trackingPolicy != 'DEFERRED_IMPLICIT') { $root->addChild('change-tracking-policy', $trackingPolicy); } if (isset($metadata->table['indexes'])) { $indexesXml = $root->addChild('indexes'); foreach ($metadata->table['indexes'] as $name => $index) { $indexXml = $indexesXml->addChild('index'); $indexXml->addAttribute('name', $name); $indexXml->addAttribute('columns', implode(',', $index['columns'])); } } if (isset($metadata->table['uniqueConstraints'])) { $uniqueConstraintsXml = $root->addChild('unique-constraints'); foreach ($metadata->table['uniqueConstraints'] as $name => $unique) { $uniqueConstraintXml = $uniqueConstraintsXml->addChild('unique-constraint'); $uniqueConstraintXml->addAttribute('name', $name); $uniqueConstraintXml->addAttribute('columns', implode(',', $unique['columns'])); } } $fields = $metadata->fieldMappings; $id = array(); foreach ($fields as $name => $field) { if (isset($field['id']) && $field['id']) { $id[$name] = $field; unset($fields[$name]); } } if (!$metadata->isIdentifierComposite && ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType))) { $id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType; } if ($id) { foreach ($id as $field) { $idXml = $root->addChild('id'); $idXml->addAttribute('name', $field['fieldName']); $idXml->addAttribute('type', $field['type']); if (isset($field['columnName'])) { $idXml->addAttribute('column', $field['columnName']); } if (isset($field['length'])) { $idXml->addAttribute('length', $field['length']); } if (isset($field['associationKey']) && $field['associationKey']) { $idXml->addAttribute('association-key', 'true'); } if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { $generatorXml = $idXml->addChild('generator'); $generatorXml->addAttribute('strategy', $idGeneratorType); } } } if ($fields) { foreach ($fields as $field) { $fieldXml = $root->addChild('field'); $fieldXml->addAttribute('name', $field['fieldName']); $fieldXml->addAttribute('type', $field['type']); if (isset($field['columnName'])) { $fieldXml->addAttribute('column', $field['columnName']); } if (isset($field['length'])) { $fieldXml->addAttribute('length', $field['length']); } if (isset($field['precision'])) { $fieldXml->addAttribute('precision', $field['precision']); } if (isset($field['scale'])) { $fieldXml->addAttribute('scale', $field['scale']); } if (isset($field['unique']) && $field['unique']) { $fieldXml->addAttribute('unique', $field['unique']); } if (isset($field['options'])) { $optionsXml = $fieldXml->addChild('options'); foreach ($field['options'] as $key => $value) { $optionsXml->addAttribute($key, $value); } } if (isset($field['version'])) { $fieldXml->addAttribute('version', $field['version']); } if (isset($field['columnDefinition'])) { $fieldXml->addAttribute('column-definition', $field['columnDefinition']); } if (isset($field['nullable'])) { $fieldXml->addAttribute('nullable', $field['nullable'] ? 'true' : 'false'); } } } $orderMap = array(ClassMetadataInfo::ONE_TO_ONE, ClassMetadataInfo::ONE_TO_MANY, ClassMetadataInfo::MANY_TO_ONE, ClassMetadataInfo::MANY_TO_MANY); uasort($metadata->associationMappings, function ($m1, $m2) use(&$orderMap) { $a1 = array_search($m1['type'], $orderMap); $a2 = array_search($m2['type'], $orderMap); return strcmp($a1, $a2); }); foreach ($metadata->associationMappings as $name => $associationMapping) { if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_ONE) { $associationMappingXml = $root->addChild('one-to-one'); } else { if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_ONE) { $associationMappingXml = $root->addChild('many-to-one'); } else { if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) { $associationMappingXml = $root->addChild('one-to-many'); } else { if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) { $associationMappingXml = $root->addChild('many-to-many'); } } } } $associationMappingXml->addAttribute('field', $associationMapping['fieldName']); $associationMappingXml->addAttribute('target-entity', $associationMapping['targetEntity']); if (isset($associationMapping['mappedBy'])) { $associationMappingXml->addAttribute('mapped-by', $associationMapping['mappedBy']); } if (isset($associationMapping['inversedBy'])) { $associationMappingXml->addAttribute('inversed-by', $associationMapping['inversedBy']); } if (isset($associationMapping['indexBy'])) { $associationMappingXml->addAttribute('index-by', $associationMapping['indexBy']); } if (isset($associationMapping['orphanRemoval']) && $associationMapping['orphanRemoval'] !== false) { $associationMappingXml->addAttribute('orphan-removal', 'true'); } if (isset($associationMapping['joinTable']) && $associationMapping['joinTable']) { $joinTableXml = $associationMappingXml->addChild('join-table'); $joinTableXml->addAttribute('name', $associationMapping['joinTable']['name']); $joinColumnsXml = $joinTableXml->addChild('join-columns'); foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) { $joinColumnXml = $joinColumnsXml->addChild('join-column'); $joinColumnXml->addAttribute('name', $joinColumn['name']); $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']); if (isset($joinColumn['onDelete'])) { $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']); } } $inverseJoinColumnsXml = $joinTableXml->addChild('inverse-join-columns'); foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) { $inverseJoinColumnXml = $inverseJoinColumnsXml->addChild('join-column'); $inverseJoinColumnXml->addAttribute('name', $inverseJoinColumn['name']); $inverseJoinColumnXml->addAttribute('referenced-column-name', $inverseJoinColumn['referencedColumnName']); if (isset($inverseJoinColumn['onDelete'])) { $inverseJoinColumnXml->addAttribute('on-delete', $inverseJoinColumn['onDelete']); } if (isset($inverseJoinColumn['columnDefinition'])) { $inverseJoinColumnXml->addAttribute('column-definition', $inverseJoinColumn['columnDefinition']); } if (isset($inverseJoinColumn['nullable'])) { $inverseJoinColumnXml->addAttribute('nullable', $inverseJoinColumn['nullable']); } if (isset($inverseJoinColumn['orderBy'])) { $inverseJoinColumnXml->addAttribute('order-by', $inverseJoinColumn['orderBy']); } } } if (isset($associationMapping['joinColumns'])) { $joinColumnsXml = $associationMappingXml->addChild('join-columns'); foreach ($associationMapping['joinColumns'] as $joinColumn) { $joinColumnXml = $joinColumnsXml->addChild('join-column'); $joinColumnXml->addAttribute('name', $joinColumn['name']); $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']); if (isset($joinColumn['onDelete'])) { $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']); } if (isset($joinColumn['columnDefinition'])) { $joinColumnXml->addAttribute('column-definition', $joinColumn['columnDefinition']); } if (isset($joinColumn['nullable'])) { $joinColumnXml->addAttribute('nullable', $joinColumn['nullable']); } } } if (isset($associationMapping['orderBy'])) { $orderByXml = $associationMappingXml->addChild('order-by'); foreach ($associationMapping['orderBy'] as $name => $direction) { $orderByFieldXml = $orderByXml->addChild('order-by-field'); $orderByFieldXml->addAttribute('name', $name); $orderByFieldXml->addAttribute('direction', $direction); } } $cascade = array(); if ($associationMapping['isCascadeRemove']) { $cascade[] = 'cascade-remove'; } if ($associationMapping['isCascadePersist']) { $cascade[] = 'cascade-persist'; } if ($associationMapping['isCascadeRefresh']) { $cascade[] = 'cascade-refresh'; } if ($associationMapping['isCascadeMerge']) { $cascade[] = 'cascade-merge'; } if ($associationMapping['isCascadeDetach']) { $cascade[] = 'cascade-detach'; } if (count($cascade) === 5) { $cascade = array('cascade-all'); } if ($cascade) { $cascadeXml = $associationMappingXml->addChild('cascade'); foreach ($cascade as $type) { $cascadeXml->addChild($type); } } } if (isset($metadata->lifecycleCallbacks) && count($metadata->lifecycleCallbacks) > 0) { $lifecycleCallbacksXml = $root->addChild('lifecycle-callbacks'); foreach ($metadata->lifecycleCallbacks as $name => $methods) { foreach ($methods as $method) { $lifecycleCallbackXml = $lifecycleCallbacksXml->addChild('lifecycle-callback'); $lifecycleCallbackXml->addAttribute('type', $name); $lifecycleCallbackXml->addAttribute('method', $method); } } } return $this->_asXml($xml); }
/** * Completes the ID generator mapping. If "auto" is specified we choose the generator * most appropriate for the targeted database platform. * * @param ClassMetadataInfo $class * * @return void * * @throws ORMException */ private function completeIdGeneratorMapping(ClassMetadataInfo $class) { $idGenType = $class->generatorType; if ($idGenType == ClassMetadata::GENERATOR_TYPE_AUTO) { if ($this->targetPlatform->prefersSequences()) { $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_SEQUENCE); } else { if ($this->targetPlatform->prefersIdentityColumns()) { $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_IDENTITY); } else { $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_TABLE); } } } // Create & assign an appropriate ID generator instance switch ($class->generatorType) { case ClassMetadata::GENERATOR_TYPE_IDENTITY: $sequenceName = null; $fieldName = $class->identifier ? $class->getSingleIdentifierFieldName() : null; // Platforms that do not have native IDENTITY support need a sequence to emulate this behaviour. if ($this->targetPlatform->usesSequenceEmulatedIdentityColumns()) { $columnName = $class->getSingleIdentifierColumnName(); $quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']); $sequenceName = $this->targetPlatform->getIdentitySequenceName($class->getTableName(), $columnName); $definition = array('sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName)); if ($quoted) { $definition['quoted'] = true; } $sequenceName = $this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform); } $generator = $fieldName && $class->fieldMappings[$fieldName]['type'] === 'bigint' ? new BigIntegerIdentityGenerator($sequenceName) : new IdentityGenerator($sequenceName); $class->setIdGenerator($generator); break; case ClassMetadata::GENERATOR_TYPE_SEQUENCE: // If there is no sequence definition yet, create a default definition $definition = $class->sequenceGeneratorDefinition; if (!$definition) { $fieldName = $class->getSingleIdentifierFieldName(); $columnName = $class->getSingleIdentifierColumnName(); $quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']); $sequenceName = $class->getTableName() . '_' . $columnName . '_seq'; $definition = array('sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName), 'allocationSize' => 1, 'initialValue' => 1); if ($quoted) { $definition['quoted'] = true; } $class->setSequenceGeneratorDefinition($definition); } $sequenceGenerator = new \Doctrine\ORM\Id\SequenceGenerator($this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform), $definition['allocationSize']); $class->setIdGenerator($sequenceGenerator); break; case ClassMetadata::GENERATOR_TYPE_NONE: $class->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator()); break; case ClassMetadata::GENERATOR_TYPE_UUID: $class->setIdGenerator(new \Doctrine\ORM\Id\UuidGenerator()); break; case ClassMetadata::GENERATOR_TYPE_TABLE: throw new ORMException("TableGenerator not yet implemented."); break; case ClassMetadata::GENERATOR_TYPE_CUSTOM: $definition = $class->customGeneratorDefinition; if (!class_exists($definition['class'])) { throw new ORMException("Can't instantiate custom generator : " . $definition['class']); } $class->setIdGenerator(new $definition['class']()); break; default: throw new ORMException("Unknown generator type: " . $class->generatorType); } }
/** * Converts a single ClassMetadata instance to the exported format * and returns it * * @param ClassMetadataInfo $metadata * @return mixed $exported */ public function exportClassMetadata(ClassMetadataInfo $metadata) { $xml = new \SimpleXmlElement("<?xml version=\"1.0\" encoding=\"utf-8\"?><doctrine-mapping/>"); $xml->addAttribute('xmlns', 'http://doctrine-project.org/schemas/orm/doctrine-mapping'); $xml->addAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $xml->addAttribute('xsi:schemaLocation', 'http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd'); if ($metadata->isMappedSuperclass) { $root = $xml->addChild('mapped-superclass'); } else { $root = $xml->addChild('entity'); } if ($metadata->customRepositoryClassName) { $root->addAttribute('repository-class', $metadata->customRepositoryClassName); } $root->addAttribute('name', $metadata->name); if (isset($metadata->primaryTable['name'])) { $root->addAttribute('table', $metadata->primaryTable['name']); } if (isset($metadata->primaryTable['schema'])) { $root->addAttribute('schema', $metadata->primaryTable['schema']); } if (isset($metadata->primaryTable['inheritance-type'])) { $root->addAttribute('inheritance-type', $metadata->primaryTable['inheritance-type']); } if ($metadata->discriminatorColumn) { $discriminatorColumnXml = $root->addChild('discriminiator-column'); $discriminatorColumnXml->addAttribute('name', $metadata->discriminatorColumn['name']); $discriminatorColumnXml->addAttribute('type', $metadata->discriminatorColumn['type']); $discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']); } if ($metadata->discriminatorMap) { $discriminatorMapXml = $root->addChild('discriminator-map'); foreach ($metadata->discriminatorMap as $value => $className) { $discriminatorMappingXml = $discriminatorMapXml->addChild('discriminator-mapping'); $discriminatorMappingXml->addAttribute('value', $value); $discriminatorMappingXml->addAttribute('class', $className); } } $root->addChild('change-tracking-policy', $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy)); if (isset($metadata->primaryTable['indexes'])) { $indexesXml = $root->addChild('indexes'); foreach ($metadata->primaryTable['indexes'] as $name => $index) { $indexXml = $indexesXml->addChild('index'); $indexXml->addAttribute('name', $name); $indexXml->addAttribute('columns', implode(',', $index['columns'])); } } if (isset($metadata->primaryTable['uniqueConstraints'])) { $uniqueConstraintsXml = $root->addChild('unique-constraints'); foreach ($metadata->primaryTable['uniqueConstraints'] as $unique) { $uniqueConstraintXml = $uniqueConstraintsXml->addChild('unique-constraint'); $uniqueConstraintXml->addAttribute('name', $name); $uniqueConstraintXml->addAttribute('columns', implode(',', $unique['columns'])); } } $fields = $metadata->fieldMappings; $id = array(); foreach ($fields as $name => $field) { if (isset($field['id']) && $field['id']) { $id[$name] = $field; unset($fields[$name]); } } if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { $id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType; } if ($fields) { foreach ($fields as $field) { $fieldXml = $root->addChild('field'); $fieldXml->addAttribute('name', $field['fieldName']); $fieldXml->addAttribute('type', $field['type']); if (isset($field['columnName'])) { $fieldXml->addAttribute('column', $field['columnName']); } if (isset($field['length'])) { $fieldXml->addAttribute('length', $field['length']); } if (isset($field['precision'])) { $fieldXml->addAttribute('precision', $field['precision']); } if (isset($field['scale'])) { $fieldXml->addAttribute('scale', $field['scale']); } if (isset($field['unique']) && $field['unique']) { $fieldXml->addAttribute('unique', $field['unique']); } if (isset($field['options'])) { $optionsXml = $fieldXml->addChild('options'); foreach ($field['options'] as $key => $value) { $optionsXml->addAttribute($key, $value); } } if (isset($field['version'])) { $fieldXml->addAttribute('version', $field['version']); } if (isset($field['columnDefinition'])) { $fieldXml->addAttribute('column-definition', $field['columnDefinition']); } } } if ($id) { foreach ($id as $field) { $idXml = $root->addChild('id'); $idXml->addAttribute('name', $field['fieldName']); $idXml->addAttribute('type', $field['type']); if (isset($field['columnName'])) { $idXml->addAttribute('column', $field['columnName']); } if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { $generatorXml = $idXml->addChild('generator'); $generatorXml->addAttribute('strategy', $idGeneratorType); } } } foreach ($metadata->associationMappings as $name => $associationMapping) { if ($associationMapping instanceof OneToOneMapping) { $associationMappingXml = $root->addChild('one-to-one'); } else { if ($associationMapping instanceof OneToManyMapping) { $associationMappingXml = $root->addChild('one-to-many'); } else { if ($associationMapping instanceof ManyToManyMapping) { $associationMappingXml = $root->addChild('many-to-many'); } } } $associationMappingXml->addAttribute('field', $associationMapping->sourceFieldName); $associationMappingXml->addAttribute('target-entity', $associationMapping->targetEntityName); if (isset($associationMapping->mappedBy)) { $associationMappingXml->addAttribute('mapped-by', $associationMapping->mappedBy); } if (isset($associationMapping->orphanRemoval)) { $associationMappingXml->addAttribute('orphan-removal', $associationMapping->orphanRemoval); } if (isset($associationMapping->joinTable) && $associationMapping->joinTable) { $joinTableXml = $associationMappingXml->addChild('join-table'); $joinTableXml->addAttribute('name', $associationMapping->joinTable['name']); $joinColumnsXml = $joinTableXml->addChild('join-columns'); foreach ($associationMapping->joinTable['joinColumns'] as $joinColumn) { $joinColumnXml = $joinColumnsXml->addChild('join-column'); $joinColumnXml->addAttribute('name', $joinColumn['name']); $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']); if (isset($joinColumn['onDelete'])) { $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']); } if (isset($joinColumn['onUpdate'])) { $joinColumnXml->addAttribute('on-update', $joinColumn['onUpdate']); } } $inverseJoinColumnsXml = $joinTableXml->addChild('inverse-join-columns'); foreach ($associationMapping->joinTable['inverseJoinColumns'] as $inverseJoinColumn) { $inverseJoinColumnXml = $inverseJoinColumnsXml->addChild('join-column'); $inverseJoinColumnXml->addAttribute('name', $inverseJoinColumn['name']); $inverseJoinColumnXml->addAttribute('referenced-column-name', $inverseJoinColumn['referencedColumnName']); if (isset($inverseJoinColumn['onDelete'])) { $inverseJoinColumnXml->addAttribute('on-delete', $inverseJoinColumn['onDelete']); } if (isset($inverseJoinColumn['onUpdate'])) { $inverseJoinColumnXml->addAttribute('on-update', $inverseJoinColumn['onUpdate']); } if (isset($inverseJoinColumn['columnDefinition'])) { $inverseJoinColumnXml->addAttribute('column-definition', $inverseJoinColumn['columnDefinition']); } if (isset($inverseJoinColumn['nullable'])) { $inverseJoinColumnXml->addAttribute('nullable', $inverseJoinColumn['nullable']); } if (isset($inverseJoinColumn['orderBy'])) { $inverseJoinColumnXml->addAttribute('order-by', $inverseJoinColumn['orderBy']); } } } if (isset($associationMapping->joinColumns)) { $joinColumnsXml = $associationMappingXml->addChild('join-columns'); foreach ($associationMapping->joinColumns as $joinColumn) { $joinColumnXml = $joinColumnsXml->addChild('join-column'); $joinColumnXml->addAttribute('name', $joinColumn['name']); $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']); if (isset($joinColumn['onDelete'])) { $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']); } if (isset($joinColumn['onUpdate'])) { $joinColumnXml->addAttribute('on-update', $joinColumn['onUpdate']); } if (isset($joinColumn['columnDefinition'])) { $joinColumnXml->addAttribute('column-definition', $joinColumn['columnDefinition']); } if (isset($joinColumn['nullable'])) { $joinColumnXml->addAttribute('nullable', $joinColumn['nullable']); } } } if (isset($associationMapping->orderBy)) { $orderByXml = $associationMappingXml->addChild('order-by'); foreach ($associationMapping->orderBy as $name => $direction) { $orderByFieldXml = $orderByXml->addChild('order-by-field'); $orderByFieldXml->addAttribute('name', $name); $orderByFieldXml->addAttribute('direction', $direction); } } $cascade = array(); if ($associationMapping->isCascadeRemove) { $cascade[] = 'remove'; } if ($associationMapping->isCascadePersist) { $cascade[] = 'persist'; } if ($associationMapping->isCascadeRefresh) { $cascade[] = 'refresh'; } if ($associationMapping->isCascadeMerge) { $cascade[] = 'merge'; } if ($associationMapping->isCascadeDetach) { $cascade[] = 'detach'; } if ($cascade) { $cascadeXml = $associationMappingXml->addChild('cascade'); foreach ($cascade as $type) { $cascadeXml->addChild($type); } } } if (isset($metadata->lifecycleCallbacks)) { $lifecycleCallbacksXml = $root->addChild('lifecycle-callbacks'); foreach ($metadata->lifecycleCallbacks as $name => $methods) { foreach ($methods as $method) { $lifecycleCallbackXml = $lifecycleCallbacksXml->addChild('lifecycle-callback'); $lifecycleCallbackXml->addAttribute('type', $name); $lifecycleCallbackXml->addAttribute('method', $method); } } } return $this->_asXml($xml); }
/** * Completes the ID generator mapping. If "auto" is specified we choose the generator * most appropriate for the targeted database platform. * * @param ClassMetadataInfo $class * @throws ORMException */ private function completeIdGeneratorMapping(ClassMetadataInfo $class) { $idGenType = $class->generatorType; if ($idGenType == ClassMetadata::GENERATOR_TYPE_AUTO) { if ($this->targetPlatform->prefersSequences()) { $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_SEQUENCE); } else { if ($this->targetPlatform->prefersIdentityColumns()) { $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_IDENTITY); } else { $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_TABLE); } } } // Create & assign an appropriate ID generator instance switch ($class->generatorType) { case ClassMetadata::GENERATOR_TYPE_IDENTITY: // For PostgreSQL IDENTITY (SERIAL) we need a sequence name. It defaults to // <table>_<column>_seq in PostgreSQL for SERIAL columns. // Not pretty but necessary and the simplest solution that currently works. $sequenceName = null; if ($this->targetPlatform instanceof Platforms\PostgreSQLPlatform) { $fieldName = $class->getSingleIdentifierFieldName(); $columnName = $class->getSingleIdentifierColumnName(); $quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']); $sequenceName = $class->getTableName() . '_' . $columnName . '_seq'; $definition = array('sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName)); if ($quoted) { $definition['quoted'] = true; } $sequenceName = $this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform); } $class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($sequenceName)); break; case ClassMetadata::GENERATOR_TYPE_SEQUENCE: // If there is no sequence definition yet, create a default definition $definition = $class->sequenceGeneratorDefinition; if (!$definition) { $fieldName = $class->getSingleIdentifierFieldName(); $columnName = $class->getSingleIdentifierColumnName(); $quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']); $sequenceName = $class->getTableName() . '_' . $columnName . '_seq'; $definition = array('sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName), 'allocationSize' => 1, 'initialValue' => 1); if ($quoted) { $definition['quoted'] = true; } $class->setSequenceGeneratorDefinition($definition); } $sequenceGenerator = new \Doctrine\ORM\Id\SequenceGenerator($this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform), $definition['allocationSize']); $class->setIdGenerator($sequenceGenerator); break; case ClassMetadata::GENERATOR_TYPE_NONE: $class->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator()); break; case ClassMetadata::GENERATOR_TYPE_UUID: $class->setIdGenerator(new \Doctrine\ORM\Id\UuidGenerator()); break; case ClassMetadata::GENERATOR_TYPE_TABLE: throw new ORMException("TableGenerator not yet implemented."); break; case ClassMetadata::GENERATOR_TYPE_CUSTOM: $definition = $class->customGeneratorDefinition; if (!class_exists($definition['class'])) { throw new ORMException("Can't instantiate custom generator : " . $definition['class']); } $class->setIdGenerator(new $definition['class']()); break; default: throw new ORMException("Unknown generator type: " . $class->generatorType); } }
/** * Converts a single ClassMetadata instance to the exported format * and returns it * * TODO: Should this code be pulled out in to a toArray() method in ClassMetadata * * @param ClassMetadataInfo $metadata * @return mixed $exported */ public function exportClassMetadata(ClassMetadataInfo $metadata) { $array = array(); if ($metadata->isMappedSuperclass) { $array['type'] = 'mappedSuperclass'; } else { $array['type'] = 'entity'; } $array['table'] = $metadata->primaryTable['name']; if (isset($metadata->primaryTable['schema'])) { $array['schema'] = $metadata->primaryTable['schema']; } $inheritanceType = $metadata->getInheritanceType(); if ($inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) { $array['inheritanceType'] = $this->_getInheritanceTypeString($inheritanceType); } if ($column = $metadata->getDiscriminatorColumn()) { $array['discriminatorColumn'] = $column; } if ($map = $metadata->discriminatorMap) { $array['discriminatorMap'] = $map; } if ($metadata->changeTrackingPolicy !== ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT) { $array['changeTrackingPolicy'] = $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy); } if (isset($metadata->primaryTable['indexes'])) { $array['indexes'] = $metadata->primaryTable['indexes']; } if (isset($metadata->primaryTable['uniqueConstraints'])) { $array['uniqueConstraints'] = $metadata->primaryTable['uniqueConstraints']; } $fieldMappings = $metadata->fieldMappings; $ids = array(); foreach ($fieldMappings as $name => $fieldMapping) { if (isset($fieldMapping['length'])) { $fieldMapping['type'] = $fieldMapping['type'] . '(' . $fieldMapping['length'] . ')'; unset($fieldMapping['length']); } $fieldMapping['column'] = $fieldMapping['columnName']; unset($fieldMapping['columnName'], $fieldMapping['fieldName']); if ($fieldMapping['column'] == $name) { unset($fieldMapping['column']); } if (isset($fieldMapping['id']) && $fieldMapping['id']) { $ids[$name] = $fieldMapping; unset($fieldMappings[$name]); continue; } $fieldMappings[$name] = $fieldMapping; } if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { $ids[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $this->_getIdGeneratorTypeString($metadata->generatorType); } if ($ids) { $array['fields'] = $ids; } if ($fieldMappings) { if (!isset($array['fields'])) { $array['fields'] = array(); } $array['fields'] = array_merge($array['fields'], $fieldMappings); } $associations = array(); foreach ($metadata->associationMappings as $name => $associationMapping) { $associationMappingArray = array('targetEntity' => $associationMapping->targetEntityName, 'cascade' => array('remove' => $associationMapping->isCascadeRemove, 'persist' => $associationMapping->isCascadePersist, 'refresh' => $associationMapping->isCascadeRefresh, 'merge' => $associationMapping->isCascadeMerge, 'detach' => $associationMapping->isCascadeDetach)); if ($associationMapping instanceof OneToOneMapping) { $joinColumns = $associationMapping->joinColumns; $newJoinColumns = array(); foreach ($joinColumns as $joinColumn) { $newJoinColumns[$joinColumn['name']]['referencedColumnName'] = $joinColumn['referencedColumnName']; } $oneToOneMappingArray = array('mappedBy' => $associationMapping->mappedByFieldName, 'joinColumns' => $newJoinColumns, 'orphanRemoval' => $associationMapping->orphanRemoval); $associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray); $array['oneToOne'][$name] = $associationMappingArray; } else { if ($associationMapping instanceof OneToManyMapping) { $oneToManyMappingArray = array('mappedBy' => $associationMapping->mappedByFieldName, 'orphanRemoval' => $associationMapping->orphanRemoval); $associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray); $array['oneToMany'][$name] = $associationMappingArray; } else { if ($associationMapping instanceof ManyToManyMapping) { $manyToManyMappingArray = array('mappedBy' => $associationMapping->mappedByFieldName, 'joinTable' => $associationMapping->joinTable); $associationMappingArray = array_merge($associationMappingArray, $manyToManyMappingArray); $array['manyToMany'][$name] = $associationMappingArray; } } } } return \sfYaml::dump(array($metadata->name => $array), 10); }
/** * Get the single identifier field name. * * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $meta * @return string */ public function getSingleIdentifierFieldName(ClassMetadataInfo $meta) { return $meta->getSingleIdentifierFieldName(); }