Skip to content

Commit e9192e4

Browse files
committed
[make:controller] generate final controller class
1 parent a3b7f14 commit e9192e4

File tree

7 files changed

+113
-20
lines changed

7 files changed

+113
-20
lines changed

src/Maker/MakeController.php

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
use Symfony\Bundle\MakerBundle\Generator;
1818
use Symfony\Bundle\MakerBundle\InputConfiguration;
1919
use Symfony\Bundle\MakerBundle\Str;
20+
use Symfony\Bundle\MakerBundle\Util\ClassSource\Model\ClassData;
2021
use Symfony\Bundle\MakerBundle\Util\PhpCompatUtil;
21-
use Symfony\Bundle\MakerBundle\Util\UseStatementGenerator;
2222
use Symfony\Bundle\TwigBundle\TwigBundle;
2323
use Symfony\Component\Console\Command\Command;
2424
use Symfony\Component\Console\Input\InputArgument;
@@ -76,22 +76,48 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
7676
$withTemplate = $this->isTwigInstalled() && !$input->getOption('no-template');
7777
$isInvokable = (bool) $input->getOption('invokable');
7878

79-
$useStatements = new UseStatementGenerator([
80-
AbstractController::class,
81-
$withTemplate ? Response::class : JsonResponse::class,
82-
Route::class,
83-
]);
79+
$controllerClass = $input->getArgument('controller-class');
8480

85-
$templateName = Str::asFilePath($controllerClassNameDetails->getRelativeNameWithoutSuffix())
81+
$controllerClassData = ClassData::create(
82+
class: '\\' === $controllerClass[0] ? substr($controllerClass, 1) : \sprintf('Controller\%s', $input->getArgument('controller-class')),
83+
suffix: 'Controller',
84+
extendsClass: AbstractController::class,
85+
useStatements: [
86+
$withTemplate ? Response::class : JsonResponse::class,
87+
Route::class,
88+
]
89+
);
90+
91+
// dd([
92+
// $controllerClassNameDetails,
93+
// $controllerClassNameDetails->getRelativeName(),
94+
// $controllerClassNameDetails->getShortName(),
95+
// $controllerClassNameDetails->getFullName(),
96+
// $controllerClassNameDetails->getRelativeNameWithoutSuffix(),
97+
// ],
98+
// [
99+
// $controllerClassData,
100+
// $controllerClassData->getClassName(relative: true),
101+
// $controllerClassData->getClassName(),
102+
// $controllerClassData->getFullClassName(),
103+
// $controllerClassData->getClassName(relative: true, withoutSuffix: true),
104+
// ]
105+
// );
106+
107+
// $templateName = Str::asFilePath($controllerClassNameDetails->getRelativeNameWithoutSuffix())
108+
$templateName = Str::asFilePath($controllerClassData->getClassName(relative: true, withoutSuffix: true))
86109
.($isInvokable ? '.html.twig' : '/index.html.twig');
87110

88111
$controllerPath = $generator->generateController(
89-
$controllerClassNameDetails->getFullName(),
112+
$controllerClassData->getFullClassName(),
90113
'controller/Controller.tpl.php',
91114
[
92-
'use_statements' => $useStatements,
93-
'route_path' => Str::asRoutePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()),
94-
'route_name' => Str::asRouteName($controllerClassNameDetails->getRelativeNameWithoutSuffix()),
115+
'class_data' => $controllerClassData,
116+
// 'use_statements' => $useStatements,
117+
// 'route_path' => Str::asRoutePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()),
118+
'route_path' => Str::asRoutePath($controllerClassData->getClassName(relative: true, withoutSuffix: true)),
119+
'route_name' => Str::AsRouteName($controllerClassData->getClassName(relative: true, withoutSuffix: true)),
120+
// 'route_name' => Str::asRouteName($controllerClassNameDetails->getRelativeNameWithoutSuffix()),
95121
'method_name' => $isInvokable ? '__invoke' : 'index',
96122
'with_template' => $withTemplate,
97123
'template_name' => $templateName,
@@ -105,7 +131,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
105131
[
106132
'controller_path' => $controllerPath,
107133
'root_directory' => $generator->getRootDirectory(),
108-
'class_name' => $controllerClassNameDetails->getShortName(),
134+
'class_name' => $controllerClassData->getClassName(),
109135
]
110136
);
111137
}

src/Resources/skeleton/controller/Controller.tpl.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<?= "<?php\n" ?>
22

3-
namespace <?= $namespace; ?>;
3+
namespace <?= $class_data->getNamespace(); ?>;
44

5-
<?= $use_statements; ?>
5+
<?= $class_data->getUseStatements(); ?>
66

7-
class <?= $class_name; ?> extends AbstractController
7+
<?= $class_data->getClassDeclaration(); ?>
88
{
99
<?= $generator->generateRouteForControllerMethod($route_path, $route_name); ?>
1010
public function <?= $method_name ?>(): <?php if ($with_template) { ?>Response<?php } else { ?>JsonResponse<?php } ?>

src/Util/ClassSource/Model/ClassData.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ private function __construct(
2929
private UseStatementGenerator $useStatementGenerator,
3030
private bool $isFinal = true,
3131
private string $rootNamespace = 'App',
32+
private ?string $classSuffix = null,
3233
) {
34+
if (str_starts_with(haystack: $this->namespace, needle: $this->rootNamespace)) {
35+
$this->namespace = substr_replace(string: $this->namespace, replace: '', offset: 0, length: \strlen($this->rootNamespace) + 1);
36+
}
3337
}
3438

3539
public static function create(string $class, ?string $suffix = null, ?string $extendsClass = null, bool $isEntity = false, array $useStatements = []): self
@@ -52,12 +56,30 @@ className: Str::asClassName($className),
5256
extends: null === $extendsClass ? null : Str::getShortClassName($extendsClass),
5357
isEntity: $isEntity,
5458
useStatementGenerator: $useStatements,
59+
classSuffix: $suffix,
5560
);
5661
}
5762

58-
public function getClassName(): string
63+
public function getClassName(bool $relative = false, bool $withoutSuffix = false): string
5964
{
60-
return $this->className;
65+
if (!$withoutSuffix && !$relative) {
66+
return $this->className;
67+
}
68+
69+
if ($relative) {
70+
$class = \sprintf('%s\%s', $this->namespace, $this->className);
71+
72+
$firstNsSeparatorPosition = stripos($class, '\\');
73+
$class = substr_replace(string: $class, replace: '', offset: 0, length: $firstNsSeparatorPosition + 1);
74+
75+
if ($withoutSuffix) {
76+
$class = Str::removeSuffix($class, $this->classSuffix);
77+
}
78+
79+
return $class;
80+
}
81+
82+
return Str::removeSuffix($this->className, $this->classSuffix);
6183
}
6284

6385
public function getNamespace(): string

tests/Util/ClassSource/ClassDataTest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Bundle\MakerBundle\MakerBundle;
1616
use Symfony\Bundle\MakerBundle\Test\MakerTestKernel;
17+
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
1718
use Symfony\Bundle\MakerBundle\Util\ClassSource\Model\ClassData;
1819

1920
class ClassDataTest extends TestCase
@@ -91,4 +92,48 @@ public function namespaceDataProvider(): \Generator
9192
yield ['MyController', 'Maker', 'Maker', 'Maker\MyController'];
9293
yield ['Controller\MyController', 'Maker', 'Maker\Controller', 'Maker\Controller\MyController'];
9394
}
95+
96+
public function testGetClassName(): void
97+
{
98+
$class = ClassData::create(class: 'Controller\\Foo', suffix: 'Controller');
99+
self::assertSame('FooController', $class->getClassName());
100+
self::assertSame('Foo', $class->getClassName(relative: false, withoutSuffix: true));
101+
self::assertSame('FooController', $class->getClassName(relative: true, withoutSuffix: false));
102+
self::assertSame('Foo', $class->getClassName(relative: true, withoutSuffix: true));
103+
self::assertSame('App\Controller\FooController', $class->getFullClassName());
104+
}
105+
106+
public function testGetClassNameRelativeNamespace(): void
107+
{
108+
$class = ClassData::create(class: 'Controller\\Admin\\Foo', suffix: 'Controller');
109+
self::assertSame('FooController', $class->getClassName());
110+
self::assertSame('Foo', $class->getClassName(relative: false, withoutSuffix: true));
111+
self::assertSame('Admin\FooController', $class->getClassName(relative: true, withoutSuffix: false));
112+
self::assertSame('Admin\Foo', $class->getClassName(relative: true, withoutSuffix: true));
113+
self::assertSame('App\Controller\Admin\FooController', $class->getFullClassName());
114+
}
115+
116+
public function testGetClassNameWithAbsoluteNamespace(): void
117+
{
118+
$class = ClassData::create(class: '\\Foo\\Bar\\Admin\\Baz', suffix: 'Controller');
119+
self::assertSame('BazController', $class->getClassName());
120+
self::assertSame('Baz', $class->getClassName(relative: false, withoutSuffix: true));
121+
// self::assertSame('Admin\FooController', $class->getClassName(relative: true, withoutSuffix: false));
122+
// self::assertSame('Admin\Baz', $class->getClassName(relative: true, withoutSuffix: true));
123+
self::assertSame('Foo\Bar\Admin\BazController', $class->getFullClassName());
124+
}
125+
126+
// public function testClassNameDetails(): void
127+
// {
128+
// $class = new ClassNameDetails(
129+
// fullClassName: 'Foo',
130+
// namespacePrefix: 'Controller\\',
131+
// suffix: 'Controller',
132+
// );
133+
//
134+
// self::assertSame('FooController', $class->getFullName());
135+
// self::assertSame('MyController', $class->getShortName());
136+
// self::assertSame('My', $class->getRelativeNameWithoutSuffix());
137+
// self::assertSame('MyController', $class->getRelativeName());
138+
// }
94139
}

tests/fixtures/make-controller/tests/it_generates_a_controller.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
66

7-
class GeneratedControllerTest extends WebTestCase
7+
final class GeneratedControllerTest extends WebTestCase
88
{
99
public function testController()
1010
{

tests/fixtures/make-controller/tests/it_generates_a_controller_with_twig.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
66

7-
class GeneratedControllerTest extends WebTestCase
7+
final class GeneratedControllerTest extends WebTestCase
88
{
99
public function testController()
1010
{

tests/fixtures/make-controller/tests/it_generates_an_invokable_controller.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
66

7-
class GeneratedControllerTest extends WebTestCase
7+
final class GeneratedControllerTest extends WebTestCase
88
{
99
public function testControllerValidity()
1010
{

0 commit comments

Comments
 (0)