You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Nextcloud apps can register custom `occ <https://docs.nextcloud.com/server/latest/admin_manual/occ_command.html>`_ commands that administrators can run from the command line. Commands extend ``OC\Core\Command\Base``, which wraps
8
-
`Symfony Console <https://symfony.com/doc/current/console.html>`_ and adds bash completion support, so the full Symfony
9
-
Console API is available.
7
+
Nextcloud apps can register custom `occ <https://docs.nextcloud.com/server/latest/admin_manual/occ_command.html>`_
8
+
commands that administrators can run from the command line. Commands are plain PHP classes annotated with the
9
+
``#[AsCommand]`` attribute from ``OCP\Console``. Nextcloud wires the attribute on top of
10
+
`Symfony Console <https://symfony.com/doc/current/console.html>`_ for you, so you get argument parsing, bash
11
+
completion, and formatted output without extending a base class.
10
12
11
13
12
14
Registering a command
@@ -31,11 +33,8 @@ injection container, so constructor injection works automatically.
31
33
Creating a command class
32
34
------------------------
33
35
34
-
Place command classes in ``lib/Command/``. Each class must extend
35
-
``OC\Core\Command\Base`` and implement two methods:
36
-
37
-
- ``configure()`` — declare the name, description, arguments, and options.
38
-
- ``execute()`` — run the command logic and return an exit code.
36
+
Place command classes in ``lib/Command/``. Add a ``#[AsCommand]`` attribute to the class and implement a single
37
+
``__invoke()`` method that runs the command:
39
38
40
39
.. code-block:: php
41
40
:caption: lib/Command/Greet.php
@@ -46,60 +45,103 @@ Place command classes in ``lib/Command/``. Each class must extend
46
45
47
46
namespace OCA\MyApp\Command;
48
47
49
-
use OC\Core\Command\Base;
48
+
use OCP\Console\Attribute\Argument;
49
+
use OCP\Console\Attribute\AsCommand;
50
+
use OCP\Console\Attribute\Option;
51
+
use OCP\Console\ExitCode;
52
+
use OCP\Console\IOutput;
50
53
use OCP\IUserManager;
51
-
use Symfony\Component\Console\Input\InputArgument;
52
-
use Symfony\Component\Console\Input\InputInterface;
53
-
use Symfony\Component\Console\Input\InputOption;
54
-
use Symfony\Component\Console\Output\OutputInterface;
55
-
56
-
class Greet extends Base {
57
54
55
+
#[AsCommand(
56
+
name: 'myapp:greet',
57
+
// this short description is shown when running "occ list"
58
+
description: 'Print a greeting for a Nextcloud user.',
59
+
// this is shown when running the command with the "--help" option
60
+
help: 'This command prints a greeting for the given Nextcloud user.',
61
+
// this allows you to show one or more usage examples (no need to add the command name)
62
+
usages: ['bob', 'alice --shout'],
63
+
)]
64
+
class Greet {
58
65
public function __construct(
59
66
private IUserManager $userManager,
60
67
) {
61
-
parent::__construct();
62
68
}
63
69
64
-
#[\Override]
65
-
protected function configure(): void {
66
-
$this
67
-
->setName('myapp:greet')
68
-
->setDescription('Print a greeting for a Nextcloud user')
69
-
->addArgument(
70
-
'user-id',
71
-
InputArgument::REQUIRED,
72
-
'The user to greet',
73
-
)
74
-
->addOption(
75
-
'shout',
76
-
null,
77
-
InputOption::VALUE_NONE,
78
-
'Print the greeting in uppercase',
79
-
);
80
-
}
81
-
82
-
#[\Override]
83
-
protected function execute(InputInterface $input, OutputInterface $output): int {
84
-
$userId = $input->getArgument('user-id');
70
+
public function __invoke(
71
+
IOutput $output,
72
+
#[Argument(description: 'The username of the user')]
73
+
string $userId,
74
+
#[Option(description: 'Print the greeting in uppercase')]
75
+
bool $shout = false,
76
+
): ExitCode {
85
77
$user = $this->userManager->get($userId);
86
78
87
79
if ($user === null) {
88
80
$output->writeln("<error>User \"$userId\" not found.</error>");
0 commit comments