/
GenerateEntityDoctrineCommand.php
129 lines (108 loc) · 5.29 KB
/
GenerateEntityDoctrineCommand.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
namespace Symfony\Bundle\DoctrineBundle\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\Output;
use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
use Doctrine\ORM\Tools\EntityGenerator;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
/**
* Initialize a new Doctrine entity inside a bundle.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
class GenerateEntityDoctrineCommand extends DoctrineCommand
{
protected function configure()
{
$this
->setName('doctrine:generate:entity')
->setDescription('Generate a new Doctrine entity inside a bundle.')
->addArgument('bundle', null, InputArgument::REQUIRED, 'The bundle to initialize the entity in.')
->addArgument('entity', null, InputArgument::REQUIRED, 'The entity class to initialize.')
->addOption('mapping-type', null, InputOption::PARAMETER_OPTIONAL, 'The mapping type to to use for the entity.')
->addOption('fields', null, InputOption::PARAMETER_OPTIONAL, 'The fields to create with the new entity.')
->setHelp(<<<EOT
The <info>doctrine:generate:entity</info> task initializes a new Doctrine entity inside a bundle:
<info>./symfony doctrine:generate:entity "Bundle\MyCustomBundle" "User\Group"</info>
The above would initialize a new entity in the following entity namespace <info>Bundle\MyCustomBundle\Entity\User\Group</info>.
You can also optionally specify the fields you want to generate in the new entity:
<info>./symfony doctrine:generate:entity "Bundle\MyCustomBundle" "User\Group" --fields="name:string(255) description:text"</info>
EOT
);
}
/**
* @throws \InvalidArgumentException When the bundle doesn't end with Bundle (Example: "Bundle\MySampleBundle")
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (!preg_match('/Bundle$/', $bundle = $input->getArgument('bundle'))) {
throw new \InvalidArgumentException('The bundle name must end with Bundle. Example: "Bundle\MySampleBundle".');
}
$dirs = $this->container->get('kernel')->getBundleDirs();
$tmp = str_replace('\\', '/', $bundle);
$namespace = str_replace('/', '\\', dirname($tmp));
$bundle = basename($tmp);
if (!isset($dirs[$namespace])) {
throw new \InvalidArgumentException(sprintf('Unable to initialize the bundle entity (%s not defined).', $namespace));
}
$entity = $input->getArgument('entity');
$entityNamespace = $namespace.'\\'.$bundle.'\\Entity';
$fullEntityClassName = $entityNamespace.'\\'.$entity;
$tmp = str_replace('\\', '/', $fullEntityClassName);
$tmp = str_replace('/', '\\', dirname($tmp));
$className = basename($tmp);
$mappingType = $input->getOption('mapping-type');
$mappingType = $mappingType ? $mappingType : 'xml';
$class = new ClassMetadataInfo($fullEntityClassName);
$class->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
$class->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
// Map the specified fields
$fields = $input->getOption('fields');
if ($fields)
{
$e = explode(' ', $fields);
foreach ($e as $value) {
$e = explode(':', $value);
$name = $e[0];
$type = isset($e[1]) ? $e[1] : 'string';
preg_match_all('/(.*)\((.*)\)/', $type, $matches);
$type = isset($matches[1][0]) ? $matches[1][0] : 'string';
$length = isset($matches[2][0]) ? $matches[2][0] : null;
$class->mapField(array(
'fieldName' => $name,
'type' => $type,
'length' => $length
));
}
}
// Setup a new exporter for the mapping type specified
$cme = new ClassMetadataExporter();
$exporter = $cme->getExporter($mappingType);
if ($mappingType === 'annotation') {
$path = $dirs[$namespace].'/'.$bundle.'/Entity/'.str_replace($entityNamespace.'\\', null, $fullEntityClassName).'.php';
$exporter->setEntityGenerator($this->getEntityGenerator());
} else {
$mappingType = $mappingType == 'yaml' ? 'yml' : $mappingType;
$path = $dirs[$namespace].'/'.$bundle.'/Resources/config/doctrine/metadata/orm/'.str_replace('\\', '.', $fullEntityClassName).'.dcm.'.$mappingType;
}
$code = $exporter->exportClassMetadata($class);
if (!is_dir($dir = dirname($path))) {
mkdir($dir, 0777, true);
}
$output->writeln(sprintf('Generating entity for "<info>%s</info>"', $bundle));
$output->writeln(sprintf(' > generating <comment>%s</comment>', $fullEntityClassName));
file_put_contents($path, $code);
}
}