Skip to content

Commit 522869b

Browse files
committed
support for root namespaces and suffix's
1 parent 7826980 commit 522869b

File tree

9 files changed

+105
-31
lines changed

9 files changed

+105
-31
lines changed

src/DependencyInjection/MakerExtension.php

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public function load(array $configs, ContainerBuilder $container): void
4949
$componentGeneratorDefinition
5050
->replaceArgument(0, $config['generate_final_classes'])
5151
->replaceArgument(1, $config['generate_final_entities'])
52+
->replaceArgument(2, $rootNamespace)
5253
;
5354

5455
$container->registerForAutoconfiguration(MakerInterface::class)

src/Maker/MakeCrud.php

+6-4
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
148148
} while (class_exists($formClassDetails->getFullName()));
149149

150150
$controllerClassData = ClassData::create(
151-
class: sprintf('App\Controller\%sController', $this->controllerClassName),
151+
class: sprintf('Controller\%s', $this->controllerClassName),
152+
suffix: 'Controller',
152153
extendsClass: AbstractController::class,
153154
useStatements: [
154155
$entityClassDetails->getFullName(),
@@ -175,7 +176,7 @@ class: sprintf('App\Controller\%sController', $this->controllerClassName),
175176
}
176177

177178
$generator->generateController(
178-
$controllerClassDetails->getFullName(),
179+
$controllerClassData->getFullClassName(),
179180
'crud/controller/Controller.tpl.php',
180181
array_merge([
181182
'class_data' => $controllerClassData,
@@ -247,7 +248,8 @@ class: sprintf('App\Controller\%sController', $this->controllerClassName),
247248

248249
if ($this->shouldGenerateTests()) {
249250
$testClassData = ClassData::create(
250-
class: sprintf('App\Tests\Controller\%sControllerTest', $entityClassDetails->getRelativeNameWithoutSuffix()),
251+
class: sprintf('Tests\Controller\%s', $entityClassDetails->getRelativeNameWithoutSuffix()),
252+
suffix: 'ControllerTest',
251253
extendsClass: WebTestCase::class,
252254
useStatements: [
253255
$entityClassDetails->getFullName(),
@@ -263,7 +265,7 @@ class: sprintf('App\Tests\Controller\%sControllerTest', $entityClassDetails->get
263265
}
264266

265267
$generator->generateClass(
266-
$testClassData->fullClassName,
268+
$testClassData->getFullClassName(),
267269
'crud/test/Test.EntityManager.tpl.php',
268270
[
269271
'class_data' => $testClassData,

src/Maker/MakeVoter.php

+12-10
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
use Symfony\Component\Console\Command\Command;
2020
use Symfony\Component\Console\Input\InputArgument;
2121
use Symfony\Component\Console\Input\InputInterface;
22+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
2223
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
24+
use Symfony\Component\Security\Core\User\UserInterface;
2325

2426
/**
2527
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
@@ -47,21 +49,21 @@ public function configureCommand(Command $command, InputConfiguration $inputConf
4749

4850
public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void
4951
{
50-
$classMetaData = ClassData::create(
51-
class: sprintf('App\Security\Voter\%sVoter', $input->getArgument('name')),
52+
$voterClassData = ClassData::create(
53+
class: sprintf('Security\Voter\%s', $input->getArgument('name')),
54+
suffix: 'Voter',
5255
extendsClass: Voter::class,
53-
);
54-
55-
$voterClassNameDetails = $generator->createClassNameDetails(
56-
$input->getArgument('name'),
57-
'Security\\Voter\\',
58-
'Voter'
56+
useStatements: [
57+
TokenInterface::class,
58+
Voter::class,
59+
UserInterface::class,
60+
]
5961
);
6062

6163
$generator->generateClass(
62-
$voterClassNameDetails->getFullName(),
64+
$voterClassData->getFullClassName(),
6365
'security/Voter.tpl.php',
64-
['class_data' => $classMetaData]
66+
['class_data' => $voterClassData]
6567
);
6668

6769
$generator->writeChanges();

src/Resources/config/services.xml

+3-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@
8080
</service>
8181

8282
<service id="maker.template_component_generator" class="Symfony\Bundle\MakerBundle\Util\TemplateComponentGenerator">
83-
<argument /> <!-- generate_final_classes -->
84-
<argument /> <!-- generate_final_entities -->
83+
<argument /> <!-- generate_final_classes -->
84+
<argument /> <!-- generate_final_entities -->
85+
<argument /> <!-- root_namespace -->
8586
</service>
8687
</services>
8788
</container>

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?= "<?php\n" ?>
22

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

55
<?= $class_data->getUseStatements(); ?>
66

src/Resources/skeleton/security/Voter.tpl.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
<?= "<?php\n" ?>
22

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

5-
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
6-
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
7-
use Symfony\Component\Security\Core\User\UserInterface;
5+
<?= $class_data->getUseStatements(); ?>
86

97
<?= $class_data->getClassDeclaration() ?>
108
{
@@ -16,7 +14,7 @@ protected function supports(string $attribute, mixed $subject): bool
1614
// replace with your own logic
1715
// https://symfony.com/doc/current/security/voters.html
1816
return in_array($attribute, [self::EDIT, self::VIEW])
19-
&& $subject instanceof \App\Entity\<?= str_replace('Voter', null, $class_name) ?>;
17+
&& $subject instanceof \App\Entity\<?= str_replace('Voter', null, $class_data->getClassName()) ?>;
2018
}
2119

2220
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool

src/Util/ClassSource/Model/ClassData.php

+37-6
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,65 @@
2222
final class ClassData
2323
{
2424
private function __construct(
25-
public readonly string $className,
26-
public readonly string $namespace,
27-
public readonly string $fullClassName,
25+
private string $className,
26+
private string $namespace,
2827
public readonly ?string $extends,
2928
public readonly bool $isEntity,
3029
private UseStatementGenerator $useStatementGenerator,
3130
private bool $isFinal = true,
31+
private string $rootNamespace = 'App',
3232
) {
3333
}
3434

35-
public static function create(string $class, ?string $extendsClass = null, bool $isEntity = false, array $useStatements = []): self
35+
public static function create(string $class, ?string $suffix = null, ?string $extendsClass = null, bool $isEntity = false, array $useStatements = []): self
3636
{
37+
$className = Str::getShortClassName($class);
38+
39+
if (null !== $suffix && !str_ends_with($className, $suffix)) {
40+
$className = Str::asClassName(sprintf('%s%s', $className, $suffix));
41+
}
42+
3743
$useStatements = new UseStatementGenerator($useStatements);
3844

3945
if ($extendsClass) {
4046
$useStatements->addUseStatement($extendsClass);
4147
}
4248

4349
return new self(
44-
className: Str::getShortClassName($class),
50+
className: Str::asClassName($className),
4551
namespace: Str::getNamespace($class),
46-
fullClassName: $class,
4752
extends: null === $extendsClass ? null : Str::getShortClassName($extendsClass),
4853
isEntity: $isEntity,
4954
useStatementGenerator: $useStatements,
5055
);
5156
}
5257

58+
public function getClassName(): string
59+
{
60+
return $this->className;
61+
}
62+
63+
public function getNamespace(): string
64+
{
65+
if (empty($this->namespace)) {
66+
return $this->rootNamespace;
67+
}
68+
69+
return sprintf('%s\%s', $this->rootNamespace, $this->namespace);
70+
}
71+
72+
public function getFullClassName(): string
73+
{
74+
return sprintf('%s\%s', $this->getNamespace(), $this->className);
75+
}
76+
77+
public function setRootNamespace(string $rootNamespace): self
78+
{
79+
$this->rootNamespace = $rootNamespace;
80+
81+
return $this;
82+
}
83+
5384
public function getClassDeclaration(): string
5485
{
5586
$extendsDeclaration = '';

src/Util/TemplateComponentGenerator.php

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ final class TemplateComponentGenerator
2323
public function __construct(
2424
private bool $generateFinalClasses,
2525
private bool $generateFinalEntities,
26+
private string $rootNamespace,
2627
) {
2728
}
2829

@@ -54,6 +55,8 @@ public function getPropertyType(ClassNameDetails $classNameDetails): ?string
5455

5556
public function configureClass(ClassData $classMetadata): ClassData
5657
{
58+
$classMetadata->setRootNamespace($this->rootNamespace);
59+
5760
if ($classMetadata->isEntity) {
5861
return $classMetadata->setIsFinal($this->generateFinalEntities);
5962
}

tests/Util/ClassSource/ClassDataTest.php

+39-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ public function testStaticConstructor(): void
2525
// Sanity check in case Maker's NS changes
2626
self::assertSame('Symfony\Bundle\MakerBundle\MakerBundle', MakerBundle::class);
2727

28-
self::assertSame('MakerBundle', $meta->className);
29-
self::assertSame('Symfony\Bundle\MakerBundle', $meta->namespace);
30-
self::assertSame('Symfony\Bundle\MakerBundle\MakerBundle', $meta->fullClassName);
28+
self::assertSame('MakerBundle', $meta->getClassName());
29+
self::assertSame('App\Symfony\Bundle\MakerBundle', $meta->getNamespace());
30+
self::assertSame('App\Symfony\Bundle\MakerBundle\MakerBundle', $meta->getFullClassName());
3131
}
3232

3333
public function testGetClassDeclaration(): void
@@ -55,4 +55,40 @@ public function testGetClassDeclarationWithExtends(): void
5555

5656
self::assertSame('final class MakerBundle extends MakerTestKernel', $meta->getClassDeclaration());
5757
}
58+
59+
/** @dataProvider suffixDataProvider */
60+
public function testSuffix(?string $suffix, string $expectedResult): void
61+
{
62+
$data = ClassData::create(class: MakerBundle::class, suffix: $suffix);
63+
64+
self::assertSame($expectedResult, $data->getClassName());
65+
}
66+
67+
public function suffixDataProvider(): \Generator
68+
{
69+
yield [null, 'MakerBundle'];
70+
yield ['Testing', 'MakerBundleTesting'];
71+
yield ['Bundle', 'MakerBundle'];
72+
}
73+
74+
/** @dataProvider namespaceDataProvider */
75+
public function testNamespace(string $class, ?string $rootNamespace, string $expectedNamespace, string $expectedFullClassName): void
76+
{
77+
$class = ClassData::create($class);
78+
79+
if (null !== $rootNamespace) {
80+
$class->setRootNamespace($rootNamespace);
81+
}
82+
83+
self::assertSame($expectedNamespace, $class->getNamespace());
84+
self::assertSame($expectedFullClassName, $class->getFullClassName());
85+
}
86+
87+
public function namespaceDataProvider(): \Generator
88+
{
89+
yield ['MyController', null, 'App', 'App\MyController'];
90+
yield ['Controller\MyController', null, 'App\Controller', 'App\Controller\MyController'];
91+
yield ['MyController', 'Maker', 'Maker', 'Maker\MyController'];
92+
yield ['Controller\MyController', 'Maker', 'Maker\Controller', 'Maker\Controller\MyController'];
93+
}
5894
}

0 commit comments

Comments
 (0)