Skip to content

Commit 3a3da45

Browse files
author
janvt
authored
Merge pull request #22 from geekcell/feat/maker-controller
Maker Command - Controller
2 parents 9dd1210 + 3e52790 commit 3a3da45

File tree

6 files changed

+226
-2
lines changed

6 files changed

+226
-2
lines changed

README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,5 +206,26 @@ Usage:
206206
make:ddd:query|command [<name>]
207207

208208
Arguments:
209-
name The name of the query|command class (e.g. Customer)
209+
name The name of the query|command class (e.g. Customer)
210+
```
211+
212+
### Controller
213+
214+
This command can be used to generate a controller with optional `QueryBus` and `CommandBus` dependencies.
215+
216+
#### Command Output
217+
218+
```bash
219+
Description:
220+
Creates a new controller class
221+
222+
Usage:
223+
make:ddd:controller [options] [--] [<name>]
224+
225+
Arguments:
226+
name The name of the model class (e.g. Customer)
227+
228+
Options:
229+
--include-query-bus Add a query bus dependency
230+
--include-command-bus Add a command bus dependency
210231
```

config/services.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ services:
3535
tags:
3636
- { name: maker.command }
3737

38+
GeekCell\DddBundle\Maker\MakeController:
39+
class: GeekCell\DddBundle\Maker\MakeController
40+
arguments:
41+
- '@maker.file_manager'
42+
tags:
43+
- { name: maker.command }
44+
3845
GeekCell\DddBundle\Maker\Doctrine\DoctrineConfigUpdater:
3946
class: GeekCell\DddBundle\Maker\Doctrine\DoctrineConfigUpdater
4047
public: false

src/Maker/MakeController.php

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace GeekCell\DddBundle\Maker;
6+
7+
use GeekCell\Ddd\Contracts\Application\CommandBus;
8+
use GeekCell\Ddd\Contracts\Application\QueryBus;
9+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
10+
use Symfony\Bundle\MakerBundle\FileManager;
11+
use Symfony\Bundle\MakerBundle\InputConfiguration;
12+
use Symfony\Bundle\MakerBundle\DependencyBuilder;
13+
use Symfony\Bundle\MakerBundle\ConsoleStyle;
14+
use Symfony\Bundle\MakerBundle\Generator;
15+
use Symfony\Bundle\MakerBundle\InputAwareMakerInterface;
16+
use Symfony\Bundle\MakerBundle\Maker\AbstractMaker;
17+
use Symfony\Bundle\MakerBundle\Util\UseStatementGenerator;
18+
use Symfony\Component\Console\Command\Command;
19+
use Symfony\Component\Console\Input\InputArgument;
20+
use Symfony\Component\Console\Input\InputInterface;
21+
use Symfony\Component\Console\Input\InputOption;
22+
use Symfony\Component\HttpFoundation\Response;
23+
use Symfony\Component\Routing\Annotation\Route;
24+
25+
final class MakeController extends AbstractMaker implements InputAwareMakerInterface
26+
{
27+
const NAMESPACE_PREFIX = 'Infrastructure\\Http\\Controller\\';
28+
const CONFIG_PATH = 'config/routes/ddd.yaml';
29+
30+
public function __construct(private FileManager $fileManager)
31+
{
32+
}
33+
34+
/**
35+
* @inheritDoc
36+
*/
37+
public static function getCommandName(): string
38+
{
39+
return 'make:ddd:controller';
40+
}
41+
42+
/**
43+
* @inheritDoc
44+
*/
45+
public static function getCommandDescription(): string
46+
{
47+
return 'Creates a new controller class';
48+
}
49+
50+
/**
51+
* @inheritDoc
52+
*/
53+
public function configureCommand(Command $command, InputConfiguration $inputConfig): void
54+
{
55+
$command
56+
->addArgument(
57+
'name',
58+
InputArgument::REQUIRED,
59+
'The name of the controller class (e.g. <fg=yellow>Customer</>)',
60+
)
61+
->addOption(
62+
'include-query-bus',
63+
null,
64+
InputOption::VALUE_REQUIRED,
65+
'Add a query bus dependency.',
66+
false
67+
)
68+
->addOption(
69+
'include-command-bus',
70+
null,
71+
InputOption::VALUE_REQUIRED,
72+
'Add a command bus dependency.',
73+
false
74+
)
75+
;
76+
}
77+
78+
/**
79+
* @inheritDoc
80+
*/
81+
public function configureDependencies(DependencyBuilder $dependencies, InputInterface $input = null): void
82+
{
83+
}
84+
85+
/**
86+
* @inheritDoc
87+
*/
88+
public function interact(InputInterface $input, ConsoleStyle $io, Command $command): void
89+
{
90+
if (false === $input->getOption('include-query-bus')) {
91+
$includeQueryBus = $io->confirm(
92+
'Do you want to add a query bus dependency?',
93+
false,
94+
);
95+
$input->setOption('include-query-bus', $includeQueryBus);
96+
}
97+
98+
if (false === $input->getOption('include-command-bus')) {
99+
$includeCommandBus = $io->confirm(
100+
'Do you want to add a command bus dependency?',
101+
false,
102+
);
103+
$input->setOption('include-command-bus', $includeCommandBus);
104+
}
105+
}
106+
107+
/**
108+
* @inheritDoc
109+
*/
110+
public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void
111+
{
112+
$classNameDetails = $generator->createClassNameDetails(
113+
$input->getArgument('name'),
114+
self::NAMESPACE_PREFIX,
115+
'Controller',
116+
);
117+
118+
$classesToImport = [
119+
AbstractController::class,
120+
Route::class,
121+
Response::class
122+
];
123+
124+
$routeName = lcfirst($input->getArgument('name'));
125+
$templateVars = [
126+
'route_name' => $routeName,
127+
'route_name_snake' => strtolower(
128+
preg_replace(
129+
["/([A-Z]+)/", "/_([A-Z]+)([A-Z][a-z])/"],
130+
["_$1", "_$1_$2"],
131+
$routeName
132+
)
133+
),
134+
'dependencies' => []
135+
];
136+
137+
if ($input->getOption('include-query-bus')) {
138+
$templateVars['dependencies'][] = 'private QueryBus $queryBus';
139+
$classesToImport[] = QueryBus::class;
140+
}
141+
142+
if ($input->getOption('include-command-bus')) {
143+
$templateVars['dependencies'][] = 'private CommandBus $commandBus';
144+
$classesToImport[] = CommandBus::class;
145+
}
146+
147+
$templateVars['use_statements'] = new UseStatementGenerator($classesToImport);
148+
149+
$templatePath = __DIR__.'/../Resources/skeleton/controller/Controller.tpl.php';
150+
$generator->generateClass(
151+
$classNameDetails->getFullName(),
152+
$templatePath,
153+
$templateVars,
154+
);
155+
156+
// ensure controller config has been created
157+
if (!$this->fileManager->fileExists(self::CONFIG_PATH)) {
158+
$templatePathConfig = __DIR__ . '/../Resources/skeleton/controller/RouteConfig.tpl.php';
159+
$generator->generateFile(
160+
self::CONFIG_PATH,
161+
$templatePathConfig,
162+
[
163+
'path' => '../../src/Infrastructure/Http/Controller/',
164+
'namespace' => str_replace('\\' . $classNameDetails->getShortName(), '', $classNameDetails->getFullName())
165+
]
166+
);
167+
}
168+
169+
$generator->writeChanges();
170+
171+
$this->writeSuccessMessage($io);
172+
}
173+
}

src/Maker/MakeModel.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma
154154
$modelName,
155155
$useSuffix ? 'Model' : '',
156156
),
157-
true,
158157
);
159158
$input->setOption('aggregate-root', $asAggregateRoot);
160159
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?= "<?php\n" ?>
2+
3+
namespace <?= $namespace; ?>;
4+
5+
<?= $use_statements ?>
6+
7+
class <?= $class_name ?> extends AbstractController
8+
{
9+
<?php if (count($dependencies) > 0): ?>
10+
public function __construct(<?= implode(', ', $dependencies ) ?>)
11+
{}
12+
13+
<?php endif; ?>
14+
#[Route('/<?= $route_name_snake ?>', name: '<?= $route_name_snake ?>')]
15+
public function <?= $route_name ?>(): Response
16+
{
17+
return new Response();
18+
}
19+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
controllers:
2+
resource:
3+
path: <?= $path ?><?= "\n" ?>
4+
namespace: <?= $namespace ?><?= "\n" ?>
5+
type: attribute

0 commit comments

Comments
 (0)