Commit 49c73d56 authored by jwage's avatar jwage

[2.0] Refactoring AnnotationExporter code to a EntityGenerator tool which is...

[2.0] Refactoring AnnotationExporter code to a EntityGenerator tool which is used now in orm:convert-mapping to generate annotated entities and also used in orm:generate-entity-stubs for generating entity classes and properties/method stubs from mapping information
parent 119c4eca
......@@ -83,7 +83,8 @@ class CliController extends AbstractNamespace
->addTask('run-dql', $ns . '\RunDqlTask')
->addTask('schema-tool', $ns . '\SchemaToolTask')
->addTask('version', $ns . '\VersionTask')
->addTask('convert-d1-schema', $ns . '\ConvertDoctrine1SchemaTask');
->addTask('convert-d1-schema', $ns . '\ConvertDoctrine1SchemaTask')
->addTask('generate-entity-stubs', $ns . '\GenerateEntityStubsTask');
$ns = 'Doctrine\DBAL\Tools\Cli\Tasks';
$this->addNamespace('Dbal')
......
......@@ -171,7 +171,7 @@ class ConvertMappingTask extends AbstractTask
$exporter->export();
}
private function _determineSourceType($source)
protected function _determineSourceType($source)
{
// If the --from=<VALUE> is a directory lets determine if it is
// annotations, yaml, xml, etc.
......@@ -204,7 +204,7 @@ class ConvertMappingTask extends AbstractTask
}
}
private function _getSourceByType($type, $source)
protected function _getSourceByType($type, $source)
{
// If --from==database then the source is an instance of SchemaManager
// for the current EntityMAnager
......
<?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\ORM\Tools\Cli\Tasks;
use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup,
Doctrine\Common\Cli\CliException,
Doctrine\ORM\Tools\EntityGenerator,
Doctrine\ORM\Tools\Export\ClassMetadataExporter;
/**
* CLI Task to generate entity classes and method stubs from your mapping information.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class GenerateEntityStubsTask extends ConvertMappingTask
{
/**
* @inheritdoc
*/
public function buildDocumentation()
{
$options = new OptionGroup(OptionGroup::CARDINALITY_N_N, array(
new Option('from', '<FROM>', 'The path to mapping information.'),
new Option('dest', '<DEST>', 'The path to your entities.')
));
$doc = $this->getDocumentation();
$doc->setName('generate-entity-stubs')
->setDescription('Generate entity classes and method stubs from your mapping information.')
->getOptionGroup()
->addOption($options);
}
/**
* @inheritdoc
*/
public function validate()
{
$arguments = $this->getArguments();
$em = $this->getConfiguration()->getAttribute('em');
if ( ! isset($arguments['from']) || ! isset($arguments['dest'])) {
throw new CliException('You must specify a value for --from and --dest');
}
return true;
}
public function run()
{
$printer = $this->getPrinter();
$arguments = $this->getArguments();
$from = $arguments['from'];
$dest = realpath($arguments['dest']);
$generator = new EntityGenerator();
$generator->setGenerateAnnotations(true);
$generator->setGenerateStubMethods(true);
$generator->setRegenerateEntityIfExists(false);
$generator->setUpdateEntityIfExists(true);
if (isset($arguments['extend']) && $arguments['extend']) {
$generator->setClassToExtend($arguments['extend']);
}
if (isset($arguments['num-spaces']) && $arguments['extend']) {
$generator->setNumSpaces($arguments['num-spaces']);
}
$type = $this->_determineSourceType($from);
if ( ! $type) {
throw new CliException(
"Invalid mapping source type '$sourceArg'."
);
}
$source = $this->_getSourceByType($type, $from);
$cme = new ClassMetadataExporter();
$cme->addMappingSource($source, $type);
$metadatas = $cme->getMetadatasForMappingSources();
$printer->writeln(
sprintf(
'Generating entity stubs for "%s" mapping information located at "%s" to "%s"',
$printer->format($type, 'KEYWORD'),
$printer->format($from, 'KEYWORD'),
$printer->format($dest, 'KEYWORD')
)
);
$generator->generate($metadatas, $dest);
}
}
\ No newline at end of file
<?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\ORM\Tools;
use Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\AssociationMapping;
/**
* Generic class used to generate PHP5 entity classes from ClassMetadataInfo instances
*
* [php]
* $classes = $em->getClassMetadataFactory()->getAllMetadata();
*
* $generator = new \Doctrine\ORM\Tools\EntityGenerator();
* $generator->setGenerateAnnotations(true);
* $generator->setGenerateStubMethods(true);
* $generator->setRegenerateEntityIfExists(false);
* $generator->setUpdateEntityIfExists(true);
* $generator->generate($classes, '/path/to/generate/entities');
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class EntityGenerator
{
/** The extension to use for written php files */
private $_extension = '.php';
/** Whether or not the current ClassMetadataInfo instance is new or old */
private $_isNew;
/** If $_isNew is false then current code contains the current code from disk */
private $_currentCode;
/** Number of spaces to use for indention in generated code */
private $_numSpaces = 4;
/** The actual spaces to use for indention */
private $_spaces = ' ';
/** The class all generated entities should extend */
private $_classToExtend;
/** Whether or not to generation annotations */
private $_generateAnnotations = false;
/** Whether or not to generated sub methods */
private $_generateStubMethods = false;
/** Whether or not to update the entity class if it exists already */
private $_updateEntityIfExists = false;
/** Whether or not to re-generate entity class if it exists already */
private $_regenerateEntityIfExists = false;
private static $_template =
'<?php
<namespace><use>
<entityAnnotation>
<entityClassName>
{
<entityBody>
}';
/**
* Generate and write entity classes for the given array of ClassMetadataInfo instances
*
* @param array $metadatas
* @param string $outputDirectory
* @return void
*/
public function generate(array $metadatas, $outputDirectory)
{
foreach ($metadatas as $metadata) {
$this->writeEntityClass($metadata, $outputDirectory);
}
}
/**
* Generated and write entity class to disk for the given ClassMetadataInfo instance
*
* @param ClassMetadataInfo $metadata
* @param string $outputDirectory
* @return void
*/
public function writeEntityClass(ClassMetadataInfo $metadata, $outputDirectory)
{
$path = $outputDirectory . '/' . str_replace('\\', DIRECTORY_SEPARATOR, $metadata->name) . $this->_extension;
$dir = dirname($path);
if ( ! is_dir($dir)) {
mkdir($dir, 0777, true);
}
$this->_isNew = ! file_exists($path);
// If entity doesn't exist or we're re-generating the entities entirely
if ($this->_isNew || ( ! $this->_isNew && $this->_regenerateEntityIfExists)) {
file_put_contents($path, $this->generateEntityClass($metadata));
// If entity exists and we're allowed to update the entity class
} else if ( ! $this->_isNew && $this->_updateEntityIfExists) {
file_put_contents($path, $this->generateUpdatedEntityClass($metadata, $path));
}
}
/**
* Generate a PHP5 Doctrine 2 entity class from the given ClassMetadataInfo instance
*
* @param ClassMetadataInfo $metadata
* @return string $code
*/
public function generateEntityClass(ClassMetadataInfo $metadata)
{
$placeHolders = array(
'<namespace>',
'<use>',
'<entityAnnotation>',
'<entityClassName>',
'<entityBody>'
);
$replacements = array(
$this->_generateEntityNamespace($metadata),
$this->_generateEntityUse($metadata),
$this->_generateAnnotations ? "\n" . $this->_generateEntityAnnotation($metadata) : null,
$this->_generateEntityClassName($metadata),
$this->_generateEntityBody($metadata)
);
$code = str_replace($placeHolders, $replacements, self::$_template);
return $code;
}
/**
* Generate the updated code for the given ClassMetadataInfo and entity at path
*
* @param ClassMetadataInfo $metadata
* @param string $path
* @return string $code;
*/
public function generateUpdatedEntityClass(ClassMetadataInfo $metadata, $path)
{
$this->_currentCode = file_get_contents($path);
$body = $this->_generateEntityBody($metadata);
$last = strrpos($this->_currentCode, '}');
$code = substr($this->_currentCode, 0, $last) . $body . '}';
return $code;
}
/**
* Set the number of spaces the exported class should have
*
* @param integer $numSpaces
* @return void
*/
public function setNumSpaces($numSpaces)
{
$this->_spaces = str_repeat(' ', $numSpaces);
$this->_numSpaces = $numSpaces;
}
/**
* Set the extension to use when writing php files to disk
*
* @param string $extension
* @return void
*/
public function setExtension($extension)
{
$this->_extension = $extension;
}
/**
* Set the name of the class the generated classes should extend from
*
* @return void
*/
public function setClassToExtend($classToExtend)
{
$this->_classToExtend = $classToExtend;
}
/**
* Set whether or not to generate annotations for the entity
*
* @param bool $bool
* @return void
*/
public function setGenerateAnnotations($bool)
{
$this->_generateAnnotations = $bool;
}
/**
* Set whether or not to try and update the entity if it already exists
*
* @param bool $bool
* @return void
*/
public function setUpdateEntityIfExists($bool)
{
$this->_updateEntityIfExists = $bool;
}
/**
* Set whether or not to regenerate the entity if it exists
*
* @param bool $bool
* @return void
*/
public function setRegenerateEntityIfExists($bool)
{
$this->_regenerateEntityIfExists = $bool;
}
/**
* Set whether or not to generate stub methods for the entity
*
* @param bool $bool
* @return void
*/
public function setGenerateStubMethods($bool)
{
$this->_generateStubMethods = $bool;
}
private function _generateEntityNamespace(ClassMetadataInfo $metadata)
{
if ($this->_hasNamespace($metadata)) {
return 'namespace ' . $this->_getNamespace($metadata) .';';
}
}
private function _generateEntityUse(ClassMetadataInfo $metadata)
{
if ($this->_extendsClass()) {
return "\n\nuse " . $this->_getClassToExtendNamespace().";\n";
}
}
private function _generateEntityClassName(ClassMetadataInfo $metadata)
{
return 'class ' . $this->_getClassName($metadata) .
($this->_extendsClass() ? 'extends ' . $this->_getClassToExtendName() : null);
}
private function _generateEntityBody(ClassMetadataInfo $metadata)
{
$fieldMappingProperties = $this->_generateEntityFieldMappingProperties($metadata);
$associationMappingProperties = $this->_generateEntityAssociationMappingProperties($metadata);
$stubMethods = $this->_generateStubMethods ? $this->_generateEntityStubMethods($metadata) : null;
$lifecycleCallbackMethods = $this->_generateEntityLifecycleCallbackMethods($metadata);
$code = '';
if ($fieldMappingProperties) {
$code .= $fieldMappingProperties . "\n";
}
if ($associationMappingProperties) {
$code .= $associationMappingProperties . "\n";
}
if ($stubMethods) {
$code .= $stubMethods . "\n";
}
if ($lifecycleCallbackMethods) {
$code .= $lifecycleCallbackMethods . "\n";
}
return $code;
}
private function _hasProperty($property, $metadata)
{
if ($this->_isNew) {
return false;
} else {
return strpos($this->_currentCode, '$' . $property) !== false ? true : false;
}
}
private function _hasMethod($method, $metadata)
{
if ($this->_isNew) {
return false;
} else {
return strpos($this->_currentCode, 'function ' . $method) !== false ? true : false;
}
}
private function _hasNamespace($metadata)
{
return strpos($metadata->name, '\\') ? true : false;
}
private function _extendsClass()
{
return $this->_classToExtend ? true : false;
}
private function _getClassToExtend()
{
return $this->_classToExtend;
}
private function _getClassToExtendName()
{
$refl = new \ReflectionClass($this->_getClassToExtend());
return $refl->getShortName();
}
private function _getClassToExtendNamespace()
{
$refl = new \ReflectionClass($this->_getClassToExtend());
return $refl->getNamespaceName() ? $refl->getNamespaceName():$refl->getShortName();
}
private function _getClassName($metadata)
{
if ($pos = strrpos($metadata->name, '\\')) {
return substr($metadata->name, $pos + 1, strlen($metadata->name));
} else {
return $metadata->name;
}
}
private function _getNamespace($metadata)
{
return substr($metadata->name, 0, strrpos($metadata->name, '\\'));
}
private function _generateEntityAnnotation($metadata)
{
$lines = array();
$lines[] = '/**';
$methods = array(
'_generateTableAnnotation',
'_generateInheritanceAnnotation',
'_generateDiscriminatorColumnAnnotation',
'_generateDiscriminatorMapAnnotation'
);
foreach ($methods as $method) {
if ($code = $this->$method($metadata)) {
$lines[] = ' * ' . $code;
}
}
if ($metadata->isMappedSuperclass) {
$lines[] = ' * @MappedSupperClass';
} else {
$lines[] = ' * @Entity';
}
if ($metadata->customRepositoryClassName) {
$lines[count($lines) - 1] .= '(repositoryClass="' . $metadata->customRepositoryClassName . '")';
}
if (isset($metadata->lifecycleCallbacks) && $metadata->lifecycleCallbacks) {
$lines[] = ' * @HasLifecycleCallbacks';
}
$lines[] = ' */';
return implode("\n", $lines);
}
private function _generateTableAnnotation($metadata)
{
$table = array();
$table[] = 'name="' . $metadata->primaryTable['name'] . '"';
if (isset($metadata->primaryTable['schema'])) {
$table[] = 'schema="' . $metadata->primaryTable['schema'] . '"';
}
return '@Table(' . implode(', ', $table) . ')';
}
private function _generateInheritanceAnnotation($metadata)
{
if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
return '@InheritanceType("'.$this->_getInheritanceTypeString($metadata->inheritanceType).'")';
}
}
private function _generateDiscriminatorColumnAnnotation($metadata)
{
if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
$discrColumn = $metadata->discriminatorValue;
$columnDefinition = 'name="' . $discrColumn['name']
. '", type="' . $discrColumn['type']
. '", length=' . $discrColumn['length'];
return '@DiscriminatorColumn(' . $columnDefinition . ')';
}
}
private function _generateDiscriminatorMapAnnotation($metadata)
{
if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
$inheritanceClassMap = array();
foreach ($metadata->discriminatorMap as $type => $class) {
$inheritanceClassMap[] .= '"' . $type . '" = "' . $class . '"';
}
return '@DiscriminatorMap({' . implode(', ', $inheritanceClassMap) . '})';
}
}
private function _generateEntityStubMethods(ClassMetadataInfo $metadata)
{
$methods = array();
foreach ($metadata->fieldMappings as $fieldMapping) {
if ( ! isset($fieldMapping['id']) || ! $fieldMapping['id']) {
if ($code = $this->_generateStubMethod('set', $fieldMapping['fieldName'], $metadata)) {
$methods[] = $code;
}
}
if ($code = $this->_generateStubMethod('get', $fieldMapping['fieldName'], $metadata)) {
$methods[] = $code;
}
}
foreach ($metadata->associationMappings as $associationMapping) {
if ($associationMapping instanceof \Doctrine\ORM\Mapping\OneToOneMapping) {
if ($code = $this->_generateStubMethod('set', $associationMapping->sourceFieldName, $metadata)) {
$methods[] = $code;
}
if ($code = $this->_generateStubMethod('get', $associationMapping->sourceFieldName, $metadata)) {
$methods[] = $code;
}
} else if ($associationMapping instanceof \Doctrine\ORM\Mapping\OneToManyMapping) {
if ($associationMapping->isOwningSide) {
if ($code = $this->_generateStubMethod('set', $associationMapping->sourceFieldName, $metadata)) {
$methods[] = $code;
}
if ($code = $this->_generateStubMethod('get', $associationMapping->sourceFieldName, $metadata)) {
$methods[] = $code;
}
} else {
if ($code = $this->_generateStubMethod('add', $associationMapping->sourceFieldName, $metadata)) {
$methods[] = $code;
}
if ($code = $this->_generateStubMethod('get', $associationMapping->sourceFieldName, $metadata)) {
$methods[] = $code;
}
}
} else if ($associationMapping instanceof \Doctrine\ORM\Mapping\ManyToManyMapping) {
if ($code = $this->_generateStubMethod('add', $associationMapping->sourceFieldName, $metadata)) {
$methods[] = $code;
}
if ($code = $this->_generateStubMethod('get', $associationMapping->sourceFieldName, $metadata)) {
$methods[] = $code;
}
}
}
return implode('', $methods);
}
private function _generateEntityLifecycleCallbackMethods(ClassMetadataInfo $metadata)
{
if (isset($metadata->lifecycleCallbacks) && $metadata->lifecycleCallbacks) {
$methods = array();
foreach ($metadata->lifecycleCallbacks as $name => $callbacks) {
foreach ($callbacks as $callback) {
if ($code = $this->_generateLifecycleCallbackMethod($name, $callback, $metadata)) {
$methods[] = $code;
}
}
}
return implode('', $methods);
}
}
private function _generateEntityAssociationMappingProperties(ClassMetadataInfo $metadata)
{
$lines = array();
foreach ($metadata->associationMappings as $associationMapping) {
if ($this->_hasProperty($associationMapping->sourceFieldName, $metadata)) {
continue;
}
if ($this->_generateAnnotations) {
$lines[] = $this->_generateAssociationMappingAnnotation($associationMapping, $metadata);
}
$lines[] = $this->_spaces . 'private $' . $associationMapping->sourceFieldName . ($associationMapping->isManyToMany() ? ' = array()' : null) . ";\n";
}
$code = implode("\n", $lines);
return $code;
}
private function _generateEntityFieldMappingProperties(ClassMetadataInfo $metadata)
{
$lines = array();
foreach ($metadata->fieldMappings as $fieldMapping) {
if ($this->_hasProperty($fieldMapping['fieldName'], $metadata)) {
continue;
}
if ($this->_generateAnnotations) {
$lines[] = $this->_generateFieldMappingAnnotation($fieldMapping, $metadata);
}
$lines[] = $this->_spaces . 'private $' . $fieldMapping['fieldName'] . ";\n";
}
$code = implode("\n", $lines);
return $code;
}
private function _generateStubMethod($type, $fieldName, ClassMetadataInfo $metadata)
{
$methodName = $type . ucfirst($fieldName);
if ($this->_hasMethod($methodName, $metadata)) {
return;
}
$method = array();
$method[] = $this->_spaces . '/**';
if ($type == 'get') {
$method[] = $this->_spaces . ' * Get ' . $fieldName;
} else if ($type == 'set') {
$method[] = $this->_spaces . ' * Set ' . $fieldName;
} else if ($type == 'add') {
$method[] = $this->_spaces . ' * Add ' . $fieldName;
}
$method[] = $this->_spaces . ' */';
if ($type == 'get') {
$method[] = $this->_spaces . 'public function ' . $methodName . '()';
} else if ($type == 'set') {
$method[] = $this->_spaces . 'public function ' . $methodName . '($value)';
} else if ($type == 'add') {
$method[] = $this->_spaces . 'public function ' . $methodName . '($value)';
}
$method[] = $this->_spaces . '{';
if ($type == 'get') {
$method[] = $this->_spaces . $this->_spaces . 'return $this->' . $fieldName . ';';
} else if ($type == 'set') {
$method[] = $this->_spaces . $this->_spaces . '$this->' . $fieldName . ' = $value;';
} else if ($type == 'add') {
$method[] = $this->_spaces . $this->_spaces . '$this->' . $fieldName . '[] = $value;';
}
$method[] = $this->_spaces . '}';
$method[] = "\n";
return implode("\n", $method);
}
private function _generateLifecycleCallbackMethod($name, $methodName, $metadata)
{
if ($this->_hasMethod($methodName, $metadata)) {
return;
}
$method = array();
$method[] = $this->_spaces . '/**';
$method[] = $this->_spaces . ' * @'.$name;
$method[] = $this->_spaces . ' */';
$method[] = $this->_spaces . 'public function ' . $methodName . '()';
$method[] = $this->_spaces . '{';
$method[] = $this->_spaces . '}';
return implode("\n", $method)."\n\n";
}
private function _generateJoinColumnAnnotation(array $joinColumn)
{
$joinColumnAnnot = array();
if (isset($joinColumn['name'])) {
$joinColumnAnnot[] = 'name="' . $joinColumn['name'] . '"';
}
if (isset($joinColumn['referencedColumnName'])) {
$joinColumnAnnot[] = 'referencedColumnName="' . $joinColumn['referencedColumnName'] . '"';
}
if (isset($joinColumn['unique']) && $joinColumn['unique']) {
$joinColumnAnnot[] = 'unique=' . ($joinColumn['unique'] ? 'true' : 'false');
}
if (isset($joinColumn['nullable'])) {
$joinColumnAnnot[] = 'nullable=' . ($joinColumn['nullable'] ? 'true' : 'false');
}
if (isset($joinColumn['onDelete'])) {
$joinColumnAnnot[] = 'onDelete=' . ($joinColumn['onDelete'] ? 'true' : 'false');
}
if (isset($joinColumn['onUpdate'])) {
$joinColumnAnnot[] = 'onUpdate=' . ($joinColumn['onUpdate'] ? 'true' : 'false');
}
if (isset($joinColumn['columnDefinition'])) {
$joinColumnAnnot[] = 'columnDefinition="' . $joinColumn['columnDefinition'] . '"';
}
return '@JoinColumn(' . implode(', ', $joinColumnAnnot) . ')';
}
private function _generateAssociationMappingAnnotation(AssociationMapping $associationMapping, ClassMetadataInfo $metadata)
{
$e = explode('\\', get_class($associationMapping));
$type = str_replace('Mapping', '', end($e));
$typeOptions = array();
if (isset($associationMapping->targetEntityName)) {
$typeOptions[] = 'targetEntity="' . $associationMapping->targetEntityName . '"';
}
if (isset($associationMapping->mappedBy)) {
$typeOptions[] = 'mappedBy="' . $associationMapping->mappedBy . '"';
}
if ($associationMapping->hasCascades()) {
$cascades = array();
if ($associationMapping->isCascadePersist) $cascades[] = '"persist"';
if ($associationMapping->isCascadeRemove) $cascades[] = '"remove"';
if ($associationMapping->isCascadeDetach) $cascades[] = '"detach"';
if ($associationMapping->isCascadeMerge) $cascades[] = '"merge"';
if ($associationMapping->isCascadeRefresh) $cascades[] = '"refresh"';
$typeOptions[] = 'cascade={' . implode(',', $cascades) . '}';
}
if (isset($associationMapping->orphanRemoval) && $associationMapping->orphanRemoval) {
$typeOptions[] = 'orphanRemoval=' . ($associationMapping->orphanRemoval ? 'true' : 'false');
}
$lines = array();
$lines[] = $this->_spaces . '/**';
$lines[] = $this->_spaces . ' * @' . $type . '(' . implode(', ', $typeOptions) . ')';
if (isset($associationMapping->joinColumns) && $associationMapping->joinColumns) {
$lines[] = $this->_spaces . ' * @JoinColumns({';
$joinColumnsLines = array();
foreach ($associationMapping->joinColumns as $joinColumn) {
if ($joinColumnAnnot = $this->_generateJoinColumnAnnotation($joinColumn)) {
$joinColumnsLines[] = $this->_spaces . ' * ' . $joinColumnAnnot;
}
}
$lines[] = implode(",\n", $joinColumnsLines);
$lines[] = $this->_spaces . ' * })';
}
if (isset($associationMapping->joinTable) && $associationMapping->joinTable) {
$joinTable = array();
$joinTable[] = 'name="' . $associationMapping->joinTable['name'] . '"';
if (isset($associationMapping->joinTable['schema'])) {
$joinTable[] = 'schema="' . $associationMapping->joinTable['schema'] . '"';
}
$lines[] = $this->_spaces . ' * @JoinTable(' . implode(', ', $joinTable) . ',';
$lines[] = $this->_spaces . ' * joinColumns={';
foreach ($associationMapping->joinTable['joinColumns'] as $joinColumn) {
$lines[] = $this->_spaces . ' * ' . $this->_generateJoinColumnAnnotation($joinColumn);
}
$lines[] = $this->_spaces . ' * },';
$lines[] = $this->_spaces . ' * inverseJoinColumns={';
foreach ($associationMapping->joinTable['inverseJoinColumns'] as $joinColumn) {
$lines[] = $this->_spaces . ' * ' . $this->_generateJoinColumnAnnotation($joinColumn);
}
$lines[] = $this->_spaces . ' * }';
$lines[] = $this->_spaces . ' * )';
}
if (isset($associationMapping->orderBy)) {
$lines[] = $this->_spaces . ' * @OrderBy({';
foreach ($associationMapping->orderBy as $name => $direction) {
$lines[] = $this->_spaces . ' * "' . $name . '"="' . $direction . '",';
}
$lines[count($lines) - 1] = substr($lines[count($lines) - 1], 0, strlen($lines[count($lines) - 1]) - 1);
$lines[] = $this->_spaces . ' * })';
}
$lines[] = $this->_spaces . ' */';
return implode("\n", $lines);
}
private function _generateFieldMappingAnnotation(array $fieldMapping, ClassMetadataInfo $metadata)
{
$lines = array();
$lines[] = $this->_spaces . '/**';
$column = array();
if (isset($fieldMapping['columnName'])) {
$column[] = 'name="' . $fieldMapping['columnName'] . '"';
}
if (isset($fieldMapping['type'])) {
$column[] = 'type="' . $fieldMapping['type'] . '"';
}
if (isset($fieldMapping['length'])) {
$column[] = 'length=' . $fieldMapping['length'];
}
if (isset($fieldMapping['precision'])) {
$column[] = 'precision=' . $fieldMapping['precision'];
}
if (isset($fieldMapping['scale'])) {
$column[] = 'scale=' . $fieldMapping['scale'];
}
if (isset($fieldMapping['nullable'])) {
$column[] = 'nullable=' . var_export($fieldMapping['nullable'], true);
}
if (isset($fieldMapping['columnDefinition'])) {
$column[] = 'columnDefinition="' . $fieldMapping['columnDefinition'] . '"';
}
if (isset($fieldMapping['options'])) {
$options = array();
foreach ($fieldMapping['options'] as $key => $value) {
$value = var_export($value, true);
$value = str_replace("'", '"', $value);
$options[] = ! is_numeric($key) ? $key . '=' . $value:$value;
}
if ($options) {
$column[] = 'options={' . implode(', ', $options) . '}';
}
}
if (isset($fieldMapping['unique'])) {
$column[] = 'unique=' . var_export($fieldMapping['unique'], true);
}
$lines[] = $this->_spaces . ' * @Column(' . implode(', ', $column) . ')';
if (isset($fieldMapping['id']) && $fieldMapping['id']) {
$lines[] = $this->_spaces . ' * @Id';
if ($generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
$lines[] = $this->_spaces.' * @GeneratedValue(strategy="' . $generatorType . '")';
}
if ($metadata->sequenceGeneratorDefinition) {
$sequenceGenerator = array();
if (isset($metadata->sequenceGeneratorDefinition['sequenceName'])) {
$sequenceGenerator[] = 'sequenceName="' . $metadata->sequenceGeneratorDefinition['sequenceName'] . '"';
}
if (isset($metadata->sequenceGeneratorDefinition['allocationSize'])) {
$sequenceGenerator[] = 'allocationSize="' . $metadata->sequenceGeneratorDefinition['allocationSize'] . '"';
}
if (isset($metadata->sequenceGeneratorDefinition['initialValue'])) {
$sequenceGenerator[] = 'initialValue="' . $metadata->sequenceGeneratorDefinition['initialValue'] . '"';
}
$lines[] = $this->_spaces . ' * @SequenceGenerator(' . implode(', ', $sequenceGenerator) . ')';
}
}
if (isset($fieldMapping['version']) && $fieldMapping['version']) {
$lines[] = $this->_spaces . ' * @Version';
}
$lines[] = $this->_spaces . ' */';
return implode("\n", $lines);
}
private function _getInheritanceTypeString($type)
{
switch ($type)
{
case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
return 'NONE';
break;
case ClassMetadataInfo::INHERITANCE_TYPE_JOINED:
return 'JOINED';
break;
case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE:
return 'SINGLE_TABLE';
break;
case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS:
return 'PER_CLASS';
break;
}
}
private function _getChangeTrackingPolicyString($policy)
{
switch ($policy)
{
case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
return 'DEFERRED_IMPLICIT';
break;
case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
return 'DEFERRED_EXPLICIT';
break;
case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
return 'NOTIFY';
break;
}
}
private function _getIdGeneratorTypeString($type)
{
switch ($type)
{
case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
return 'AUTO';
break;
case ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE:
return 'SEQUENCE';
break;
case ClassMetadataInfo::GENERATOR_TYPE_TABLE:
return 'TABLE';
break;
case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
return 'IDENTITY';
break;
}
}
}
\ No newline at end of file
......@@ -23,7 +23,8 @@
namespace Doctrine\ORM\Tools\Export\Driver;
use Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\AssociationMapping;
Doctrine\ORM\Mapping\AssociationMapping,
Doctrine\ORM\Tools\EntityGenerator;
/**
* ClassMetadata exporter for PHP classes with annotations
......@@ -37,24 +38,12 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo,
class AnnotationExporter extends AbstractExporter
{
protected $_extension = '.php';
private $_generator;
private $_isNew = false;
private $_outputPath;
private $_numSpaces;
private $_spaces;
private $_classToExtend;
private $_currentCode;
/**
* Constructor
*
* @param string $dir Diretory to fetch for metadatas
*/
public function __construct($dir = null)
{
parent::__construct($dir);
$this->setNumSpaces(4);
$this->_generator = new EntityGenerator();
}
/**
......@@ -66,53 +55,11 @@ class AnnotationExporter extends AbstractExporter
*/
public function exportClassMetadata(ClassMetadataInfo $metadata)
{
$this->_currentCode = null;
if (file_exists($this->_outputPath)) {
$this->_currentCode = file_get_contents($this->_outputPath);
}
ob_start();
include($this->_isNew ? 'annotation.tpl.php' : 'annotation_body.tpl.php');
$code = ob_get_contents();
ob_end_clean();
$code = str_replace(array('[?php', '?]'), array('<?php', '?>'), $code);
$code = explode("\n", $code);
if ($this->_currentCode) {
$body = $code;
$code = $this->_currentCode;
$code = explode("\n", $code);
unset($code[array_search('}', $code)]);
foreach ($body as $line) {
$code[] = $line;
}
$code[] = '}';
}
$code = array_values($code);
// Remove empty lines before last "}"
for ($i = count($code) - 1; $i > 0; --$i) {
$line = trim($code[$i]);
if ($line && $line != '}') {
break;
}
if ( ! $line) {
unset($code[$i]);
}
}
$code = array_values($code);
$exported = implode("\n", $code);
return $exported;
$this->_generator->setGenerateAnnotations(true);
$this->_generator->setGenerateStubMethods(false);
$this->_generator->setRegenerateEntityIfExists(false);
$this->_generator->setUpdateEntityIfExists(false);
$this->_generator->writeEntityClass($metadata, $this->_outputDir);
}
/**
......@@ -123,8 +70,7 @@ class AnnotationExporter extends AbstractExporter
*/
public function setNumSpaces($numSpaces)
{
$this->_spaces = str_repeat(' ', $numSpaces);
$this->_numSpaces = $numSpaces;
$this->_generator->setNumSpaces($numSpaces);
}
/**
......@@ -134,475 +80,6 @@ class AnnotationExporter extends AbstractExporter
*/
public function setClassToExtend($classToExtend)
{
$this->_classToExtend = $classToExtend;
}
/**
* This method is overriden so that each class is outputted
* to the appropriate path where namespaces become directories.
*
* Export each ClassMetadata instance to a single Doctrine Mapping file
* named after the entity
*
* @return void
*/
public function export()
{
if ( ! is_dir($this->_outputDir)) {
mkdir($this->_outputDir, 0777);
}
foreach ($this->_metadatas as $metadata) {
$outputPath = $this->_outputDir . '/' . str_replace('\\', DIRECTORY_SEPARATOR, $metadata->name) . $this->_extension;
$outputDir = dirname($outputPath);
if ( ! is_dir($outputDir)) {
mkdir($outputDir, 0777, true);
}
if ( ! file_exists($outputPath)) {
$this->_isNew = true;
}
$this->_outputPath = $outputPath;
$output = $this->exportClassMetadata($metadata);
file_put_contents($outputPath, $output);
}
}
private function _hasProperty($property, $metadata)
{
if ($this->_isNew) {
return false;
} else {
return strpos($this->_currentCode, '$' . $property) !== false ? true : false;
}
}
private function _hasMethod($method, $metadata)
{
if ($this->_isNew) {
return false;
} else {
return strpos($this->_currentCode, 'function ' . $method) !== false ? true : false;
}
}
private function _hasNamespace($metadata)
{
return strpos($metadata->name, '\\') ? true : false;
}
private function _extendsClass()
{
return $this->_classToExtend ? true : false;
}
private function _getClassToExtend()
{
return $this->_classToExtend;
}
private function _getClassToExtendName()
{
$refl = new \ReflectionClass($this->_getClassToExtend());
return $refl->getShortName();
}
private function _getClassToExtendNamespace()
{
$refl = new \ReflectionClass($this->_getClassToExtend());
return $refl->getNamespaceName() ? $refl->getNamespaceName():$refl->getShortName();
}
private function _getClassName($metadata)
{
if ($pos = strrpos($metadata->name, '\\')) {
return substr($metadata->name, $pos + 1, strlen($metadata->name));
} else {
return $metadata->name;
}
}
private function _getNamespace($metadata)
{
return substr($metadata->name, 0, strrpos($metadata->name, '\\'));
}
private function _getEntityAnnotation($metadata)
{
$lines = array();
$lines[] = '/**';
$methods = array(
'_getTableAnnotation',
'_getInheritanceAnnotation',
'_getDiscriminatorColumnAnnotation',
'_getDiscriminatorMapAnnotation'
);
foreach ($methods as $method) {
if ($code = $this->$method($metadata)) {
$lines[] = ' * ' . $code;
}
}
if ($metadata->isMappedSuperclass) {
$lines[] = ' * @MappedSupperClass';
} else {
$lines[] = ' * @Entity';
}
if ($metadata->customRepositoryClassName) {
$lines[count($lines) - 1] .= '(repositoryClass="' . $metadata->customRepositoryClassName . '")';
}
if (isset($metadata->lifecycleCallbacks) && $metadata->lifecycleCallbacks) {
$lines[] = ' * @HasLifecycleCallbacks';
}
$lines[] = ' */';
$lines[] = '';
return implode("\n", $lines);
}
private function _getTableAnnotation($metadata)
{
$table = array();
$table[] = 'name="' . $metadata->primaryTable['name'] . '"';
if (isset($metadata->primaryTable['schema'])) {
$table[] = 'schema="' . $metadata->primaryTable['schema'] . '"';
}
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 _getDiscriminatorColumnAnnotation($metadata)
{
if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
$discrColumn = $metadata->discriminatorValue;
$columnDefinition = 'name="' . $discrColumn['name']
. '", type="' . $discrColumn['type']
. '", length=' . $discrColumn['length'];
return '@DiscriminatorColumn(' . $columnDefinition . ')';
}
return '';
}
private function _getDiscriminatorMapAnnotation($metadata)
{
if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
$inheritanceClassMap = array();
foreach ($metadata->discriminatorMap as $type => $class) {
$inheritanceClassMap[] .= '"' . $type . '" = "' . $class . '"';
}
return '@DiscriminatorMap({' . implode(', ', $inheritanceClassMap) . '})';
}
return '';
}
private function _addMethod($type, $fieldName, $metadata, array &$methods)
{
$methodName = $type . ucfirst($fieldName);
if ($this->_hasMethod($methodName, $metadata)) {
return false;
}
$method = array();
$method[] = $this->_spaces . '/**';
if ($type == 'get') {
$method[] = $this->_spaces . ' * Get ' . $fieldName;
} else if ($type == 'set') {
$method[] = $this->_spaces . ' * Set ' . $fieldName;
} else if ($type == 'add') {
$method[] = $this->_spaces . ' * Add ' . $fieldName;
}
$method[] = $this->_spaces . ' */';
if ($type == 'get') {
$method[] = $this->_spaces . 'public function ' . $methodName . '()';
} else if ($type == 'set') {
$method[] = $this->_spaces . 'public function ' . $methodName . '($value)';
} else if ($type == 'add') {
$method[] = $this->_spaces . 'public function ' . $methodName . '($value)';
}
$method[] = $this->_spaces . '{';
if ($type == 'get') {
$method[] = $this->_spaces . $this->_spaces . 'return $this->' . $fieldName . ';';
} else if ($type == 'set') {
$method[] = $this->_spaces . $this->_spaces . '$this->' . $fieldName . ' = $value;';
} else if ($type == 'add') {
$method[] = $this->_spaces . $this->_spaces . '$this->' . $fieldName . '[] = $value;';
}
$method[] = $this->_spaces . '}';
$method[] = "\n";
$methods[] = implode("\n", $method);
}
private function _addLifecycleCallbackMethod($name, $methodName, $metadata, array &$methods)
{
if ($this->_hasMethod($methodName, $metadata)) {
return false;
}
$method = array();
$method[] = $this->_spaces . '/**';
$method[] = $this->_spaces . ' * @'.$name;
$method[] = $this->_spaces . ' */';
$method[] = $this->_spaces . 'public function ' . $methodName . '()';
$method[] = $this->_spaces . '{';
$method[] = $this->_spaces . '}';
$methods[] = implode("\n", $method)."\n\n";
}
private function _getMethods($metadata)
{
$methods = array();
foreach ($metadata->fieldMappings as $fieldMapping) {
if ( ! isset($fieldMapping['id']) || ! $fieldMapping['id']) {
$this->_addMethod('set', $fieldMapping['fieldName'], $metadata, $methods);
}
$this->_addMethod('get', $fieldMapping['fieldName'], $metadata, $methods);
}
foreach ($metadata->associationMappings as $associationMapping) {
if ($associationMapping instanceof \Doctrine\ORM\Mapping\OneToOneMapping) {
$this->_addMethod('set', $associationMapping->sourceFieldName, $metadata, $methods);
$this->_addMethod('get', $associationMapping->sourceFieldName, $metadata, $methods);
} else if ($associationMapping instanceof \Doctrine\ORM\Mapping\OneToManyMapping) {
if ($associationMapping->isOwningSide) {
$this->_addMethod('set', $associationMapping->sourceFieldName, $metadata, $methods);
$this->_addMethod('get', $associationMapping->sourceFieldName, $metadata, $methods);
} else {
$this->_addMethod('add', $associationMapping->sourceFieldName, $metadata, $methods);
$this->_addMethod('get', $associationMapping->sourceFieldName, $metadata, $methods);
}
} else if ($associationMapping instanceof \Doctrine\ORM\Mapping\ManyToManyMapping) {
$this->_addMethod('add', $associationMapping->sourceFieldName, $metadata, $methods);
$this->_addMethod('get', $associationMapping->sourceFieldName, $metadata, $methods);
}
}
if (isset($metadata->lifecycleCallbacks) && $metadata->lifecycleCallbacks) {
foreach ($metadata->lifecycleCallbacks as $name => $callbacks) {
foreach ($callbacks as $callback) {
$this->_addLifecycleCallbackMethod($name, $callback, $metadata, $methods);
}
}
}
return $methods;
}
private function _getJoinColumnAnnotation(array $joinColumn)
{
$joinColumnAnnot = array();
if (isset($joinColumn['name'])) {
$joinColumnAnnot[] = 'name="' . $joinColumn['name'] . '"';
}
if (isset($joinColumn['referencedColumnName'])) {
$joinColumnAnnot[] = 'referencedColumnName="' . $joinColumn['referencedColumnName'] . '"';
}
if (isset($joinColumn['unique']) && $joinColumn['unique']) {
$joinColumnAnnot[] = 'unique=' . ($joinColumn['unique'] ? 'true' : 'false');
}
if (isset($joinColumn['nullable'])) {
$joinColumnAnnot[] = 'nullable=' . ($joinColumn['nullable'] ? 'true' : 'false');
}
if (isset($joinColumn['onDelete'])) {
$joinColumnAnnot[] = 'onDelete=' . ($joinColumn['onDelete'] ? 'true' : 'false');
}
if (isset($joinColumn['onUpdate'])) {
$joinColumnAnnot[] = 'onUpdate=' . ($joinColumn['onUpdate'] ? 'true' : 'false');
}
if (isset($joinColumn['columnDefinition'])) {
$joinColumnAnnot[] = 'columnDefinition="' . $joinColumn['columnDefinition'] . '"';
}
return '@JoinColumn(' . implode(', ', $joinColumnAnnot) . ')';
}
private function _getAssociationMappingAnnotation(AssociationMapping $associationMapping, ClassMetadataInfo $metadata)
{
$e = explode('\\', get_class($associationMapping));
$type = str_replace('Mapping', '', end($e));
$typeOptions = array();
if (isset($associationMapping->targetEntityName)) {
$typeOptions[] = 'targetEntity="' . $associationMapping->targetEntityName . '"';
}
if (isset($associationMapping->mappedBy)) {
$typeOptions[] = 'mappedBy="' . $associationMapping->mappedBy . '"';
}
if ($associationMapping->hasCascades()) {
$cascades = array();
if ($associationMapping->isCascadePersist) $cascades[] = '"persist"';
if ($associationMapping->isCascadeRemove) $cascades[] = '"remove"';
if ($associationMapping->isCascadeDetach) $cascades[] = '"detach"';
if ($associationMapping->isCascadeMerge) $cascades[] = '"merge"';
if ($associationMapping->isCascadeRefresh) $cascades[] = '"refresh"';
$typeOptions[] = 'cascade={' . implode(',', $cascades) . '}';
}
if (isset($associationMapping->orphanRemoval) && $associationMapping->orphanRemoval) {
$typeOptions[] = 'orphanRemoval=' . ($associationMapping->orphanRemoval ? 'true' : 'false');
}
$lines = array();
$lines[] = $this->_spaces . '/**';
$lines[] = $this->_spaces . ' * @' . $type . '(' . implode(', ', $typeOptions) . ')';
if (isset($associationMapping->joinColumns) && $associationMapping->joinColumns) {
$lines[] = $this->_spaces . ' * @JoinColumns({';
$joinColumnsLines = array();
foreach ($associationMapping->joinColumns as $joinColumn) {
if ($joinColumnAnnot = $this->_getJoinColumnAnnotation($joinColumn)) {
$joinColumnsLines[] = $this->_spaces . ' * ' . $joinColumnAnnot;
}
}
$lines[] = implode(",\n", $joinColumnsLines);
$lines[] = $this->_spaces . ' * })';
}
if (isset($associationMapping->joinTable) && $associationMapping->joinTable) {
$joinTable = array();
$joinTable[] = 'name="' . $associationMapping->joinTable['name'] . '"';
if (isset($associationMapping->joinTable['schema'])) {
$joinTable[] = 'schema="' . $associationMapping->joinTable['schema'] . '"';
}
$lines[] = $this->_spaces . ' * @JoinTable(' . implode(', ', $joinTable) . ',';
$lines[] = $this->_spaces . ' * joinColumns={';
foreach ($associationMapping->joinTable['joinColumns'] as $joinColumn) {
$lines[] = $this->_spaces . ' * ' . $this->_getJoinColumnAnnotation($joinColumn);
}
$lines[] = $this->_spaces . ' * },';
$lines[] = $this->_spaces . ' * inverseJoinColumns={';
foreach ($associationMapping->joinTable['inverseJoinColumns'] as $joinColumn) {
$lines[] = $this->_spaces . ' * ' . $this->_getJoinColumnAnnotation($joinColumn);
}
$lines[] = $this->_spaces . ' * }';
$lines[] = $this->_spaces . ' * )';
}
if (isset($associationMapping->orderBy)) {
$lines[] = $this->_spaces . ' * @OrderBy({';
foreach ($associationMapping->orderBy as $name => $direction) {
$lines[] = $this->_spaces . ' * "' . $name . '"="' . $direction . '",';
}
$lines[count($lines) - 1] = substr($lines[count($lines) - 1], 0, strlen($lines[count($lines) - 1]) - 1);
$lines[] = $this->_spaces . ' * })';
}
$lines[] = $this->_spaces . ' */';
return implode("\n", $lines);
}
private function _getFieldMappingAnnotation(array $fieldMapping, ClassMetadataInfo $metadata)
{
$lines = array();
$lines[] = $this->_spaces . '/**';
$column = array();
if (isset($fieldMapping['columnName'])) {
$column[] = 'name="' . $fieldMapping['columnName'] . '"';
}
if (isset($fieldMapping['type'])) {
$column[] = 'type="' . $fieldMapping['type'] . '"';
}
if (isset($fieldMapping['length'])) {
$column[] = 'length=' . $fieldMapping['length'];
}
if (isset($fieldMapping['precision'])) {
$column[] = 'precision=' . $fieldMapping['precision'];
}
if (isset($fieldMapping['scale'])) {
$column[] = 'scale=' . $fieldMapping['scale'];
}
if (isset($fieldMapping['nullable'])) {
$column[] = 'nullable=' . var_export($fieldMapping['nullable'], true);
}
if (isset($fieldMapping['columnDefinition'])) {
$column[] = 'columnDefinition="' . $fieldMapping['columnDefinition'] . '"';
}
if (isset($fieldMapping['options'])) {
$options = array();
foreach ($fieldMapping['options'] as $key => $value) {
$value = var_export($value, true);
$value = str_replace("'", '"', $value);
$options[] = ! is_numeric($key) ? $key . '=' . $value:$value;
}
if ($options) {
$column[] = 'options={' . implode(', ', $options) . '}';
}
}
if (isset($fieldMapping['unique'])) {
$column[] = 'unique=' . var_export($fieldMapping['unique'], true);
}
$lines[] = $this->_spaces . ' * @Column(' . implode(', ', $column) . ')';
if (isset($fieldMapping['id']) && $fieldMapping['id']) {
$lines[] = $this->_spaces . ' * @Id';
if ($generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
$lines[] = $this->_spaces.' * @GeneratedValue(strategy="' . $generatorType . '")';
}
if ($metadata->sequenceGeneratorDefinition) {
$sequenceGenerator = array();
if (isset($metadata->sequenceGeneratorDefinition['sequenceName'])) {
$sequenceGenerator[] = 'sequenceName="' . $metadata->sequenceGeneratorDefinition['sequenceName'] . '"';
}
if (isset($metadata->sequenceGeneratorDefinition['allocationSize'])) {
$sequenceGenerator[] = 'allocationSize="' . $metadata->sequenceGeneratorDefinition['allocationSize'] . '"';
}
if (isset($metadata->sequenceGeneratorDefinition['initialValue'])) {
$sequenceGenerator[] = 'initialValue="' . $metadata->sequenceGeneratorDefinition['initialValue'] . '"';
}
$lines[] = $this->_spaces . ' * @SequenceGenerator(' . implode(', ', $sequenceGenerator) . ')';
}
}
if (isset($fieldMapping['version']) && $fieldMapping['version']) {
$lines[] = $this->_spaces . ' * @Version';
}
$lines[] = $this->_spaces . ' */';
return implode("\n", $lines);
$this->_generator->setClassToExtend($classToExtend);
}
}
\ No newline at end of file
......@@ -26,6 +26,7 @@ class AllTests
$suite->addTestSuite('Doctrine\Tests\ORM\Tools\Export\AnnotationClassMetadataExporterTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Tools\ConvertDoctrine1SchemaTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Tools\SchemaToolTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Tools\EntityGeneratorTest');
return $suite;
}
......
<?php
namespace Doctrine\Tests\ORM\Tools;
use Doctrine\ORM\Tools\SchemaTool,
Doctrine\ORM\Tools\EntityGenerator,
Doctrine\ORM\Tools\Export\ClassMetadataExporter,
Doctrine\ORM\Mapping\ClassMetadataInfo;
require_once __DIR__ . '/../../TestInit.php';
class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
{
public function testWriteEntityClass()
{
$metadata = new ClassMetadataInfo('EntityGeneratorBook');
$metadata->primaryTable['name'] = 'book';
$metadata->mapField(array('fieldName' => 'name', 'type' => 'varchar'));
$metadata->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
$metadata->mapOneToOne(array('fieldName' => 'other', 'targetEntity' => 'Other', 'mappedBy' => 'this'));
$joinColumns = array(
array('name' => 'other_id', 'referencedColumnName' => 'id')
);
$metadata->mapOneToOne(array('fieldName' => 'association', 'targetEntity' => 'Other', 'joinColumns' => $joinColumns));
$metadata->mapManyToMany(array(
'fieldName' => 'author',
'targetEntity' => 'Author',
'joinTable' => array(
'name' => 'book_author',
'joinColumns' => array(array('name' => 'bar_id', 'referencedColumnName' => 'id')),
'inverseJoinColumns' => array(array('name' => 'baz_id', 'referencedColumnName' => 'id')),
),
));
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
$generator = new EntityGenerator();
$generator->setGenerateAnnotations(true);
$generator->setGenerateStubMethods(true);
$generator->setRegenerateEntityIfExists(false);
$generator->setUpdateEntityIfExists(true);
$generator->writeEntityClass($metadata, __DIR__);
$path = __DIR__ . '/EntityGeneratorBook.php';
$this->assertTrue(file_exists($path));
require_once $path;
}
/**
* @depends testWriteEntityClass
*/
public function testGeneratedEntityClassMethods()
{
$this->assertTrue(method_exists('\EntityGeneratorBook', 'getId'));
$this->assertTrue(method_exists('\EntityGeneratorBook', 'setName'));
$this->assertTrue(method_exists('\EntityGeneratorBook', 'getName'));
$this->assertTrue(method_exists('\EntityGeneratorBook', 'setOther'));
$this->assertTrue(method_exists('\EntityGeneratorBook', 'getOther'));
$this->assertTrue(method_exists('\EntityGeneratorBook', 'setAssociation'));
$this->assertTrue(method_exists('\EntityGeneratorBook', 'getAssociation'));
$this->assertTrue(method_exists('\EntityGeneratorBook', 'getAuthor'));
$this->assertTrue(method_exists('\EntityGeneratorBook', 'addAuthor'));
$book = new \EntityGeneratorBook();
$book->setName('Jonathan H. Wage');
$this->assertEquals('Jonathan H. Wage', $book->getName());
$book->setOther('Other');
$this->assertEquals('Other', $book->getOther());
$book->setAssociation('Test');
$this->assertEquals('Test', $book->getAssociation());
$book->addAuthor('Test');
$this->assertEquals(array('Test'), $book->getAuthor());
unlink(__DIR__ . '/EntityGeneratorBook.php');
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment