|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace Illuminate\Foundation\Console; |
| 4 | + |
| 5 | +use Closure; |
| 6 | +use Illuminate\Console\Command; |
| 7 | +use Illuminate\Contracts\Broadcasting\Broadcaster; |
| 8 | +use Illuminate\Support\Collection; |
| 9 | +use Symfony\Component\Console\Attribute\AsCommand; |
| 10 | +use Symfony\Component\Console\Terminal; |
| 11 | + |
| 12 | +#[AsCommand(name: 'channel:list')] |
| 13 | +class ChannelListCommand extends Command |
| 14 | +{ |
| 15 | + /** |
| 16 | + * The console command name. |
| 17 | + * |
| 18 | + * @var string |
| 19 | + */ |
| 20 | + protected $name = 'channel:list'; |
| 21 | + |
| 22 | + /** |
| 23 | + * The console command description. |
| 24 | + * |
| 25 | + * @var string |
| 26 | + */ |
| 27 | + protected $description = 'List all registered private broadcast channels'; |
| 28 | + |
| 29 | + /** |
| 30 | + * The terminal width resolver callback. |
| 31 | + * |
| 32 | + * @var \Closure|null |
| 33 | + */ |
| 34 | + protected static $terminalWidthResolver; |
| 35 | + |
| 36 | + /** |
| 37 | + * Execute the console command. |
| 38 | + * |
| 39 | + * @param \Illuminate\Contracts\Broadcasting\Broadcaster |
| 40 | + * @return void |
| 41 | + */ |
| 42 | + public function handle(Broadcaster $broadcaster) |
| 43 | + { |
| 44 | + $channels = $broadcaster->getChannels(); |
| 45 | + |
| 46 | + if (! $this->laravel->providerIsLoaded('App\Providers\BroadcastServiceProvider') && |
| 47 | + file_exists($this->laravel->path('Providers/BroadcastServiceProvider.php'))) { |
| 48 | + $this->components->warn('The [App\Providers\BroadcastServiceProvider] has not been loaded. Your private channels may not be loaded.'); |
| 49 | + } |
| 50 | + |
| 51 | + if (! $channels->count()) { |
| 52 | + return $this->components->error("Your application doesn't have any private broadcasting channels."); |
| 53 | + } |
| 54 | + |
| 55 | + $this->displayChannels($channels); |
| 56 | + } |
| 57 | + |
| 58 | + /** |
| 59 | + * Display the channel information on the console. |
| 60 | + * |
| 61 | + * @param Collection $channels |
| 62 | + * @return void |
| 63 | + */ |
| 64 | + protected function displayChannels($channels) |
| 65 | + { |
| 66 | + $this->output->writeln($this->forCli($channels)); |
| 67 | + } |
| 68 | + |
| 69 | + /** |
| 70 | + * Convert the given channels to regular CLI output. |
| 71 | + * |
| 72 | + * @param \Illuminate\Support\Collection $channels |
| 73 | + * @return array |
| 74 | + */ |
| 75 | + protected function forCli($channels) |
| 76 | + { |
| 77 | + $maxChannelName = $channels->keys()->max(function ($channelName) { |
| 78 | + return mb_strlen($channelName); |
| 79 | + }); |
| 80 | + |
| 81 | + $terminalWidth = $this->getTerminalWidth(); |
| 82 | + |
| 83 | + $channelCount = $this->determineChannelCountOutput($channels, $terminalWidth); |
| 84 | + |
| 85 | + return $channels->map(function ($channel, $channelName) use ($maxChannelName, $terminalWidth) { |
| 86 | + $resolver = $channel instanceof Closure ? 'Closure' : $channel; |
| 87 | + |
| 88 | + $spaces = str_repeat(' ', max($maxChannelName + 6 - mb_strlen($channelName), 0)); |
| 89 | + |
| 90 | + $dots = str_repeat('.', max( |
| 91 | + $terminalWidth - mb_strlen($channelName.$spaces.$resolver) - 6, 0 |
| 92 | + )); |
| 93 | + |
| 94 | + $dots = empty($dots) ? $dots : " $dots"; |
| 95 | + |
| 96 | + return sprintf( |
| 97 | + ' <fg=blue;options=bold>%s</> %s<fg=white>%s</><fg=#6C7280>%s</>', |
| 98 | + $channelName, |
| 99 | + $spaces, |
| 100 | + $resolver, |
| 101 | + $dots, |
| 102 | + ); |
| 103 | + }) |
| 104 | + ->filter() |
| 105 | + ->sort() |
| 106 | + ->prepend('') |
| 107 | + ->push('')->push($channelCount)->push('') |
| 108 | + ->toArray(); |
| 109 | + } |
| 110 | + |
| 111 | + /** |
| 112 | + * Determine and return the output for displaying the number of registered chanels in the CLI output. |
| 113 | + * |
| 114 | + * @param \Illuminate\Support\Collection $channels |
| 115 | + * @param int $terminalWidth |
| 116 | + * @return string |
| 117 | + */ |
| 118 | + protected function determineChannelCountOutput($channels, $terminalWidth) |
| 119 | + { |
| 120 | + $channelCountText = 'Showing ['.$channels->count().'] private channels'; |
| 121 | + |
| 122 | + $offset = $terminalWidth - mb_strlen($channelCountText) - 2; |
| 123 | + |
| 124 | + $spaces = str_repeat(' ', $offset); |
| 125 | + |
| 126 | + return $spaces.'<fg=blue;options=bold>Showing ['.$channels->count().'] private channels</>'; |
| 127 | + } |
| 128 | + |
| 129 | + /** |
| 130 | + * Get the terminal width. |
| 131 | + * |
| 132 | + * @return int |
| 133 | + */ |
| 134 | + public static function getTerminalWidth() |
| 135 | + { |
| 136 | + return is_null(static::$terminalWidthResolver) |
| 137 | + ? (new Terminal)->getWidth() |
| 138 | + : call_user_func(static::$terminalWidthResolver); |
| 139 | + } |
| 140 | + |
| 141 | + /** |
| 142 | + * Set a callback that should be used when resolving the terminal width. |
| 143 | + * |
| 144 | + * @param \Closure|null $resolver |
| 145 | + * @return void |
| 146 | + */ |
| 147 | + public static function resolveTerminalWidthUsing($resolver) |
| 148 | + { |
| 149 | + static::$terminalWidthResolver = $resolver; |
| 150 | + } |
| 151 | +} |
0 commit comments