addArgument('name', InputArgument::REQUIRED, 'Controller name'); $this->addOption('plugin', 'p', InputOption::VALUE_REQUIRED, 'Plugin name under plugin/. e.g. admin'); $this->addOption('path', 'P', InputOption::VALUE_REQUIRED, 'Target directory (relative to base path). e.g. plugin/admin/app/controller'); $this->addOption('force', 'f', InputOption::VALUE_NONE, 'Override existing file without confirmation.'); $this->setHelp($this->buildHelpText()); $this->addUsage('User'); $this->addUsage('User -p admin'); $this->addUsage('User -P plugin/admin/app/controller'); $this->addUsage('admin/User -f'); } /** * @param InputInterface $input * @param OutputInterface $output * @return int */ protected function execute(InputInterface $input, OutputInterface $output): int { try { $name = Util::nameToClass((string)$input->getArgument('name')); $plugin = $this->normalizeOptionValue($input->getOption('plugin')); $path = $this->normalizeOptionValue($input->getOption('path')); $force = (bool)$input->getOption('force'); if ($plugin && (str_contains($plugin, '/') || str_contains($plugin, '\\'))) { $output->writeln($this->msg('invalid_plugin', ['{plugin}' => $plugin])); return Command::FAILURE; } if ($plugin && !$this->assertPluginExists($plugin, $output)) { return Command::FAILURE; } // When "-p/--plugin" is provided, controller suffix should come from the plugin config, // not from the main project config. if ($plugin) { $suffix = (string)config("plugin.$plugin.app.controller_suffix", 'Controller'); } else { $suffix = (string)config('app.controller_suffix', 'Controller'); } $name = str_replace('\\', '/', $name); $name = $this->applySuffixToLastSegment($name, $suffix); // When path is not provided: in interactive mode prompt for path (same UX as make:crud). if (!$path && $input->isInteractive()) { $pathDefault = Util::getDefaultAppRelativePath('controller', $plugin ?: null); $path = $this->promptForControllerPath($input, $output, $pathDefault); } if ($plugin || $path) { $resolved = $this->resolveTargetByPluginOrPath( $name, $plugin, $path, $output, fn(string $p) => Util::getDefaultAppRelativePath('controller', $p), fn(string $key, array $replace = []) => $this->msg($key, $replace) ); if ($resolved === null) { return Command::FAILURE; } [$class, $namespace, $file] = $resolved; if (!$this->isControllerNamespace($namespace)) { $output->writeln(Util::selectByLocale(Messages::getPathMissingControllerMessage())); return Command::FAILURE; } } else { [$class, $namespace, $file] = $this->resolveAppControllerTarget($name); } $output->writeln($this->msg('make_controller', ['{name}' => $class])); if (is_file($file) && !$force) { $relative = $this->toRelativePath($file); $prompt = $this->msg('override_prompt', ['{path}' => $relative]); $question = new ConfirmationQuestion($prompt, true); $yes = (bool)$this->askOrAbort($input, $output, $question); if (!$yes) { return Command::SUCCESS; } } $this->createController($class, $namespace, $file); $output->writeln($this->msg('created', ['{path}' => $this->toRelativePath($file)])); return self::SUCCESS; } catch (\Throwable $e) { throw $e; } } /** * @param $name * @param $namespace * @param $file * @return void */ protected function createController($name, $namespace, $file) { $path = pathinfo($file, PATHINFO_DIRNAME); if (!is_dir($path)) { mkdir($path, 0777, true); } $controller_content = <<normalizeRelativePath($defaultPath); $label = Util::selectLocaleMessages(Messages::getTypeLabels())['controller'] ?? 'Controller'; $promptText = Util::selectLocaleMessages(Messages::getMakeCrudMessages())['enter_path_prompt'] ?? 'Enter {label} path (Enter for default: {default}): '; $promptText = strtr($promptText, ['{label}' => $label, '{default}' => $defaultPath]); $promptText = '' . trim($promptText) . "\n"; $question = new Question($promptText, $defaultPath); $path = $this->askOrAbort($input, $output, $question); $path = is_string($path) ? $path : $defaultPath; return $this->normalizeRelativePath($path ?: $defaultPath); } /** * Command help text (multilingual). * * @return string */ protected function buildHelpText(): string { return Util::selectByLocale(Messages::getMakeControllerHelpText()); } /** * Hardcoded CLI messages (bilingual) without translation module. * * @param string $key * @param array $replace * @return string */ protected function msg(string $key, array $replace = []): string { return strtr(Util::selectLocaleMessages(Messages::getMakeControllerMessages())[$key] ?? $key, $replace); } }