diff --git a/framework/core/src/Console/ConsoleServiceProvider.php b/framework/core/src/Console/ConsoleServiceProvider.php new file mode 100644 index 000000000..674927538 --- /dev/null +++ b/framework/core/src/Console/ConsoleServiceProvider.php @@ -0,0 +1,34 @@ +app->singleton('flarum.console.commands', function () { + return [ + CacheClearCommand::class, + GenerateMigrationCommand::class, + MigrateCommand::class, + ResetCommand::class, + ]; + }); + } +} diff --git a/framework/core/src/Console/Event/Configuring.php b/framework/core/src/Console/Event/Configuring.php index eaeea3358..0e4b1dc06 100644 --- a/framework/core/src/Console/Event/Configuring.php +++ b/framework/core/src/Console/Event/Configuring.php @@ -14,9 +14,7 @@ use Illuminate\Console\Command; use Symfony\Component\Console\Application as ConsoleApplication; /** - * Configure the console application. - * - * This event is fired after the core commands are added to the application. + * @deprecated */ class Configuring { diff --git a/framework/core/src/Console/Server.php b/framework/core/src/Console/Server.php index 832f5a4e0..86257ca52 100644 --- a/framework/core/src/Console/Server.php +++ b/framework/core/src/Console/Server.php @@ -39,11 +39,14 @@ class Server $console->add($command); } - $this->extend($console); + $this->extend($console); // deprecated exit($console->run()); } + /** + * @deprecated + */ private function extend(ConsoleApplication $console) { $app = Application::getInstance(); diff --git a/framework/core/src/Extend/Console.php b/framework/core/src/Extend/Console.php new file mode 100644 index 000000000..8fef2b635 --- /dev/null +++ b/framework/core/src/Extend/Console.php @@ -0,0 +1,37 @@ +addCommands[] = $command; + + return $this; + } + + public function extend(Container $container, Extension $extension = null) + { + $container->extend('flarum.console.commands', function ($existingCommands) { + return array_merge($existingCommands, $this->addCommands); + }); + } +} diff --git a/framework/core/src/Foundation/InstalledApp.php b/framework/core/src/Foundation/InstalledApp.php index f7c4e959d..9cf4f0265 100644 --- a/framework/core/src/Foundation/InstalledApp.php +++ b/framework/core/src/Foundation/InstalledApp.php @@ -9,13 +9,10 @@ namespace Flarum\Foundation; -use Flarum\Database\Console\GenerateMigrationCommand; -use Flarum\Database\Console\MigrateCommand; -use Flarum\Database\Console\ResetCommand; -use Flarum\Foundation\Console\CacheClearCommand; use Flarum\Foundation\Console\InfoCommand; use Flarum\Http\Middleware\DispatchRoute; use Flarum\Settings\SettingsRepositoryInterface; +use Illuminate\Console\Command; use Illuminate\Contracts\Container\Container; use Laminas\Stratigility\Middleware\OriginalMessages; use Laminas\Stratigility\MiddlewarePipe; @@ -115,12 +112,21 @@ class InstalledApp implements AppInterface */ public function getConsoleCommands() { - return [ - $this->container->make(GenerateMigrationCommand::class), - $this->container->make(InfoCommand::class, ['config' => $this->config]), - $this->container->make(MigrateCommand::class), - $this->container->make(ResetCommand::class), - $this->container->make(CacheClearCommand::class), - ]; + $commands = []; + + // The info command is a special case, as it requires a config parameter that's only available here. + $commands[] = $this->container->make(InfoCommand::class, ['config' => $this->config]); + + foreach ($this->container->make('flarum.console.commands') as $command) { + $newCommand = $this->container->make($command); + + if ($newCommand instanceof Command) { + $newCommand->setLaravel($this->container); + } + + $commands[] = $newCommand; + } + + return $commands; } } diff --git a/framework/core/src/Foundation/InstalledSite.php b/framework/core/src/Foundation/InstalledSite.php index ae22c72f2..ecce78c4f 100644 --- a/framework/core/src/Foundation/InstalledSite.php +++ b/framework/core/src/Foundation/InstalledSite.php @@ -12,6 +12,7 @@ namespace Flarum\Foundation; use Flarum\Admin\AdminServiceProvider; use Flarum\Api\ApiServiceProvider; use Flarum\Bus\BusServiceProvider; +use Flarum\Console\ConsoleServiceProvider; use Flarum\Database\DatabaseServiceProvider; use Flarum\Database\MigrationServiceProvider; use Flarum\Discussion\DiscussionServiceProvider; @@ -113,6 +114,7 @@ class InstalledSite implements SiteInterface $laravel->register(AdminServiceProvider::class); $laravel->register(ApiServiceProvider::class); $laravel->register(BusServiceProvider::class); + $laravel->register(ConsoleServiceProvider::class); $laravel->register(DatabaseServiceProvider::class); $laravel->register(DiscussionServiceProvider::class); $laravel->register(ExtensionServiceProvider::class); diff --git a/framework/core/tests/integration/ConsoleTestCase.php b/framework/core/tests/integration/ConsoleTestCase.php new file mode 100644 index 000000000..80d907a2e --- /dev/null +++ b/framework/core/tests/integration/ConsoleTestCase.php @@ -0,0 +1,44 @@ +console)) { + $this->console = new ConsoleApplication('Flarum', Application::VERSION); + $this->console->setAutoExit(false); + + foreach ($this->app()->getConsoleCommands() as $command) { + $this->console->add($command); + } + } + + return $this->console; + } + + protected function runCommand(array $inputArray) + { + $input = new ArrayInput($inputArray); + $output = new BufferedOutput(); + + $this->console()->run($input, $output); + + return trim($output->fetch()); + } +} diff --git a/framework/core/tests/integration/extenders/ConsoleTest.php b/framework/core/tests/integration/extenders/ConsoleTest.php new file mode 100644 index 000000000..8a941b17a --- /dev/null +++ b/framework/core/tests/integration/extenders/ConsoleTest.php @@ -0,0 +1,65 @@ + 'customTestCommand' + ]; + + $this->assertEquals('Command "customTestCommand" is not defined.', $this->runCommand($input)); + } + + /** + * @test + */ + public function custom_command_exists_when_added() + { + $this->extend( + (new Extend\Console()) + ->command(CustomCommand::class) + ); + + $input = [ + 'command' => 'customTestCommand' + ]; + + $this->assertEquals('Custom Command.', $this->runCommand($input)); + } +} + +class CustomCommand extends AbstractCommand +{ + /** + * {@inheritdoc} + */ + protected function configure() + { + $this->setName('customTestCommand'); + } + + /** + * {@inheritdoc} + */ + protected function fire() + { + $this->info('Custom Command.'); + } +}