Skip to content

Commit a963522

Browse files
New make Stimulus controller
update test Coding standards Coding standards Make constants private Add targets and language
1 parent b6b0afe commit a963522

File tree

7 files changed

+272
-0
lines changed

7 files changed

+272
-0
lines changed

src/Maker/MakeStimulusController.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\Maker;
13+
14+
use Symfony\Bundle\MakerBundle\ConsoleStyle;
15+
use Symfony\Bundle\MakerBundle\DependencyBuilder;
16+
use Symfony\Bundle\MakerBundle\Generator;
17+
use Symfony\Bundle\MakerBundle\InputConfiguration;
18+
use Symfony\Component\Console\Command\Command;
19+
use Symfony\Component\Console\Input\InputArgument;
20+
use Symfony\Component\Console\Input\InputInterface;
21+
use Symfony\WebpackEncoreBundle\WebpackEncoreBundle;
22+
23+
/**
24+
* @author Abdelilah Jabri <[email protected]>
25+
*
26+
* @internal
27+
*/
28+
final class MakeStimulusController extends AbstractMaker
29+
{
30+
public static function getCommandName(): string
31+
{
32+
return 'make:stimulus-controller';
33+
}
34+
35+
public static function getCommandDescription(): string
36+
{
37+
return 'Creates a new Stimulus controller';
38+
}
39+
40+
public function configureCommand(Command $command, InputConfiguration $inputConfig)
41+
{
42+
$command
43+
->addArgument('name', InputArgument::REQUIRED, 'The name of the Stimulus controller (e.g. <fg=yellow>hello</>)')
44+
->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeStimulusController.txt'));
45+
}
46+
47+
public function interact(InputInterface $input, ConsoleStyle $io, Command $command)
48+
{
49+
$command->addArgument('extension', InputArgument::OPTIONAL);
50+
$command->addArgument('targets', InputArgument::IS_ARRAY, '', []);
51+
52+
$chosenExtension = $io->choice(
53+
'Language (<fg=yellow>JavaScript</> or <fg=yellow>TypeScript</>)',
54+
[
55+
'js' => 'JavaScript',
56+
'ts' => 'TypeScript',
57+
]
58+
);
59+
60+
$input->setArgument('extension', $chosenExtension);
61+
62+
$includeTargets = $io->confirm('Do you want to include targets?');
63+
if ($includeTargets) {
64+
$targets = [];
65+
$isFirstTarget = true;
66+
while (true) {
67+
$newTarget = $this->askForNextTarget($io, $targets, $isFirstTarget);
68+
$isFirstTarget = false;
69+
70+
if (null === $newTarget) {
71+
break;
72+
}
73+
74+
$targets[] = $newTarget;
75+
}
76+
77+
$input->setArgument('targets', $targets);
78+
}
79+
}
80+
81+
public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator)
82+
{
83+
$controllerName = $input->getArgument('name');
84+
$chosenExtension = $input->getArgument('extension');
85+
$targets = $input->getArgument('targets');
86+
87+
$targets = empty($targets) ? $targets : sprintf("['%s']", implode("', '", $targets));
88+
89+
$fileName = sprintf('%s_controller.%s', $controllerName, $chosenExtension);
90+
$filePath = sprintf('assets/controllers/%s', $fileName);
91+
92+
$generator->generateFile(
93+
$filePath,
94+
'stimulus/Controller.tpl.php',
95+
[
96+
'targets' => $targets
97+
]
98+
);
99+
100+
$generator->writeChanges();
101+
102+
$this->writeSuccessMessage($io);
103+
104+
$io->text([
105+
'Next:',
106+
sprintf('- Open <info>%s</info> and add the code you need', $filePath),
107+
'Find the documentation at <fg=yellow>https://github.com/symfony/stimulus-bridge</>',
108+
]);
109+
}
110+
111+
private function askForNextTarget(ConsoleStyle $io, array $targets, bool $isFirstTarget)
112+
{
113+
if ($isFirstTarget) {
114+
$questionText = 'New target name (press <return> to stop adding targets)';
115+
} else {
116+
$questionText = 'Add another target? Enter the target name (or press <return> to stop adding targets)';
117+
}
118+
119+
$targetName = $io->ask($questionText, null, function ($name) use ($targets) {
120+
if (\in_array($name, $targets)) {
121+
throw new \InvalidArgumentException(sprintf('The "%s" target already exists.', $name));
122+
}
123+
124+
return $name;
125+
});
126+
127+
if (!$targetName) {
128+
return null;
129+
}
130+
131+
return $targetName;
132+
}
133+
134+
public function configureDependencies(DependencyBuilder $dependencies)
135+
{
136+
$dependencies->addClassDependency(
137+
WebpackEncoreBundle::class,
138+
'webpack-encore-bundle'
139+
);
140+
}
141+
}

src/Resources/config/makers.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,9 @@
129129
<argument>%kernel.project_dir%</argument>
130130
<tag name="maker.command" />
131131
</service>
132+
133+
<service id="maker.maker.make_stimulus_controller" class="Symfony\Bundle\MakerBundle\Maker\MakeStimulusController">
134+
<tag name="maker.command" />
135+
</service>
132136
</services>
133137
</container>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The <info>%command.name%</info> command generates new Stimulus Controller.
2+
3+
<info>php %command.full_name% hello</info>
4+
5+
If the argument is missing, the command will ask for the controller name interactively.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Controller } from '@hotwired/stimulus';
2+
3+
/*
4+
* The following line makes this controller "lazy": it won't be downloaded until needed
5+
* See https://github.com/symfony/stimulus-bridge#lazy-controllers
6+
*/
7+
/* stimulusFetch: 'lazy' */
8+
export default class extends Controller {
9+
<?= $targets ? " static targets = $targets\n" : "" ?>
10+
// ...
11+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\Tests\Maker;
13+
14+
use Symfony\Bundle\MakerBundle\Maker\MakeStimulusController;
15+
use Symfony\Bundle\MakerBundle\Test\MakerTestCase;
16+
use Symfony\Bundle\MakerBundle\Test\MakerTestRunner;
17+
18+
class MakeStimulusControllerTest extends MakerTestCase
19+
{
20+
protected function getMakerClass(): string
21+
{
22+
return MakeStimulusController::class;
23+
}
24+
25+
public function getTestDetails()
26+
{
27+
yield 'it_generates_stimulus_controller_with_targets' => [$this->createMakerTest()
28+
->run(function (MakerTestRunner $runner) {
29+
$runner->runMaker(
30+
[
31+
'with_targets', //controller name
32+
'js', //controller language
33+
'yes', //add targets
34+
'results', //first target
35+
'messages', //second target
36+
'errors', //third target
37+
'', //empty input to stop adding targets
38+
]);
39+
40+
$generatedFilePath = $runner->getPath('assets/controllers/with_targets_controller.js');
41+
42+
$this->assertFileExists($generatedFilePath);
43+
44+
$generatedFileContents = file_get_contents($generatedFilePath);
45+
$expectedContents = file_get_contents(__DIR__.'/../fixtures/make-stimulus-controller/with_targets.js');
46+
47+
$this->assertSame(
48+
$expectedContents,
49+
$generatedFileContents
50+
);
51+
}),
52+
];
53+
54+
yield 'it_generates_stimulus_controller_without_targets' => [$this->createMakerTest()
55+
->run(function (MakerTestRunner $runner) {
56+
$runner->runMaker(
57+
[
58+
'without_targets', //controller name
59+
'js', //controller language
60+
'no', //do not add targets
61+
]);
62+
63+
$generatedFilePath = $runner->getPath('assets/controllers/without_targets_controller.js');
64+
65+
$this->assertFileExists($generatedFilePath);
66+
67+
$generatedFileContents = file_get_contents($generatedFilePath);
68+
$expectedContents = file_get_contents(__DIR__.'/../fixtures/make-stimulus-controller/without_targets.js');
69+
70+
$this->assertSame(
71+
$expectedContents,
72+
$generatedFileContents
73+
);
74+
}),
75+
];
76+
77+
yield 'it_generates_typescript_stimulus_controller' => [$this->createMakerTest()
78+
->run(function (MakerTestRunner $runner) {
79+
$runner->runMaker(
80+
[
81+
'typescript', //controller name
82+
'ts', //controller language
83+
'no', //do not add targets
84+
]);
85+
86+
$this->assertFileExists($runner->getPath('assets/controllers/typescript_controller.ts'));
87+
}),
88+
];
89+
}
90+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Controller } from '@hotwired/stimulus';
2+
3+
/*
4+
* The following line makes this controller "lazy": it won't be downloaded until needed
5+
* See https://github.com/symfony/stimulus-bridge#lazy-controllers
6+
*/
7+
/* stimulusFetch: 'lazy' */
8+
export default class extends Controller {
9+
static targets = ['results', 'messages', 'errors']
10+
// ...
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Controller } from '@hotwired/stimulus';
2+
3+
/*
4+
* The following line makes this controller "lazy": it won't be downloaded until needed
5+
* See https://github.com/symfony/stimulus-bridge#lazy-controllers
6+
*/
7+
/* stimulusFetch: 'lazy' */
8+
export default class extends Controller {
9+
// ...
10+
}

0 commit comments

Comments
 (0)