Source of file GenerateControllerCommand.php
Size: 12,745 Bytes - Last Modified: 2013-07-04T14:20:59+02:00
/home/theseer/Downloads/Symfony/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateControllerCommand.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 | <?php /* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Sensio\Bundle\GeneratorBundle\Command; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper; use Sensio\Bundle\GeneratorBundle\Generator\ControllerGenerator; /** * Generates controllers. * * @author Wouter J <wouter@wouterj.nl> */ class GenerateControllerCommand extends GeneratorCommand { private $generator; /** * @see Command */ public function configure() { $this ->setDefinition(array( new InputOption( 'controller', '', InputOption::VALUE_REQUIRED, 'The name of the controller to create' ), new InputOption( 'route-format', '', InputOption::VALUE_REQUIRED, 'The format that is used for the routing (yml, xml, php, annotation)', 'annotation' ), new InputOption( 'template-format', '', InputOption::VALUE_REQUIRED, 'The format that is used for templating (twig, php)', 'twig' ), new InputOption( 'actions', '', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'The actions in the controller' ), )) ->setDescription('Generates a controller') ->setHelp(<<<EOT The <info>generate:controller</info> command helps you generates new controllers inside bundles. By default, the command interacts with the developer to tweak the generation. Any passed option will be used as a default value for the interaction (<comment>--bundle</comment> and <comment>--controller</comment> are the only ones needed if you follow the conventions): <info>php app/console generate:controller --controller=AcmeBlogBundle:Post</info> If you want to disable any user interaction, use <comment>--no-interaction</comment> but don't forget to pass all needed options: <info>php app/console generate:controller --controller=AcmeBlogBundle:Post --no-interaction</info> Every generated file is based on a template. There are default templates but they can be overriden by placing custom templates in one of the following locations, by order of priority: <info>BUNDLE_PATH/Resources/SensioGeneratorBundle/skeleton/controller APP_PATH/Resources/SensioGeneratorBundle/skeleton/controller</info> You can check https://github.com/sensio/SensioGeneratorBundle/tree/master/Resources/skeleton in order to know the file structure of the skeleton EOT ) ->setName('generate:controller') ; } public function execute(InputInterface $input, OutputInterface $output) { $dialog = $this->getDialogHelper(); if ($input->isInteractive()) { if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) { $output->writeln('<error>Command aborted</error>'); return 1; } } if (null === $input->getOption('controller')) { throw new \RuntimeException('The controller option must be provided.'); } list($bundle, $controller) = $this->parseShortcutNotation($input->getOption('controller')); if (is_string($bundle)) { $bundle = Validators::validateBundleName($bundle); try { $bundle = $this->getContainer()->get('kernel')->getBundle($bundle); } catch (\Exception $e) { $output->writeln(sprintf('<bg=red>Bundle "%s" does not exists.</>', $bundle)); } } $dialog->writeSection($output, 'Controller generation'); $generator = $this->getGenerator($bundle); $generator->generate($bundle, $controller, $input->getOption('route-format'), $input->getOption('template-format'), $this->parseActions($input->getOption('actions'))); $output->writeln('Generating the bundle code: <info>OK</info>'); $dialog->writeGeneratorSummary($output, array()); } public function interact(InputInterface $input, OutputInterface $output) { $dialog = $this->getDialogHelper(); $dialog->writeSection($output, 'Welcome to the Symfony2 controller generator'); // namespace $output->writeln(array( '', 'Every page, and even sections of a page, are rendered by a <comment>controller</comment>.', 'This command helps you generate them easily.', '', 'First, you need to give the controller name you want to generate.', 'You must use the shortcut notation like <comment>AcmeBlogBundle:Post</comment>', '', )); while (true) { $controller = $dialog->askAndValidate($output, $dialog->getQuestion('Controller name', $input->getOption('controller')), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateControllerName'), false, $input->getOption('controller')); list($bundle, $controller) = $this->parseShortcutNotation($controller); try { $b = $this->getContainer()->get('kernel')->getBundle($bundle); if (!file_exists($b->getPath().'/Controller/'.$controller.'Controller.php')) { break; } $output->writeln(sprintf('<bg=red>Controller "%s:%s" already exists.</>', $bundle, $controller)); } catch (\Exception $e) { $output->writeln(sprintf('<bg=red>Bundle "%s" does not exists.</>', $bundle)); } } $input->setOption('controller', $bundle.':'.$controller); // routing format $defaultFormat = (null !== $input->getOption('route-format') ? $input->getOption('route-format') : 'annotation'); $output->writeln(array( '', 'Determine the format to use for the routing.', '', )); $routeFormat = $dialog->askAndValidate($output, $dialog->getQuestion('Routing format (php, xml, yml, annotation)', $defaultFormat), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateFormat'), false, $defaultFormat); $input->setOption('route-format', $routeFormat); // templating format $validateTemplateFormat = function($format) { if (!in_array($format, array('twig', 'php'))) { throw new \InvalidArgumentException(sprintf('The template format must be twig or php, "%s" given', $format)); } return $format; }; $defaultFormat = (null !== $input->getOption('template-format') ? $input->getOption('template-format') : 'twig'); $output->writeln(array( '', 'Determine the format to use for templating.', '', )); $templateFormat = $dialog->askAndValidate($output, $dialog->getQuestion('Template format (twig, php)', $defaultFormat), $validateTemplateFormat, false, $defaultFormat); $input->setOption('template-format', $templateFormat); // actions $input->setOption('actions', $this->addActions($input, $output, $dialog)); // summary $output->writeln(array( '', $this->getHelper('formatter')->formatBlock('Summary before generation', 'bg=blue;fg-white', true), '', sprintf('You are going to generate a "<info>%s:%s</info>" controller', $bundle, $controller), sprintf('using the "<info>%s</info>" format for the routing and the "<info>%s</info>" format', $routeFormat, $templateFormat), 'for templating', )); } public function addActions(InputInterface $input, OutputInterface $output, DialogHelper $dialog) { $output->writeln(array( '', 'Instead of starting with a blank controller, you can add some actions now. An action', 'is a PHP function or method that executes, for example, when a given route is matched.', 'Actions should be suffixed by <comment>Action</comment>.', '', )); $templateNameValidator = function($name) { if ('default' == $name) { return $name; } if (2 != substr_count($name, ':')) { throw new \InvalidArgumentException(sprintf('Template name "%s" does not have 2 colons', $name)); } return $name; }; $actions = $this->parseActions($input->getOption('actions')); while (true) { // name $output->writeln(''); $actionName = $dialog->askAndValidate($output, $dialog->getQuestion('New action name (press <return> to stop adding actions)', null), function ($name) use ($actions) { if (null == $name) { return $name; } if (isset($actions[$name])) { throw new \InvalidArgumentException(sprintf('Action "%s" is already defined', $name)); } if ('Action' != substr($name, -6)) { throw new \InvalidArgumentException(sprintf('Name "%s" is not suffixed by Action', $name)); } return $name; }); if (!$actionName) { break; } // route $route = $dialog->ask($output, $dialog->getQuestion('Action route', '/'.substr($actionName, 0, -6)), '/'.substr($actionName, 0, -6)); $placeholders = $this->getPlaceholdersFromRoute($route); // template $defaultTemplate = $input->getOption('controller').':'.substr($actionName, 0, -6).'.html.'.$input->getOption('template-format'); $template = $dialog->askAndValidate($output, $dialog->getQuestion('Templatename (optional)', $defaultTemplate), $templateNameValidator, false, 'default'); // adding action $actions[$actionName] = array( 'name' => $actionName, 'route' => $route, 'placeholders' => $placeholders, 'template' => $template, ); } return $actions; } public function parseActions($actions) { if (is_array($actions)) { return $actions; } $newActions = array(); foreach (explode(' ', $actions) as $action) { $data = explode(':', $action); // name if (!isset($data[0])) { throw new \InvalidArgumentException('An action must have a name'); } $name = array_shift($data); // route $route = (isset($data[0]) && '' != $data[0]) ? array_shift($data) : '/'.substr($name, 0, -6); if ($route) { $placeholders = $this->getPlaceholdersFromRoute($route); } else { $placeholders = array(); } // template $template = (0 < count($data) && '' != $data[0]) ? implode(':', $data) : 'default'; $newActions[$name] = array( 'name' => $name, 'route' => $route, 'placeholders' => $placeholders, 'template' => $template, ); } return $newActions; } public function getPlaceholdersFromRoute($route) { preg_match_all('/{(.*?)}/', $route, $placeholders); $placeholders = $placeholders[1]; return $placeholders; } public function parseShortcutNotation($shortcut) { $entity = str_replace('/', '\\', $shortcut); if (false === $pos = strpos($entity, ':')) { throw new \InvalidArgumentException(sprintf('The controller name must contain a : ("%s" given, expecting something like AcmeBlogBundle:Post)', $entity)); } return array(substr($entity, 0, $pos), substr($entity, $pos + 1)); } protected function createGenerator() { return new ControllerGenerator($this->getContainer()->get('filesystem')); } } |