diff --git a/build.properties.dev b/build.properties.dev index e5c1a4902..6ac374b96 100644 --- a/build.properties.dev +++ b/build.properties.dev @@ -1,4 +1,4 @@ -version_name=2.0.0-ALPHA1 +version_name=2.0.0-ALPHA2 version=2.0.0 stability=alpha build.dir=build diff --git a/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php b/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php index a6cf38602..29ae5d5f0 100644 --- a/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php +++ b/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php @@ -77,19 +77,33 @@ class ClassMetadataExporter throw DoctrineException::invalidMappingDriverType($type); } - $class = $this->_mappingDrivers[$type]; - if (is_subclass_of($class, 'Doctrine\ORM\Mapping\Driver\AbstractFileDriver')) { - $driver = new $class($dir, constant($class . '::PRELOAD')); - } else { - $reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache); - $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); - $driver = new $class($reader); - } + $driver = $this->getMappingDriver($type, $dir); $this->_mappingDirectories[] = array($dir, $driver); } } - private function _getMetadataInstances() + public function getMappingDriver($type, $dir) + { + if ( ! isset($this->_mappingDrivers[$type])) { + return false; + } + $class = $this->_mappingDrivers[$type]; + if (is_subclass_of($class, 'Doctrine\ORM\Mapping\Driver\AbstractFileDriver')) { + $driver = new $class($dir, constant($class . '::PRELOAD')); + } else { + $reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache); + $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); + $driver = new $class($reader); + } + return $driver; + } + + public function getMappingDirectories() + { + return $this->_mappingDirectories; + } + + public function getMetadataInstances() { $classes = array(); @@ -108,12 +122,10 @@ class ClassMetadataExporter $vars = get_defined_vars(); foreach ($vars as $var) { if ($var instanceof \Doctrine\ORM\Mapping\ClassMetadataInfo) { - $classes[] = $var; + $classes[$var->name] = $var; } } } - $classes = array_unique($classes); - $classes = array_values($classes); } else { if ($driver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) { $iter = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir), @@ -133,7 +145,7 @@ class ClassMetadataExporter if ( ! $driver->isTransient($className)) { $metadata = new ClassMetadata($className); $driver->loadMetadataForClass($className, $metadata); - $classes[] = $metadata; + $classes[$metadata->name] = $metadata; } } } else { @@ -141,7 +153,7 @@ class ClassMetadataExporter foreach ($preloadedClasses as $className) { $metadata = new ClassMetadataInfo($className); $driver->loadMetadataForClass($className, $metadata); - $classes[] = $metadata; + $classes[$metadata->name] = $metadata; } } } @@ -163,6 +175,6 @@ class ClassMetadataExporter } $class = $this->_exporterDrivers[$type]; - return new $class($this->_getMetadataInstances()); + return new $class($this->getMetadataInstances(), $dir); } } \ No newline at end of file diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php index 669ea01f0..498fc7078 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php @@ -46,6 +46,11 @@ abstract class AbstractExporter $this->_outputDir = $dir; } + public function getExtension() + { + return $this->_extension; + } + /** * Set the directory to output the mapping files to * diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php index 5dac6e9a2..df16940dc 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php @@ -116,6 +116,11 @@ class AnnotationExporter extends AbstractExporter $this->_numSpaces = $numSpaces; } + public function hasNamespace($metadata) + { + return strpos($metadata->name, '\\') ? true : false; + } + public function extendsClass() { return $this->_classToExtend ? true : false; @@ -145,7 +150,11 @@ class AnnotationExporter extends AbstractExporter public function getClassName($metadata) { - return substr($metadata->name, strpos($metadata->name, '\\') + 1, strlen($metadata->name)); + if ($pos = strpos($metadata->name, '\\')) { + return substr($metadata->name, $pos + 1, strlen($metadata->name)); + } else { + return $metadata->name; + } } public function getNamespace($metadata) @@ -227,9 +236,9 @@ class AnnotationExporter extends AbstractExporter public function getTableAnnotation($metadata) { $table = array(); - $table[] = 'name=' . $metadata->primaryTable['name']; + $table[] = 'name="' . $metadata->primaryTable['name'] . '"'; if (isset($metadata->primaryTable['schema'])) { - $table[] = 'schema=' . $metadata->primaryTable['schema']; + $table[] = 'schema="' . $metadata->primaryTable['schema'] . '"'; } return '@Table(' . implode(', ', $table) . ')'; } diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php index 28687e789..bcd7f7e97 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php @@ -22,7 +22,7 @@ namespace Doctrine\ORM\Tools\Export\Driver; -use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\ClassMetadataInfo; /** * ClassMetadata exporter for PHP code @@ -49,16 +49,16 @@ class PhpExporter extends AbstractExporter $lines = array(); $lines[] = '<?php'; $lines[] = null; - $lines[] = 'use Doctrine\ORM\Mapping\ClassMetadata;'; + $lines[] = 'use Doctrine\ORM\Mapping\ClassMetadataInfo;'; $lines[] = null; - $lines[] = "\$metadata = new ClassMetadata('" . $metadata->name . "');"; + $lines[] = "\$metadata = new ClassMetadataInfo('" . $metadata->name . "');"; if ($metadata->isMappedSuperclass) { $lines[] = '$metadata->isMappedSuperclass = true;'; } if ($metadata->inheritanceType) { - $lines[] = '$metadata->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_' . $this->_getInheritanceTypeString($metadata->inheritanceType) . ');'; + $lines[] = '$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_' . $this->_getInheritanceTypeString($metadata->inheritanceType) . ');'; } if ($metadata->customRepositoryClassName) { @@ -78,7 +78,7 @@ class PhpExporter extends AbstractExporter } if ($metadata->changeTrackingPolicy) { - $lines[] = '$metadata->setChangeTrackingPolicy(ClassMetadata::CHANGETRACKING_' . $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy) . ');'; + $lines[] = '$metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_' . $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy) . ');'; } foreach ($metadata->fieldMappings as $fieldMapping) { @@ -86,7 +86,7 @@ class PhpExporter extends AbstractExporter } if ($generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { - $lines[] = '$metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_' . $generatorType . ');'; + $lines[] = '$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_' . $generatorType . ');'; } foreach ($metadata->associationMappings as $associationMapping) { diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/annotation.tpl.php b/lib/Doctrine/ORM/Tools/Export/Driver/annotation.tpl.php index 0a028dbb9..1bac1c96f 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/annotation.tpl.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/annotation.tpl.php @@ -1,6 +1,9 @@ [?php +<?php if ($this->hasNamespace($metadata)): ?> + namespace <?php echo $this->getNamespace($metadata) ?>; +<?php endif; ?> <?php if ($this->extendsClass()): ?> use <?php echo $this->getClassToExtendNamespace() ?>; diff --git a/tests/Doctrine/Tests/ORM/AllTests.php b/tests/Doctrine/Tests/ORM/AllTests.php index 2deb14bb4..9b8e06dd6 100644 --- a/tests/Doctrine/Tests/ORM/AllTests.php +++ b/tests/Doctrine/Tests/ORM/AllTests.php @@ -31,6 +31,7 @@ class AllTests $suite->addTest(Functional\AllTests::suite()); $suite->addTest(Id\AllTests::suite()); $suite->addTest(Proxy\AllTests::suite()); + $suite->addTest(Tools\AllTests::suite()); return $suite; } diff --git a/tests/Doctrine/Tests/ORM/Tools/AllTests.php b/tests/Doctrine/Tests/ORM/Tools/AllTests.php new file mode 100644 index 000000000..5d6ac3c07 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Tools/AllTests.php @@ -0,0 +1,31 @@ +<?php + +namespace Doctrine\Tests\ORM\Tools; + +if (!defined('PHPUnit_MAIN_METHOD')) { + define('PHPUnit_MAIN_METHOD', 'Orm_Tools_AllTests::main'); +} + +require_once __DIR__ . '/../../TestInit.php'; + + +class AllTests +{ + public static function main() + { + \PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new \Doctrine\Tests\DoctrineTestSuite('Doctrine Orm Hydration'); + + $suite->addTestSuite('Doctrine\Tests\ORM\Tools\Export\ClassMetadataExporterTest'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'Orm_Tools_AllTests::main') { + AllTests::main(); +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/ClassMetadataExporterTest.php b/tests/Doctrine/Tests/ORM/Tools/Export/ClassMetadataExporterTest.php new file mode 100644 index 000000000..f0eab7c4b --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Tools/Export/ClassMetadataExporterTest.php @@ -0,0 +1,151 @@ +<?php +/* + * $Id$ + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This software consists of voluntary contributions made by many individuals + * and is licensed under the LGPL. For more information, see + * <http://www.doctrine-project.org>. + */ + +namespace Doctrine\Tests\ORM\Tools\Export; + +use Doctrine\ORM\Tools\Export\ClassMetadataExporter; + +require_once __DIR__ . '/../../../TestInit.php'; + +/** + * Test case for ClassMetadataExporter + * + * @author Jonathan H. Wage <jonwage@gmail.com> + * @author Roman Borschel <roman@code-factory.org + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link http://www.phpdoctrine.org + * @since 2.0 + * @version $Revision$ + */ +class ClassMetadataExporterTest extends \Doctrine\Tests\OrmTestCase +{ + /** + * Test that we can get the different types of exporters + */ + public function testGetExporter() + { + $cme = new ClassMetadataExporter(); + + $exporter = $cme->getExporter('xml'); + $this->assertTrue($exporter instanceof \Doctrine\ORM\Tools\Export\Driver\XmlExporter); + + $exporter = $cme->getExporter('yml'); + $this->assertTrue($exporter instanceof \Doctrine\ORM\Tools\Export\Driver\YamlExporter); + + $exporter = $cme->getExporter('annotation'); + $this->assertTrue($exporter instanceof \Doctrine\ORM\Tools\Export\Driver\AnnotationExporter); + } + + /** + * Test that we can add mapping directories for the different types of + * mapping information. + */ + public function testAddMappingDirectory() + { + $cme = new ClassMetadataExporter(); + $cme->addMappingDir(__DIR__ . '/annotation', 'annotation'); + $cme->addMappingDir(__DIR__ . '/php', 'php'); + $cme->addMappingDir(__DIR__ . '/xml', 'xml'); + $cme->addMappingDir(__DIR__ . '/yml', 'yml'); + + $mappingDirectories = $cme->getMappingDirectories(); + $this->assertEquals(4, count($mappingDirectories)); + + $this->assertEquals($mappingDirectories[0][0], __DIR__.'/annotation'); + $this->assertTrue($mappingDirectories[0][1] instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver); + + $this->assertEquals($mappingDirectories[1][0], __DIR__.'/php'); + $this->assertEquals('php', $mappingDirectories[1][1]); + + $this->assertEquals($mappingDirectories[2][0], __DIR__.'/xml'); + $this->assertTrue($mappingDirectories[2][1] instanceof \Doctrine\ORM\Mapping\Driver\XmlDriver); + + $this->assertEquals($mappingDirectories[3][0], __DIR__.'/yml'); + $this->assertTrue($mappingDirectories[3][1] instanceof \Doctrine\ORM\Mapping\Driver\YamlDriver); + } + + /** + * Test that we can add mapping directories then retrieve all the defined + * ClassMetadata instances that are defined in the directories + */ + public function testGetMetadataInstances() + { + $cme = new ClassMetadataExporter(); + $cme->addMappingDir(__DIR__ . '/annotation', 'annotation'); + $cme->addMappingDir(__DIR__ . '/php', 'php'); + $cme->addMappingDir(__DIR__ . '/xml', 'xml'); + $cme->addMappingDir(__DIR__ . '/yml', 'yml'); + + $metadataInstances = $cme->getMetadataInstances(); + $this->assertEquals(4, count($metadataInstances)); + $this->assertEquals('AnnotationTest', $metadataInstances[0]->name); + $this->assertEquals('PhpTest', $metadataInstances[1]->name); + $this->assertEquals('XmlTest', $metadataInstances[2]->name); + $this->assertEquals('YmlTest', $metadataInstances[3]->name); + } + + /** + * Test that we can export mapping directories to another format and that + * the exported data can then be read back in properly. + */ + public function testExport() + { + $exportDir = __DIR__ . '/export'; + + if ( ! is_dir($exportDir)) { + mkdir($exportDir, 0777, true); + } + + $types = array('annotation', 'php', 'xml', 'yml'); + + $cme = new ClassMetadataExporter(); + $cme->addMappingDir(__DIR__ . '/php', 'php'); + $cme->addMappingDir(__DIR__ . '/xml', 'xml'); + $cme->addMappingDir(__DIR__ . '/yml', 'yml'); + + foreach ($types as $type) { + // Export the above mapping directories to the type + $exporter = $cme->getExporter($type, __DIR__ . '/export/' . $type); + $exporter->export(); + + // Make sure the files were written + $this->assertTrue(file_exists(__DIR__ . '/export/' . $type . '/PhpTest'.$exporter->getExtension())); + $this->assertTrue(file_exists(__DIR__ . '/export/' . $type . '/XmlTest'.$exporter->getExtension())); + $this->assertTrue(file_exists(__DIR__ . '/export/' . $type . '/YmlTest'.$exporter->getExtension())); + + // Try and read back in the exported mapping files to make sure they are valid + $cme2 = new ClassMetadataExporter(); + $cme2->addMappingDir(__DIR__ . '/export/' . $type, $type); + $metadataInstances = $cme2->getMetadataInstances(); + $this->assertEquals(3, count($metadataInstances)); + $this->assertEquals('PhpTest', $metadataInstances[0]->name); + $this->assertEquals('XmlTest', $metadataInstances[1]->name); + $this->assertEquals('YmlTest', $metadataInstances[2]->name); + + // Cleanup + unlink(__DIR__ . '/export/' . $type . '/PhpTest'.$exporter->getExtension()); + unlink(__DIR__ . '/export/' . $type . '/XmlTest'.$exporter->getExtension()); + unlink(__DIR__ . '/export/' . $type . '/YmlTest'.$exporter->getExtension()); + rmdir(__DIR__ . '/export/'.$type); + } + rmdir(__DIR__ . '/export'); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/annotation/AnnotationTest.php b/tests/Doctrine/Tests/ORM/Tools/Export/annotation/AnnotationTest.php new file mode 100644 index 000000000..86b578621 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Tools/Export/annotation/AnnotationTest.php @@ -0,0 +1,52 @@ +<?php + +/** + * @Entity + * @Table(name="annotation_test") + */ +class AnnotationTest +{ + /** + * @Column(type="integer") + * @Id + * @GeneratedValue(strategy="AUTO") + */ + private $id; + + /** + * @Column(type="string", length=50) + */ + private $name; + + /** + * Set id + */ + public function setId($value) + { + $this->id = $value; + } + + /** + * Get id + */ + public function getId() + { + return $this->id; + } + + /** + * Set name + */ + public function setName($value) + { + $this->name = $value; + } + + /** + * Get name + */ + public function getName() + { + return $this->name; + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/php/PhpTest.php b/tests/Doctrine/Tests/ORM/Tools/Export/php/PhpTest.php new file mode 100644 index 000000000..be1b84309 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Tools/Export/php/PhpTest.php @@ -0,0 +1,23 @@ +<?php + +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +$metadata = new ClassMetadataInfo('PhpTest'); +$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_NONE); +$metadata->setPrimaryTable(array( + 'name' => 'php_test', + )); +$metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT); +$metadata->mapField(array( + 'id' => true, + 'fieldName' => 'id', + 'type' => 'integer', + 'columnName' => 'id', + )); +$metadata->mapField(array( + 'fieldName' => 'name', + 'type' => 'string', + 'length' => 50, + 'columnName' => 'name', + )); +$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO); \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/xml/XmlTest.dcm.xml b/tests/Doctrine/Tests/ORM/Tools/Export/xml/XmlTest.dcm.xml new file mode 100644 index 000000000..17be3e308 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Tools/Export/xml/XmlTest.dcm.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"><entity name="XmlTest" table="xml_test"><change-tracking-policy>DEFERRED_IMPLICIT</change-tracking-policy><field name="name" type="string" column="name" length="50"/><id name="id" type="integer" column="id"><generator strategy="AUTO"/></id></entity></doctrine-mapping> diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/yml/YmlTest.dcm.yml b/tests/Doctrine/Tests/ORM/Tools/Export/yml/YmlTest.dcm.yml new file mode 100644 index 000000000..be69e80fa --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Tools/Export/yml/YmlTest.dcm.yml @@ -0,0 +1,12 @@ +YmlTest: + type: entity + table: yml_test + id: + id: + type: integer + generator: + strategy: AUTO + fields: + name: + type: string + length: 50 \ No newline at end of file