/src/Symfony/Component/Messenger/Command/DebugCommand.php

https://github.com/marphi/symfony · PHP · 148 lines · 102 code · 26 blank · 20 comment · 10 complexity · c520e713707abc37cc9525a68534d817 MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Messenger\Command;
  11. use Symfony\Component\Console\Attribute\AsCommand;
  12. use Symfony\Component\Console\Command\Command;
  13. use Symfony\Component\Console\Completion\CompletionInput;
  14. use Symfony\Component\Console\Completion\CompletionSuggestions;
  15. use Symfony\Component\Console\Exception\RuntimeException;
  16. use Symfony\Component\Console\Input\InputArgument;
  17. use Symfony\Component\Console\Input\InputInterface;
  18. use Symfony\Component\Console\Output\OutputInterface;
  19. use Symfony\Component\Console\Style\SymfonyStyle;
  20. /**
  21. * A console command to debug Messenger information.
  22. *
  23. * @author Roland Franssen <franssen.roland@gmail.com>
  24. */
  25. #[AsCommand(name: 'debug:messenger', description: 'List messages you can dispatch using the message buses')]
  26. class DebugCommand extends Command
  27. {
  28. private array $mapping;
  29. public function __construct(array $mapping)
  30. {
  31. $this->mapping = $mapping;
  32. parent::__construct();
  33. }
  34. /**
  35. * {@inheritdoc}
  36. */
  37. protected function configure()
  38. {
  39. $this
  40. ->addArgument('bus', InputArgument::OPTIONAL, sprintf('The bus id (one of "%s")', implode('", "', array_keys($this->mapping))))
  41. ->setHelp(<<<'EOF'
  42. The <info>%command.name%</info> command displays all messages that can be
  43. dispatched using the message buses:
  44. <info>php %command.full_name%</info>
  45. Or for a specific bus only:
  46. <info>php %command.full_name% command_bus</info>
  47. EOF
  48. )
  49. ;
  50. }
  51. /**
  52. * {@inheritdoc}
  53. */
  54. protected function execute(InputInterface $input, OutputInterface $output): int
  55. {
  56. $io = new SymfonyStyle($input, $output);
  57. $io->title('Messenger');
  58. $mapping = $this->mapping;
  59. if ($bus = $input->getArgument('bus')) {
  60. if (!isset($mapping[$bus])) {
  61. throw new RuntimeException(sprintf('Bus "%s" does not exist. Known buses are "%s".', $bus, implode('", "', array_keys($this->mapping))));
  62. }
  63. $mapping = [$bus => $mapping[$bus]];
  64. }
  65. foreach ($mapping as $bus => $handlersByMessage) {
  66. $io->section($bus);
  67. $tableRows = [];
  68. foreach ($handlersByMessage as $message => $handlers) {
  69. if ($description = self::getClassDescription($message)) {
  70. $tableRows[] = [sprintf('<comment>%s</>', $description)];
  71. }
  72. $tableRows[] = [sprintf('<fg=cyan>%s</fg=cyan>', $message)];
  73. foreach ($handlers as $handler) {
  74. $tableRows[] = [
  75. sprintf(' handled by <info>%s</>', $handler[0]).$this->formatConditions($handler[1]),
  76. ];
  77. if ($handlerDescription = self::getClassDescription($handler[0])) {
  78. $tableRows[] = [sprintf(' <comment>%s</>', $handlerDescription)];
  79. }
  80. }
  81. $tableRows[] = [''];
  82. }
  83. if ($tableRows) {
  84. $io->text('The following messages can be dispatched:');
  85. $io->newLine();
  86. $io->table([], $tableRows);
  87. } else {
  88. $io->warning(sprintf('No handled message found in bus "%s".', $bus));
  89. }
  90. }
  91. return 0;
  92. }
  93. private function formatConditions(array $options): string
  94. {
  95. if (!$options) {
  96. return '';
  97. }
  98. $optionsMapping = [];
  99. foreach ($options as $key => $value) {
  100. $optionsMapping[] = $key.'='.$value;
  101. }
  102. return ' (when '.implode(', ', $optionsMapping).')';
  103. }
  104. private static function getClassDescription(string $class): string
  105. {
  106. try {
  107. $r = new \ReflectionClass($class);
  108. if ($docComment = $r->getDocComment()) {
  109. $docComment = preg_split('#\n\s*\*\s*[\n@]#', substr($docComment, 3, -2), 2)[0];
  110. return trim(preg_replace('#\s*\n\s*\*\s*#', ' ', $docComment));
  111. }
  112. } catch (\ReflectionException $e) {
  113. }
  114. return '';
  115. }
  116. public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
  117. {
  118. if ($input->mustSuggestArgumentValuesFor('bus')) {
  119. $suggestions->suggestValues(array_keys($this->mapping));
  120. }
  121. }
  122. }