1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
namespace SlayerBirden\DFCodeGeneration\Command; |
5
|
|
|
|
6
|
|
|
use Doctrine\Common\Annotations\AnnotationRegistry; |
7
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Config\Config; |
8
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Config\StandardProvider; |
9
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Controllers\Add; |
10
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Controllers\DecoratedProvider; |
11
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Controllers\Delete; |
12
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Controllers\EntityNamePluralDecorator; |
13
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Controllers\Get; |
14
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Controllers\Gets; |
15
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Controllers\RelationsProviderDecorator; |
16
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Controllers\UniqueProviderDecorator; |
17
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Controllers\Update; |
18
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Factory\Routes; |
19
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Tests\Add as TestAdd; |
20
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Tests\Delete as TestDelete; |
21
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Tests\Get as TestGet; |
22
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Tests\Gets as TestGets; |
23
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Tests\IdRegistry; |
24
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Tests\ReflectionProviderFactory; |
25
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Tests\Update as TestUpdate; |
26
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Factory\SimpleProvider; |
27
|
|
|
use SlayerBirden\DFCodeGeneration\Writer\OutputWriter; |
28
|
|
|
use SlayerBirden\DFCodeGeneration\Writer\Psr4FileNameProvider; |
29
|
|
|
use SlayerBirden\DFCodeGeneration\Writer\WriteInterface; |
30
|
|
|
use Symfony\Component\Console\Command\Command; |
31
|
|
|
use Symfony\Component\Console\Exception\InvalidArgumentException; |
32
|
|
|
use Symfony\Component\Console\Exception\LogicException; |
33
|
|
|
use Symfony\Component\Console\Input\InputArgument; |
34
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
35
|
|
|
use Symfony\Component\Console\Input\InputOption; |
36
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
37
|
|
|
use SlayerBirden\DFCodeGeneration\Generator\Controllers\SimpleProvider as ControllerSimpleProvider; |
38
|
|
|
|
39
|
|
|
class ApiSuiteCommand extends Command |
40
|
|
|
{ |
41
|
|
|
/** |
42
|
|
|
* @var OutputInterface |
43
|
|
|
*/ |
44
|
|
|
private $output; |
45
|
|
|
/** |
46
|
|
|
* @var string |
47
|
|
|
*/ |
48
|
|
|
private $entityClassName; |
49
|
|
|
/** |
50
|
|
|
* @var bool |
51
|
|
|
*/ |
52
|
|
|
private $force; |
53
|
|
|
/** |
54
|
|
|
* @var bool |
55
|
|
|
*/ |
56
|
|
|
private $tests; |
57
|
|
|
/** |
58
|
|
|
* @var null|WriteInterface |
59
|
|
|
*/ |
60
|
|
|
private $writer; |
61
|
|
|
|
62
|
4 |
|
public function __construct(?string $name = null, ?WriteInterface $writer = null) |
63
|
|
|
{ |
64
|
4 |
|
parent::__construct($name); |
65
|
4 |
|
$this->writer = $writer; |
66
|
4 |
|
} |
67
|
|
|
|
68
|
4 |
|
protected function configure() |
69
|
|
|
{ |
70
|
4 |
|
$this->setName('generate:api') |
71
|
4 |
|
->setDescription('Api Suite for Entity.') |
72
|
4 |
|
->setHelp('This command creates the full Api suite (CRUD + tests) for DataFlow Server Entity. Don\'t forget to use force flag if you want to write files.') |
73
|
4 |
|
->addArgument('entity', InputArgument::REQUIRED, 'Entity class') |
74
|
4 |
|
->addOption('tests', 't', InputOption::VALUE_NONE, 'Whether to create tests.') |
75
|
4 |
|
->addOption('force', 'f', InputOption::VALUE_NONE, 'Without force flag no writes happen (only output).'); |
76
|
4 |
|
} |
77
|
|
|
|
78
|
4 |
|
protected function initialize(InputInterface $input, OutputInterface $output) |
79
|
|
|
{ |
80
|
4 |
|
$this->output = $output; |
81
|
4 |
|
$this->entityClassName = $input->getArgument('entity'); |
82
|
4 |
|
$this->force = $input->getOption('force'); |
83
|
4 |
|
$this->tests = $input->getOption('tests'); |
84
|
|
|
// If it's not force mode we're using output writer |
85
|
4 |
|
if (!$this->force) { |
86
|
2 |
|
$this->writer = new OutputWriter($this->output, new Psr4FileNameProvider()); |
87
|
|
|
} |
88
|
|
|
|
89
|
4 |
|
AnnotationRegistry::registerLoader('class_exists'); |
|
|
|
|
90
|
4 |
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* {@inheritdoc} |
94
|
|
|
* @throws \Doctrine\Common\Annotations\AnnotationException |
95
|
|
|
* @throws \ReflectionException |
96
|
|
|
*/ |
97
|
4 |
|
protected function execute(InputInterface $input, OutputInterface $output) |
98
|
|
|
{ |
99
|
4 |
|
if (!class_exists($this->entityClassName)) { |
100
|
|
|
throw new InvalidArgumentException('Entity Class does not exist.'); |
101
|
|
|
} |
102
|
|
|
|
103
|
4 |
|
$this->generateControllerStack(); |
104
|
4 |
|
$this->generateRoutes(); |
105
|
4 |
|
$this->generateConfig(); |
106
|
4 |
|
if ($this->tests) { |
107
|
2 |
|
$this->generateTests(); |
108
|
|
|
} |
109
|
|
|
|
110
|
4 |
|
$output->writeln([ |
111
|
4 |
|
'<error>IMPORTANT: please check all generated files before committing.</error>', |
112
|
|
|
'<error># You might want to run something like "php-cs-fixer" to make sure formatting is correct.</error>', |
113
|
|
|
]); |
114
|
4 |
|
} |
115
|
|
|
|
116
|
2 |
|
private function generateTests(): void |
117
|
|
|
{ |
118
|
2 |
|
$entityProviderFactory = new ReflectionProviderFactory(new IdRegistry()); |
119
|
|
|
|
120
|
2 |
|
$files = []; |
121
|
2 |
|
$files[] = (new TestAdd($this->entityClassName, $entityProviderFactory))->generate(); |
122
|
2 |
|
$files[] = (new TestDelete($this->entityClassName, $entityProviderFactory))->generate(); |
123
|
2 |
|
$files[] = (new TestGet($this->entityClassName, $entityProviderFactory))->generate(); |
124
|
2 |
|
$files[] = (new TestGets($this->entityClassName, $entityProviderFactory))->generate(); |
125
|
2 |
|
$files[] = (new TestUpdate($this->entityClassName, $entityProviderFactory))->generate(); |
126
|
|
|
|
127
|
2 |
|
array_walk($files, function ($contents) { |
128
|
2 |
|
$this->writer->write($contents); |
|
|
|
|
129
|
2 |
|
}); |
130
|
|
|
|
131
|
2 |
|
$this->output->writeln('<info>Acceptance tests generated</info>'); |
132
|
2 |
|
} |
133
|
|
|
|
134
|
4 |
|
private function generateConfig(): void |
135
|
|
|
{ |
136
|
4 |
|
$this->getWriter()->write( |
137
|
4 |
|
(new Config(new StandardProvider($this->entityClassName)))->generate() |
138
|
|
|
); |
139
|
|
|
|
140
|
4 |
|
$this->output->writeln('<info>Config generated</info>'); |
141
|
4 |
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* @throws \Twig_Error_Loader |
145
|
|
|
* @throws \Twig_Error_Runtime |
146
|
|
|
* @throws \Twig_Error_Syntax |
147
|
|
|
*/ |
148
|
4 |
|
private function generateRoutes(): void |
149
|
|
|
{ |
150
|
4 |
|
$this->getWriter()->write( |
151
|
4 |
|
(new Routes(new SimpleProvider($this->entityClassName)))->generate() |
152
|
|
|
); |
153
|
|
|
|
154
|
4 |
|
$this->output->writeln('<info>Routes provider generated</info>'); |
155
|
4 |
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* @throws \Twig_Error_Loader |
159
|
|
|
* @throws \Twig_Error_Runtime |
160
|
|
|
* @throws \Twig_Error_Syntax |
161
|
|
|
*/ |
162
|
4 |
|
private function generateControllerStack(): void |
163
|
|
|
{ |
164
|
4 |
|
$files = []; |
165
|
4 |
|
$files[] = (new Add( |
166
|
4 |
|
new DecoratedProvider( |
167
|
4 |
|
$this->entityClassName, |
168
|
4 |
|
new UniqueProviderDecorator($this->entityClassName), |
169
|
4 |
|
new RelationsProviderDecorator($this->entityClassName) |
170
|
|
|
) |
171
|
4 |
|
))->generate(); |
172
|
4 |
|
$files[] = (new Delete(new ControllerSimpleProvider($this->entityClassName)))->generate(); |
173
|
4 |
|
$files[] = (new Get(new ControllerSimpleProvider($this->entityClassName)))->generate(); |
174
|
4 |
|
$files[] = (new Gets( |
175
|
4 |
|
new DecoratedProvider( |
176
|
4 |
|
$this->entityClassName, |
177
|
4 |
|
new EntityNamePluralDecorator() |
178
|
|
|
) |
179
|
4 |
|
))->generate(); |
180
|
4 |
|
$files[] = (new Update( |
181
|
4 |
|
new DecoratedProvider( |
182
|
4 |
|
$this->entityClassName, |
183
|
4 |
|
new UniqueProviderDecorator($this->entityClassName), |
184
|
4 |
|
new RelationsProviderDecorator($this->entityClassName) |
185
|
|
|
) |
186
|
4 |
|
))->generate(); |
187
|
|
|
|
188
|
4 |
|
array_walk($files, function ($contents) { |
189
|
4 |
|
$this->writer->write($contents); |
190
|
4 |
|
}); |
191
|
|
|
|
192
|
4 |
|
$this->output->writeln('<info>Controller stack generated</info>'); |
193
|
4 |
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* @return WriteInterface |
197
|
|
|
*/ |
198
|
4 |
|
private function getWriter(): WriteInterface |
199
|
|
|
{ |
200
|
4 |
|
if ($this->writer === null) { |
201
|
|
|
throw new LogicException('Writer is not defined!'); |
202
|
|
|
} |
203
|
4 |
|
return $this->writer; |
204
|
|
|
} |
205
|
|
|
} |
206
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.