DebugCommand.php 4.1 KB

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