Security update for Core, with self-updated composer
[yaffs-website] / vendor / drupal / console / src / Command / Generate / ControllerCommand.php
1 <?php
2
3 /**
4  * @file
5  * Contains Drupal\Console\Command\Generate\ControllerCommand.
6  */
7
8 namespace Drupal\Console\Command\Generate;
9
10 use Symfony\Component\Console\Input\InputInterface;
11 use Symfony\Component\Console\Input\InputOption;
12 use Symfony\Component\Console\Output\OutputInterface;
13 use Drupal\Console\Command\Shared\ServicesTrait;
14 use Drupal\Console\Command\Shared\ConfirmationTrait;
15 use Drupal\Console\Command\Shared\ModuleTrait;
16 use Drupal\Console\Generator\ControllerGenerator;
17 use Drupal\Console\Core\Command\ContainerAwareCommand;
18 use Drupal\Core\Routing\RouteProviderInterface;
19 use Drupal\Console\Core\Utils\StringConverter;
20 use Drupal\Console\Core\Utils\ChainQueue;
21 use Drupal\Console\Core\Command\Shared\InputTrait;
22 use Drupal\Console\Extension\Manager;
23 use Drupal\Console\Utils\Validator;
24
25 class ControllerCommand extends ContainerAwareCommand
26 {
27     use ModuleTrait;
28     use ServicesTrait;
29     use ConfirmationTrait;
30     use InputTrait;
31
32     /**
33      * @var Manager
34      */
35     protected $extensionManager;
36
37     /**
38      * @var ControllerGenerator
39      */
40     protected $generator;
41
42     /**
43      * @var StringConverter
44      */
45     protected $stringConverter;
46
47     /**
48      * @var Validator
49      */
50     protected $validator;
51
52     /**
53      * @var RouteProviderInterface
54      */
55     protected $routeProvider;
56
57     /**
58      * @var ChainQueue
59      */
60     protected $chainQueue;
61
62     /**
63      * ControllerCommand constructor.
64      *
65      * @param Manager                $extensionManager
66      * @param ControllerGenerator    $generator
67      * @param StringConverter        $stringConverter
68      * @param Validator              $validator
69      * @param RouteProviderInterface $routeProvider
70      * @param ChainQueue             $chainQueue
71      */
72     public function __construct(
73         Manager $extensionManager,
74         ControllerGenerator $generator,
75         StringConverter $stringConverter,
76         Validator $validator,
77         RouteProviderInterface $routeProvider,
78         ChainQueue $chainQueue
79     ) {
80         $this->extensionManager = $extensionManager;
81         $this->generator = $generator;
82         $this->stringConverter = $stringConverter;
83         $this->validator = $validator;
84         $this->routeProvider = $routeProvider;
85         $this->chainQueue = $chainQueue;
86         parent::__construct();
87     }
88
89     protected function configure()
90     {
91         $this
92             ->setName('generate:controller')
93             ->setDescription($this->trans('commands.generate.controller.description'))
94             ->setHelp($this->trans('commands.generate.controller.help'))
95             ->addOption(
96                 'module',
97                 null,
98                 InputOption::VALUE_REQUIRED,
99                 $this->trans('commands.common.options.module')
100             )
101             ->addOption(
102                 'class',
103                 null,
104                 InputOption::VALUE_OPTIONAL,
105                 $this->trans('commands.generate.controller.options.class')
106             )
107             ->addOption(
108                 'routes',
109                 null,
110                 InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
111                 $this->trans('commands.generate.controller.options.routes')
112             )
113             ->addOption(
114                 'services',
115                 null,
116                 InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
117                 $this->trans('commands.common.options.services')
118             )
119             ->addOption(
120                 'test',
121                 null,
122                 InputOption::VALUE_NONE,
123                 $this->trans('commands.generate.controller.options.test')
124             )
125             ->setAliases(['gcon']);
126     }
127
128     /**
129      * {@inheritdoc}
130      */
131     protected function execute(InputInterface $input, OutputInterface $output)
132     {
133         // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
134         if (!$this->confirmOperation()) {
135             return 1;
136         }
137
138         $module = $input->getOption('module');
139         $class = $this->validator->validateControllerName($input->getOption('class'));
140         $routes = $input->getOption('routes');
141         $test = $input->getOption('test');
142         $services = $input->getOption('services');
143
144         $routes = $this->inlineValueAsArray($routes);
145         $input->setOption('routes', $routes);
146
147         // @see use Drupal\Console\Command\Shared\ServicesTrait::buildServices
148         $build_services = $this->buildServices($services);
149
150         //$this->generator->setLearning($learning);
151         $this->generator->generate([
152             'module' => $module,
153             'class_name' => $class,
154             'routes' => $routes,
155             'test' => $test,
156             'services' => $build_services
157         ]);
158
159         // Run cache rebuild to see changes in Web UI
160         $this->chainQueue->addCommand('router:rebuild', []);
161
162         return 0;
163     }
164
165     /**
166      * {@inheritdoc}
167      */
168     protected function interact(InputInterface $input, OutputInterface $output)
169     {
170         // --module option
171         $module = $this->getModuleOption();
172
173         // --class option
174         $class = $input->getOption('class');
175         if (!$class) {
176             $class = $this->getIo()->ask(
177                 $this->trans('commands.generate.controller.questions.class'),
178                 'DefaultController',
179                 function ($class) {
180                     return $this->validator->validateControllerName($class);
181                 }
182             );
183             $input->setOption('class', $class);
184         }
185
186         $routes = $input->getOption('routes');
187         if (!$routes) {
188             while (true) {
189                 $title = $this->getIo()->askEmpty(
190                     $this->trans('commands.generate.controller.questions.title'),
191                     '',
192                     function ($title) use ($routes) {
193                         if ($routes && empty(trim($title))) {
194                             return false;
195                         }
196
197                         if (!$routes && empty(trim($title))) {
198                             throw new \InvalidArgumentException(
199                                 $this->trans(
200                                     'commands.generate.controller.messages.title-empty'
201                                 )
202                             );
203                         }
204
205                         if (in_array($title, array_column($routes, 'title'))) {
206                             throw new \InvalidArgumentException(
207                                 sprintf(
208                                     $this->trans(
209                                         'commands.generate.controller.messages.title-already-added'
210                                     ),
211                                     $title
212                                 )
213                             );
214                         }
215
216                         return $title;
217                     }
218                 );
219
220                 if ($title === '') {
221                     break;
222                 }
223
224                 $method = $this->getIo()->ask(
225                     $this->trans('commands.generate.controller.questions.method'),
226                     'hello',
227                     function ($method) use ($routes) {
228                         if (in_array($method, array_column($routes, 'method'))) {
229                             throw new \InvalidArgumentException(
230                                 sprintf(
231                                     $this->trans(
232                                         'commands.generate.controller.messages.method-already-added'
233                                     ),
234                                     $method
235                                 )
236                             );
237                         }
238
239                         return $method;
240                     }
241                 );
242
243                 $path = $this->getIo()->ask(
244                     $this->trans('commands.generate.controller.questions.path'),
245                     sprintf(
246                         '/%s/'.($method!='hello'?$method:'hello/{name}'),
247                         $module
248                     ),
249                     function ($path) use ($routes) {
250                         if (count($this->routeProvider->getRoutesByPattern($path)) > 0
251                             || in_array($path, array_column($routes, 'path'))
252                         ) {
253                             throw new \InvalidArgumentException(
254                                 sprintf(
255                                     $this->trans(
256                                         'commands.generate.controller.messages.path-already-added'
257                                     ),
258                                     $path
259                                 )
260                             );
261                         }
262
263                         return $path;
264                     }
265                 );
266                 $classMachineName = $this->stringConverter->camelCaseToMachineName($class);
267                 $routeName = $module . '.' . $classMachineName . '_' . $method;
268                 if ($this->routeProvider->getRoutesByNames([$routeName])
269                     || in_array($routeName, $routes)
270                 ) {
271                     $routeName .= '_' . rand(0, 100);
272                 }
273
274                 $routes[] = [
275                     'title' => $title,
276                     'name' => $routeName,
277                     'method' => $method,
278                     'path' => $path
279                 ];
280             }
281             $input->setOption('routes', $routes);
282         }
283
284         // --test option
285         $test = $input->getOption('test');
286         if (!$test) {
287             $test = $this->getIo()->confirm(
288                 $this->trans('commands.generate.controller.questions.test'),
289                 true
290             );
291
292             $input->setOption('test', $test);
293         }
294
295         // --services option
296         // @see use Drupal\Console\Command\Shared\ServicesTrait::servicesQuestion
297         $services = $this->servicesQuestion();
298         $input->setOption('services', $services);
299     }
300 }