Skip to content

Commit e90a1bf

Browse files
authored
Allow class based commands to be registered with the facade (#640)
1 parent b451011 commit e90a1bf

File tree

7 files changed

+58
-16
lines changed

7 files changed

+58
-16
lines changed

phpstan.neon

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ parameters:
1818
identifier: require.fileNotFound
1919
-
2020
identifier: requireOnce.fileNotFound
21-
-
22-
identifier: unset.possiblyHookedProperty
2321
-
2422
identifier: function.alreadyNarrowedType
2523
paths:

src/mantle/console/class-application.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public function resolve( Symfony_Command|Command|string $command ): static {
151151
/**
152152
* Resolve an array of commands through the console application.
153153
*
154-
* @param array|string|Symfony_Command|Command $commands
154+
* @param array|class-string<Command|Symfony_Command>|Symfony_Command|Command $commands
155155
*/
156156
public function resolve_commands( $commands ): static {
157157
$commands = Arr::wrap( $commands );

src/mantle/contracts/console/interface-kernel.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace Mantle\Contracts\Console;
99

10+
use Closure;
11+
use Mantle\Console\Command;
1012
use Symfony\Component\Console\Tester\CommandTester;
1113

1214
/**
@@ -45,6 +47,21 @@ public function test( string $command, array $parameters = [] ): CommandTester;
4547
*/
4648
public function register_commands();
4749

50+
/**
51+
* Register a new command with the console application.
52+
*
53+
* @param Command|class-string<Command> $command Command instance or class name.
54+
*/
55+
public function register( Command|string $command );
56+
57+
/**
58+
* Register a new Closure based command with a signature.
59+
*
60+
* @param string $signature Command signature.
61+
* @param Closure $callback Command callback.
62+
*/
63+
public function command( string $signature, Closure $callback );
64+
4865
/**
4966
* Log to the console.
5067
*

src/mantle/facade/class-console.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* @method static int call(string $command, array $parameters = [], mixed $output_buffer = null)
1919
* @method static \Symfony\Component\Console\Tester\CommandTester test(string $command, array $parameters = [])
2020
* @method static \Mantle\Console\Closure_Command command(string $signature, Closure $callback)
21+
* @method static void register(string|\Mantle\Console\Command $command)
2122
* @method static void bootstrap()
2223
* @method static \Mantle\Contracts\Console\Application get_console_application()
2324
* @method static void set_console_application(\Mantle\Contracts\Console\Application $app)

src/mantle/framework/console/class-kernel.php

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,10 @@
3030
class Kernel implements \Mantle\Contracts\Console\Kernel {
3131
use Loads_Classes;
3232

33-
/**
34-
* The application implementation.
35-
*
36-
* @var Application|null
37-
*/
38-
protected $app;
39-
4033
/**
4134
* The bootstrap classes for the application.
4235
*
43-
* @var array
36+
* @var array<class-string>
4437
*/
4538
protected $bootstrappers = [
4639
\Mantle\Framework\Bootstrap\Load_Configuration::class,
@@ -53,7 +46,7 @@ class Kernel implements \Mantle\Contracts\Console\Kernel {
5346
/**
5447
* The commands provided by the application.
5548
*
56-
* @var array
49+
* @var array<class-string<\Mantle\Console\Command>|Command>
5750
*/
5851
protected $commands = [];
5952

@@ -77,9 +70,7 @@ class Kernel implements \Mantle\Contracts\Console\Kernel {
7770
*
7871
* @param Application $app Application instance.
7972
*/
80-
public function __construct( Application $app ) {
81-
$this->app = $app;
82-
73+
public function __construct( protected Application $app ) {
8374
$this->ensure_environment_is_set();
8475
}
8576

@@ -127,6 +118,23 @@ public function test( string $command, array $parameters = [] ): CommandTester {
127118
return $this->get_console_application()->test( $command, $parameters );
128119
}
129120

121+
/**
122+
* Register a new command with the console application.
123+
*
124+
* @throws \InvalidArgumentException Thrown if the command is not a valid command.
125+
*
126+
* @param Command|class-string<Command> $command Command instance or class name.
127+
*/
128+
public function register( Command|string $command ): void {
129+
if ( ! class_exists( $command ) || ! is_subclass_of( $command, Command::class ) ) { // @phpstan-ignore-line function.alreadyNarrowedType
130+
throw new \InvalidArgumentException( "Command [{$command}] is not a valid command." );
131+
}
132+
133+
Console_Application::starting(
134+
fn ( Console_Application $app ) => $app->resolve( $command )
135+
);
136+
}
137+
130138
/**
131139
* Register a new Closure based command with a signature.
132140
*

src/mantle/framework/resources/application-structure/console/class-kernel.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace App\Console;
99

10+
use Mantle\Console\Command;
1011
use Mantle\Facade\Console;
1112
use Mantle\Framework\Console\Kernel as Console_Kernel;
1213

@@ -20,7 +21,7 @@ class Kernel extends Console_Kernel {
2021
/**
2122
* The commands provided by the application.
2223
*
23-
* @var array
24+
* @var array<class-string<Command>|Command>
2425
*/
2526
protected $commands = [
2627
// ...

tests/Testing/Concerns/InteractsWithConsoleTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22
namespace Mantle\Tests\Concerns;
33

4+
use Mantle\Console\Command;
45
use Mantle\Facade\Console;
56
use Mantle\Testing\Framework_Test_Case;
67
use PHPUnit\Framework\Attributes\Group;
@@ -49,6 +50,22 @@ public function test_closure_command_input() {
4950
->assertOk();
5051
}
5152

53+
public function test_class_command(): void {
54+
$command = new class() extends Command {
55+
protected $signature = 'test:class-command';
56+
57+
public function __invoke() {
58+
$this->info( 'Hello World' );
59+
}
60+
};
61+
62+
Console::register( $command::class );
63+
64+
$this->command( 'wp mantle test:class-command' )
65+
->assertOutputContains( 'Hello World' )
66+
->assertOk();
67+
}
68+
5269
public function test_wp_cli_command() {
5370
$this->markTestSkipped( 'WP-CLI commands are not supported yet.' );
5471
}

0 commit comments

Comments
 (0)