output = $output; switch (true) { case $object instanceof Application: $this->describeJoomlaApplication($object, $options); break; case $object instanceof AbstractCommand: $this->describeConsoleCommand($object, $options); break; default: parent::describe($output, $object, $options); } } /** * Formats command aliases to show them in the command description. * * @param AbstractCommand $command The command to process * * @return string * * @since 2.0.0 */ private function getCommandAliasesText(AbstractCommand $command): string { $text = ''; $aliases = $command->getAliases(); if ($aliases) { $text = '[' . implode('|', $aliases) . '] '; } return $text; } /** * Describes a command. * * @param AbstractCommand $command The command being described. * @param array $options Descriptor options. * * @return void * * @since 2.0.0 */ private function describeConsoleCommand(AbstractCommand $command, array $options): void { $command->getSynopsis(true); $command->getSynopsis(false); $command->mergeApplicationDefinition(false); $this->writeText('Usage:', $options); foreach (array_merge([$command->getSynopsis(true)], $command->getAliases()) as $usage) { $this->writeText("\n"); $this->writeText(' ' . $usage, $options); } $this->writeText("\n"); $definition = $command->getDefinition(); if ($definition->getOptions() || $definition->getArguments()) { $this->writeText("\n"); $this->describeInputDefinition($definition, $options); $this->writeText("\n"); } if ($help = $command->getProcessedHelp()) { $this->writeText("\n"); $this->writeText('Help:', $options); $this->writeText("\n"); $this->writeText(' ' . str_replace("\n", "\n ", $help), $options); $this->writeText("\n"); } } /** * Describes an application. * * @param Application $app The application being described. * @param array $options Descriptor options. * * @return void * * @since 2.0.0 */ private function describeJoomlaApplication(Application $app, array $options): void { $describedNamespace = $options['namespace'] ?? ''; $description = new ApplicationDescription($app, $describedNamespace); $version = $app->getLongVersion(); if ($version !== '') { $this->writeText("$version\n\n", $options); } $this->writeText("Usage:\n"); $this->writeText(" command [options] [arguments]\n\n"); $this->describeInputDefinition(new InputDefinition($app->getDefinition()->getOptions()), $options); $this->writeText("\n"); $this->writeText("\n"); $commands = $description->getCommands(); $namespaces = $description->getNamespaces(); if ($describedNamespace && $namespaces) { // Ensure all aliased commands are included when describing a specific namespace $describedNamespaceInfo = reset($namespaces); foreach ($describedNamespaceInfo['commands'] as $name) { $commands[$name] = $description->getCommand($name); } } $width = $this->getColumnWidth( \call_user_func_array( 'array_merge', array_map( function ($namespace) use ($commands) { return array_intersect($namespace['commands'], array_keys($commands)); }, array_values($namespaces) ) ) ); if ($describedNamespace) { $this->writeText(sprintf('Available commands for the "%s" namespace:', $describedNamespace), $options); } else { $this->writeText('Available commands:', $options); } foreach ($namespaces as $namespace) { $namespace['commands'] = array_filter( $namespace['commands'], function ($name) use ($commands) { return isset($commands[$name]); } ); if (!$namespace['commands']) { continue; } if (!$describedNamespace && $namespace['id'] !== ApplicationDescription::GLOBAL_NAMESPACE) { $this->writeText("\n"); $this->writeText(' ' . $namespace['id'] . '', $options); } foreach ($namespace['commands'] as $name) { $this->writeText("\n"); $spacingWidth = $width - StringHelper::strlen($name); $command = $commands[$name]; $commandAliases = $name === $command->getName() ? $this->getCommandAliasesText($command) : ''; $this->writeText( sprintf( ' %s%s%s', $name, str_repeat(' ', $spacingWidth), $commandAliases . $command->getDescription() ), $options ); } } $this->writeText("\n"); } /** * Calculate the column width for a group of commands. * * @param AbstractCommand[]|string[] $commands The commands to use for processing a width. * * @return integer * * @since 2.0.0 */ private function getColumnWidth(array $commands): int { $widths = []; foreach ($commands as $command) { if ($command instanceof AbstractCommand) { $widths[] = StringHelper::strlen($command->getName()); foreach ($command->getAliases() as $alias) { $widths[] = StringHelper::strlen($alias); } } else { $widths[] = StringHelper::strlen($command); } } return $widths ? max($widths) + 2 : 0; } /** * Writes text to the output. * * @param string $content The message. * @param array $options The options to use for formatting the output. * * @return void * * @since 2.0.0 */ private function writeText($content, array $options = []): void { $this->write( isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content, isset($options['raw_output']) ? !$options['raw_output'] : true ); } }