diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadata.php b/lib/Doctrine/ORM/Mapping/ClassMetadata.php index ce8a46e2a..264a568a2 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadata.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadata.php @@ -1591,7 +1591,7 @@ final class ClassMetadata } /** - * Sets the dsicriminator values used by this class. + * Sets the discriminator values used by this class. * Used for JOINED and SINGLE_TABLE inheritance mapping strategies. * * @param array $map diff --git a/lib/Doctrine/ORM/Tools/Export/ClassmetadataExporter.php b/lib/Doctrine/ORM/Tools/Export/ClassmetadataExporter.php new file mode 100644 index 000000000..c0e531df1 --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Export/ClassmetadataExporter.php @@ -0,0 +1,135 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export; + +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Mapping\Classmetadata; + +/** + * Class used for converting your mapping information between the + * supported formats: yaml, xml, and php/annotation. + * + * [php] + * // Unify all your mapping information which is written in php, xml, yml + * // and convert it to a single set of yaml files. + * + * $cme = new Doctrine\ORM\Tools\Export\ClassmetadataExporter(); + * $cme->addMappingDir(__DIR__ . '/Entities', 'php'); + * $cme->addMappingDir(__DIR__ . '/xml', 'xml'); + * $cme->addMappingDir(__DIR__ . '/yaml', 'yaml'); + * + * $exporter = $cme->getExporter('yaml'); + * $exporter->setOutputDir(__DIR__ . '/new_yaml'); + * $exporter->export(); + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +class ClassmetadataExporter +{ + private $_exporterDrivers = array( + 'xml' => 'Doctrine\ORM\Tools\Export\Driver\XmlExporter', + 'yaml' => 'Doctrine\ORM\Tools\Export\Driver\YamlExporter', + 'php' => 'Doctrine\ORM\Tools\Export\Driver\PhpExporter' + ); + + private $_mappingDrivers = array( + 'php' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver', + 'yaml' => 'Doctrine\ORM\Mapping\Driver\YamlDriver', + 'xml' => 'Doctrine\ORM\Mapping\Driver\XmlDriver' + ); + + private $_mappingDriverInstances = array(); + + public function addMappingDir($dir, $type) + { + if ( ! isset($this->_mappingDrivers[$type])) { + 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); + } + $this->_mappingDriverInstances[] = array($dir, $driver); + } + + private function _getMetadataInstances() + { + $classes = array(); + + foreach ($this->_mappingDriverInstances as $d) { + list($dir, $driver) = $d; + // TODO: This code exists in the SchemaToolTask.php + // Should we pull it out somewhere common? I can see the need to have + // a way to retrieve an array of entity names found in some directories + if ($driver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) { + $iter = new \FilesystemIterator($dir); + + $declared = get_declared_classes(); + foreach ($iter as $item) { + $baseName = $item->getBaseName(); + if ($baseName[0] == '.') { + continue; + } + require_once $item->getPathName(); + } + $declared = array_diff(get_declared_classes(), $declared); + + foreach ($declared as $className) { + if ( ! $driver->isTransient($className)) { + $metadata = new ClassMetadata($className); + $driver->loadMetadataForClass($className, $metadata); + $classes[] = $metadata; + } + } + } else { + $preloadedClasses = $driver->preload(true); + foreach ($preloadedClasses as $className) { + $metadata = new ClassMetadata($className); + $driver->loadMetadataForClass($className, $metadata); + $classes[] = $metadata; + } + } + } + + return $classes; + } + + public function getExporter($type, $dir = null) + { + if ( ! isset($this->_exporterDrivers[$type])) { + throw DoctrineException::invalidExporterDriverType($type); + } + + $class = $this->_exporterDrivers[$type]; + return new $class($this->_getMetadataInstances()); + } +} \ 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 new file mode 100644 index 000000000..18dd53d5e --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php @@ -0,0 +1,104 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export\Driver; + +use Doctrine\ORM\Mapping\ClassMetadata; + +/** + * Abstract base class which is to be used for the Exporter drivers + * which can be found in Doctrine\ORM\Tools\Export\Driver + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +abstract class AbstractExporter +{ + protected $_metadatas = array(); + protected $_outputDir; + protected $_extension; + + public function __construct(array $metadatas, $dir = null) + { + $this->_metadatas = $metadatas; + $this->_outputDir = $dir; + } + + /** + * Set the directory to output the mapping files to + * + * [php] + * $exporter = new YamlExporter($metadatas); + * $exporter->setOutputDir(__DIR__ . '/yaml'); + * $exporter->export(); + * + * @param string $dir + * @return void + */ + public function setOutputDir($dir) + { + $this->_outputDir = $dir; + } + + /** + * Export each ClassMetadata instance to a single Doctrine Mapping file + * named after the entity + * + * @return void + */ + public function export() + { + foreach ($this->_metadatas as $metadata) { + $outputPath = $this->_outputDir . '/' . str_replace('\\', '.', $metadata->name) . $this->_extension; + $output = $this->exportClassMetadata($metadata); + file_put_contents($outputPath, $output); + } + } + + /** + * Set the directory to output the mapping files to + * + * [php] + * $exporter = new YamlExporter($metadatas, __DIR__ . '/yaml'); + * $exporter->setExtension('.yml'); + * $exporter->export(); + * + * @param string $extension + * @return void + */ + public function setExtension($extension) + { + $this->_extension = $extension; + } + + /** + * Converts a single ClassMetadata instance to the exported format + * and returns it + * + * @param ClassMetadata $metadata + * @return mixed $exported + */ + abstract public function exportClassMetadata(ClassMetadata $metadata); +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php new file mode 100644 index 000000000..6ff47963c --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php @@ -0,0 +1,51 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export\Driver; + +use Doctrine\ORM\Mapping\ClassMetadata; + +/** + * ClassMetadata exporter for PHP classes with annotations + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +class PhpExporter extends AbstractExporter +{ + protected $_extension = '.php'; + + /** + * Converts a single ClassMetadata instance to the exported format + * and returns it + * + * @param ClassMetadata $metadata + * @return mixed $exported + */ + public function exportClassMetadata(ClassMetadata $metadata) + { + + } +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php new file mode 100644 index 000000000..753257974 --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php @@ -0,0 +1,51 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export\Driver; + +use Doctrine\ORM\Mapping\ClassMetadata; + +/** + * ClassMetadata exporter for Doctrine XML mapping files + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +class XmlExporter extends AbstractExporter +{ + protected $_extension = '.dcm.xml'; + + /** + * Converts a single ClassMetadata instance to the exported format + * and returns it + * + * @param ClassMetadata $metadata + * @return mixed $exported + */ + public function exportClassMetadata(ClassMetadata $metadata) + { + + } +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php new file mode 100644 index 000000000..cc524f663 --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php @@ -0,0 +1,94 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export\Driver; + +use Doctrine\ORM\Mapping\ClassMetadata; + +/** + * ClassMetadata exporter for Doctrine YAML mapping files + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +class YamlExporter extends AbstractExporter +{ + protected $_extension = '.dcm.yml'; + + /** + * 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 ClassMetadata $metadata + * @return mixed $exported + */ + public function exportClassMetadata(ClassMetadata $metadata) + { + $array = array(); + $array['type'] = 'entity'; + $array['table'] = $metadata->primaryTable['name']; + + if (isset($metadata->primaryTable['schema'])) { + $array['schema'] = $metadata->primaryTable['schema']; + } + + $array['inheritanceType'] = $metadata->getInheritanceType(); + $array['discriminatorColumn'] = $metadata->getDiscriminatorColumn(); + $array['discriminatorMap'] = $metadata->discriminatorMap; + $array['changeTrackingPolicy'] = $metadata->changeTrackingPolicy; + + if (isset($metadata->primaryTable['indexes'])) { + $array['indexes'] = $metadata->primaryTable['indexes']; + } + + if (isset($metadata->primaryTable['uniqueConstraints'])) { + $array['uniqueConstraints'] = $metadata->primaryTable['uniqueConstraints']; + } + + $fields = $metadata->getFieldMappings(); + + $id = array(); + foreach ($fields as $name => $field) { + if (isset($field['id']) && $field['id']) { + $id[$name] = $field; + unset($fields[$name]); + } + } + + if ($idGeneratorType = $metadata->getIdGeneratorType()) { + $id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType; + } + $array['id'] = $id; + $array['fields'] = $fields; + + foreach ($metadata->associationMappings as $name => $associationMapping) { + // TODO: build array of association mappings + } + + return \sfYaml::dump(array($metadata->name => $array), 10); + } +} \ No newline at end of file