diff --git a/src/Generator.php b/src/Generator.php index bf2ab0d3c..b6e16470b 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -11,7 +11,6 @@ namespace Symfony\Bundle\MakerBundle; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException; use Symfony\Bundle\MakerBundle\Util\ClassNameDetails; @@ -85,22 +84,6 @@ public function dumpFile(string $targetPath, string $contents) ]; } - public function getFileContentsForPendingOperation(string $targetPath): string - { - if (!isset($this->pendingOperations[$targetPath])) { - throw new RuntimeCommandException(sprintf('File "%s" is not in the Generator\'s pending operations', $targetPath)); - } - - $templatePath = $this->pendingOperations[$targetPath]['template']; - $parameters = $this->pendingOperations[$targetPath]['variables']; - - $templateParameters = array_merge($parameters, [ - 'relative_path' => $this->fileManager->relativizePath($targetPath), - ]); - - return $this->fileManager->parseTemplate($templatePath, $templateParameters); - } - /** * Creates a helper object to get data about a class name. * @@ -152,6 +135,27 @@ public function createClassNameDetails(string $name, string $namespacePrefix, st return new ClassNameDetails($className, $fullNamespacePrefix, $suffix); } + public function createControllerClassNameDetails(string $name, string $namespacePrefix, string $suffix = '', $Infolder, string $validationErrorMessage = ''): ClassNameDetails + { + $fullNamespacePrefix = $this->namespacePrefix.'\\'.$namespacePrefix; + if ('\\' === $name[0]) { + // class is already "absolute" - leave it alone (but strip opening \) + $className = substr($name, 1); + } else { + $className = ($Infolder) ? rtrim($fullNamespacePrefix, '\\') . '\\' . $suffix . '\\' . Str::asClassName($name) : rtrim($fullNamespacePrefix, '\\').'\\'.Str::asClassName($name, $suffix) ; + } + + Validator::validateClassName($className, $validationErrorMessage); + + // if this is a custom class, we may be completely different than the namespace prefix + // the best way can do, is find the PSR4 prefix and use that + if (0 !== strpos($className, $fullNamespacePrefix)) { + $fullNamespacePrefix = $this->fileManager->getNamespacePrefixForClass($className); + } + + return new ClassNameDetails($className, $fullNamespacePrefix, $suffix); + } + private function addOperation(string $targetPath, string $templateName, array $variables) { if ($this->fileManager->fileExists($targetPath)) { @@ -195,10 +199,15 @@ public function writeChanges() continue; } - $this->fileManager->dumpFile( - $targetPath, - $this->getFileContentsForPendingOperation($targetPath, $templateData) - ); + $templatePath = $templateData['template']; + $parameters = $templateData['variables']; + + $templateParameters = array_merge($parameters, [ + 'relative_path' => $this->fileManager->relativizePath($targetPath), + ]); + + $fileContents = $this->fileManager->parseTemplate($templatePath, $templateParameters); + $this->fileManager->dumpFile($targetPath, $fileContents); } $this->pendingOperations = []; @@ -208,16 +217,4 @@ public function getRootNamespace(): string { return $this->namespacePrefix; } - - public function generateController(string $controllerClassName, string $controllerTemplatePath, array $parameters = []): string - { - return $this->generateClass( - $controllerClassName, - $controllerTemplatePath, - $parameters + - [ - 'parent_class_name' => \method_exists(AbstractController::class, 'getParameter') ? 'AbstractController' : 'Controller', - ] - ); - } } diff --git a/src/Maker/MakeController.php b/src/Maker/MakeController.php index 757e98754..983469c64 100644 --- a/src/Maker/MakeController.php +++ b/src/Maker/MakeController.php @@ -12,9 +12,11 @@ namespace Symfony\Bundle\MakerBundle\Maker; use Doctrine\Common\Annotations\Annotation; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; use Symfony\Bundle\MakerBundle\Generator; +use Symfony\Component\Console\Input\InputOption; use Symfony\Bundle\MakerBundle\InputConfiguration; use Symfony\Bundle\MakerBundle\Str; use Symfony\Bundle\TwigBundle\TwigBundle; @@ -38,31 +40,39 @@ public function configureCommand(Command $command, InputConfiguration $inputConf $command ->setDescription('Creates a new controller class') ->addArgument('controller-class', InputArgument::OPTIONAL, sprintf('Choose a name for your controller class (e.g. %sController)', Str::asClassName(Str::getRandomTerm()))) + ->addOption('path', null, InputOption::VALUE_OPTIONAL, 'Choose a path for your controller (e.g. "Foo/Bar")') + ->addOption('template', true, InputOption::VALUE_OPTIONAL, 'If this option is set to false we will skip template creation') ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeController.txt')) ; } public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) { - $controllerClassNameDetails = $generator->createClassNameDetails( + $ControllerPathName = $input->getOption('path'); + $Infolder = ($ControllerPathName) ? true : false; + $SuffixName = ($Infolder) ? str_replace('/',"\\",$ControllerPathName) : 'Controller'; + $controllerClassNameDetails = $generator->createControllerClassNameDetails( $input->getArgument('controller-class'), 'Controller\\', - 'Controller' + $SuffixName, + $Infolder ); - - $templateName = Str::asFilePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()).'/index.html.twig'; - $controllerPath = $generator->generateController( + $templateName = ($Infolder) ? + Str::asFilePath($ControllerPathName).'/index.html.twig' : + Str::asFilePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()).'/index.html.twig'; + $controllerPath = $generator->generateClass( $controllerClassNameDetails->getFullName(), 'controller/Controller.tpl.php', [ - 'route_path' => Str::asRoutePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()), - 'route_name' => Str::asRouteName($controllerClassNameDetails->getRelativeNameWithoutSuffix()), + 'parent_class_name' => \method_exists(AbstractController::class, 'getParameter') ? 'AbstractController' : 'Controller', + 'route_path' => ($Infolder) ? str_replace("/controller","",Str::asRoutePath($controllerClassNameDetails->getRelativeNameWithoutSuffix())) : Str::asRoutePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()), + 'route_name' => ($Infolder) ? str_replace("_controller","",Str::asRouteName($controllerClassNameDetails->getRelativeNameWithoutSuffix())) : Str::asRouteName($controllerClassNameDetails->getRelativeNameWithoutSuffix()), 'twig_installed' => $this->isTwigInstalled(), 'template_name' => $templateName, ] ); - if ($this->isTwigInstalled()) { + if ($input->getOption('template') != false && $this->isTwigInstalled()) { $generator->generateFile( 'templates/'.$templateName, 'controller/twig_template.tpl.php',