diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index b52542d05..627f61577 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -52,7 +52,7 @@ class Configuration extends \Doctrine\DBAL\Configuration 'namedNativeQueries' => array(), 'autoGenerateProxyClasses' => true, 'proxyNamespace' => null, - 'entityAliasMap' => array() + 'entityNamespaces' => array() )); } @@ -121,24 +121,24 @@ class Configuration extends \Doctrine\DBAL\Configuration } /** - * Add an alias for an entity. + * Add a namespace alias for entities. * - * @param string $className * @param string $alias + * @param string $namespace */ - public function addEntityAlias($className, $alias) + public function addEntityNamespace($alias, $namespace) { - $this->_attributes['entityAliasMap'][$alias] = $className; + $this->_attributes['entityNamespaces'][$alias] = $namespace; } /** - * get the array of entity aliases + * get the array of entity namespaces * - * @return array $aliasMap + * @return array $entityNamespaces */ - public function getEntityAliasMap() + public function getEntityNamespaces() { - return $this->_attributes['entityAliasMap']; + return $this->_attributes['entityNamespaces']; } /** @@ -147,9 +147,9 @@ class Configuration extends \Doctrine\DBAL\Configuration * @param array $entityAliasMap * @return void */ - public function setEntityAliasMap(array $entityAliasMap) + public function setEntityNamespaces(array $entityNamespaces) { - $this->_attributes['entityAliasMap'] = $entityAliasMap; + $this->_attributes['entityNamespaces'] = $entityNamespaces; } /** diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 5bb495c73..fa026e389 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -127,12 +127,11 @@ class ClassMetadataFactory */ public function getMetadataFor($className) { + $className = $this->_resolveClassName($className); + if ( ! isset($this->_loadedMetadata[$className])) { - $aliasMap = $this->_em->getConfiguration()->getEntityAliasMap(); - if (isset($aliasMap[$className])) { - $className = $aliasMap[$className]; - } $cacheKey = "$className\$CLASSMETADATA"; + if ($this->_cacheDriver) { if (($cached = $this->_cacheDriver->fetch($cacheKey)) !== false) { $this->_loadedMetadata[$className] = $cached; @@ -379,4 +378,20 @@ class ClassMetadataFactory throw new ORMException("Unknown generator type: " . $class->generatorType); } } + + protected function _resolveClassName($className) + { + if (($pos = strrpos($className, ':')) !== false) { + $entityNamespaces = $this->_em->getConfiguration()->getEntityNamespaces(); + $entityNamespace = substr($className, 0, $pos); + + if ( ! isset($entityNamespaces[$entityNamespace])) { + throw MappingException::unknownEntityNamespace($entityNamespace, $className); + } + + $className = trim($entityNamespaces[$entityNamespace], '\\') . '\\' . substr($className, $pos + 1); + } + + return $className; + } } diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php index 650fcd010..9b3a89d5c 100644 --- a/lib/Doctrine/ORM/Mapping/MappingException.php +++ b/lib/Doctrine/ORM/Mapping/MappingException.php @@ -185,4 +185,11 @@ class MappingException extends \Doctrine\ORM\ORMException "does not exist." ); } + + public static function unknownEntityNamespace($namespace, $entity) + { + return new self( + "Unknown Entity namespace '$namespace' when processing '$entity'." + ); + } } \ No newline at end of file diff --git a/lib/Doctrine/ORM/Query/Lexer.php b/lib/Doctrine/ORM/Query/Lexer.php index b956291d5..65c0723a7 100644 --- a/lib/Doctrine/ORM/Query/Lexer.php +++ b/lib/Doctrine/ORM/Query/Lexer.php @@ -51,43 +51,44 @@ class Lexer extends \Doctrine\Common\Lexer const T_BOTH = 108; const T_BY = 109; const T_CLOSE_PARENTHESIS = 110; - const T_COMMA = 111; - const T_COUNT = 112; - const T_DELETE = 113; - const T_DESC = 114; - const T_DISTINCT = 115; - const T_DIVIDE = 116; - const T_DOT = 117; - const T_EMPTY = 118; - const T_EQUALS = 119; - const T_ESCAPE = 120; - const T_EXISTS = 121; - const T_FALSE = 122; - const T_FROM = 123; - const T_GREATER_THAN = 124; - const T_GROUP = 125; - const T_HAVING = 126; - const T_IN = 127; - const T_INDEX = 128; - const T_INNER = 129; - const T_IS = 130; - const T_JOIN = 131; - const T_LEADING = 132; - const T_LEFT = 133; - const T_LIKE = 134; - const T_LIMIT = 135; - const T_LOWER_THAN = 136; - const T_MAX = 137; - const T_MEMBER = 138; - const T_MIN = 139; - const T_MINUS = 140; - const T_MOD = 141; - const T_MULTIPLY = 142; - const T_NEGATE = 143; - const T_NOT = 144; - const T_NULL = 145; - const T_OF = 146; - const T_OFFSET = 147; + const T_COLON = 111; + const T_COMMA = 112; + const T_COUNT = 113; + const T_DELETE = 114; + const T_DESC = 115; + const T_DISTINCT = 116; + const T_DIVIDE = 117; + const T_DOT = 118; + const T_EMPTY = 119; + const T_EQUALS = 120; + const T_ESCAPE = 121; + const T_EXISTS = 122; + const T_FALSE = 123; + const T_FROM = 124; + const T_GREATER_THAN = 125; + const T_GROUP = 126; + const T_HAVING = 127; + const T_IN = 128; + const T_INDEX = 129; + const T_INNER = 130; + const T_IS = 131; + const T_JOIN = 132; + const T_LEADING = 133; + const T_LEFT = 134; + const T_LIKE = 135; + const T_LIMIT = 136; + const T_LOWER_THAN = 137; + const T_MAX = 138; + const T_MEMBER = 139; + const T_MIN = 140; + const T_MINUS = 141; + const T_MOD = 142; + const T_MULTIPLY = 143; + const T_NEGATE = 144; + const T_NOT = 145; + const T_NULL = 146; + const T_OF = 147; + const T_OFFSET = 148; const T_OPEN_PARENTHESIS = 149; const T_OR = 150; const T_ORDER = 151; @@ -123,7 +124,7 @@ class Lexer extends \Doctrine\Common\Lexer protected function getCatchablePatterns() { return array( - '[a-z_][a-z0-9_\\\]*', + '[a-z_][a-z0-9_\:\\\]*[a-z0-9_]{1}', '(?:[0-9]+(?:[,\.][0-9]+)*)(?:e[+-]?[0-9]+)?', "'(?:[^']|'')*'", '\?[1-9]+|:[a-z][a-z0-9_]+' diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index eae389828..1f5627a77 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -867,12 +867,22 @@ class Parser $this->match(Lexer::T_IDENTIFIER); $schemaName = $this->_lexer->token['value']; - $aliasMap = $this->_em->getConfiguration()->getEntityAliasMap(); - if (isset($aliasMap[$schemaName])) { - $schemaName = $aliasMap[$schemaName]; + + if (($pos = strrpos($schemaName, ':')) !== false) { + $entityNamespaces = $this->_em->getConfiguration()->getEntityNamespaces(); + $entityNamespace = substr($schemaName, 0, $pos); + + if ( ! isset($entityNamespaces[$entityNamespace])) { + $this->semanticalError( + "Unknown Entity namespace '$entityNamespace' when processing '$schemaName'.", $this->_lexer->token + ); + } + + $schemaName = trim($entityNamespaces[$entityNamespace], '\\') . '\\' . substr($schemaName, $pos + 1); } + $exists = class_exists($schemaName, true); - + if ( ! $exists) { $this->semanticalError("Class '$schemaName' is not defined.", $this->_lexer->token); } diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php index 76a94e51b..92cdb7fe1 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php @@ -297,6 +297,27 @@ class AnnotationExporter extends AbstractExporter return '@Table(' . implode(', ', $table) . ')'; } + private function _getInheritanceAnnotation($metadata) + { + if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) { + switch ($metadata->inheritanceType) { + case ClassMetadataInfo::INHERITANCE_TYPE_JOINED: + $type = "JOINED"; + break; + case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE: + $type = "SINGLE_TABLE"; + break; + case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS: + $type = "TABLE_PER_CLASS"; + break; + } + + return '@InheritanceType("'.$type.'")'; + } + + return ''; + } + private function _getJoinColumnAnnotation(array $joinColumn) { $joinColumnAnnot = array(); diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/annotation.tpl.php b/lib/Doctrine/ORM/Tools/Export/Driver/annotation.tpl.php index 2742eb757..5209b0544 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/annotation.tpl.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/annotation.tpl.php @@ -16,6 +16,7 @@ use _getClassToExtendNamespace() ?>; * @Entity * _getTableAnnotation($metadata)."\n" ?> + * _getInheritanceAnnotation($metadata)."\n" ?> */ class _getClassName($metadata) ?>_extendsClass()): ?> extends _getClassToExtendName() ?> diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php index f72de006c..856c7b8d2 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php @@ -65,6 +65,17 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase $users = $repos->findAll(); $this->assertEquals(2, count($users)); + + $this->_em->clear(); + + $this->_em->getConfiguration()->addEntityNamespace('CMS', 'Doctrine\Tests\Models\CMS'); + + $repos = $this->_em->getRepository('CMS:CmsUser'); + + $users = $repos->findAll(); + $this->assertEquals(2, count($users)); + + $this->_em->getConfiguration()->setEntityNamespaces(array()); } /** diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php index 0cc8ce003..e02c3e44d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php @@ -227,18 +227,18 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase ->getSingleResult(); } - public function testSupportsQueriesWithEntityAliases() + public function testSupportsQueriesWithEntityNamespaces() { - $this->_em->getConfiguration()->addEntityAlias('Doctrine\Tests\Models\CMS\CmsUser', 'TestAlias'); + $this->_em->getConfiguration()->addEntityNamespace('CMS', 'Doctrine\Tests\Models\CMS'); try { - $query = $this->_em->createQuery('UPDATE TestAlias u SET u.name = ?1'); + $query = $this->_em->createQuery('UPDATE CMS:CmsUser u SET u.name = ?1'); $this->assertEquals('UPDATE cms_users SET name = ?', $query->getSql()); $query->free(); } catch (\Exception $e) { $this->fail($e->getMessage()); } - $this->_em->getConfiguration()->setEntityAliasMap(array()); + $this->_em->getConfiguration()->setEntityNamespaces(array()); } } \ No newline at end of file