Skip to content

Commit 974d9ac

Browse files
[DOCS] Make registration of commands with attributes standard (#5925)
* [DOCS] Make registration of commands with attributes standard And refactor the examples and chapter Releases: main, 13.4, 12.4 * [DOCS] Make registration of commands with attributes standard And refactor the examples and chapter Releases: main, 13.4, 12.4 * [TASK] Language checks --------- Co-authored-by: Sarah McCarthy <[email protected]>
1 parent f72073b commit 974d9ac

15 files changed

+464
-454
lines changed

Documentation/ApiOverview/CommandControllers/CustomCommands.rst

Lines changed: 248 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,144 @@ interface (CLI) commands. Custom commands allow extension developers to
1212
provide their own functionality for use on the command line or in the TYPO3
1313
scheduler.
1414

15-
For a step-by-step guide, see:
16-
:ref:`Tutorial: Create a console command <console-command-tutorial>`
15+
.. seealso::
1716

18-
.. todo: Improve this in a follow up, especially what should go here and what in the tutorial
17+
* For a step-by-step guide, see:
18+
:ref:`Tutorial: Create a console command <console-command-tutorial>`.
19+
20+
.. contents:: Table of contents
21+
22+
.. _writing-custom-symfony-console-command:
23+
24+
The custom command class
25+
========================
26+
27+
To implement a console command in TYPO3 extend the
28+
:php:`\Symfony\Component\Console\Command\Command` class.
29+
30+
.. seealso::
31+
32+
Console commands in TYPO3 are based on the same technology as
33+
commands in Symfony. Find more information about
34+
`Commands in the Symfony documentation <https://symfony.com/doc/current/console.html>`_.
35+
36+
.. _console-command-tutorial-registration-services:
37+
38+
Console command registration
39+
============================
40+
41+
There are two ways that a console command can be registered: you can use the
42+
PHP Attribute AsCommand or register the command in your :file:`Services.yaml`:
43+
44+
.. _console-command-tutorial-registration-attribute:
45+
46+
PHP attribute `AsCommand`
47+
-------------------------
48+
49+
CLI commands can be registered by setting the attribute
50+
:php:`\Symfony\Component\Console\Attribute\AsCommand` in the command class.
51+
When using this attribute there is no need to register the command in
52+
:file:`Services.yaml`.
53+
54+
.. code-block:: php
55+
56+
#[AsCommand(
57+
name: 'examples:dosomething',
58+
description: 'A command that does nothing and always succeeds.',
59+
aliases: ['examples:dosomethingalias'],
60+
)]
61+
62+
63+
The following parameters are available:
64+
65+
`name`
66+
The name under which the command is available.
67+
68+
`description`
69+
Gives a short description. It will be displayed in the list of commands and
70+
the help information for the command.
71+
72+
`hidden`
73+
Hide the command from the command list by setting :yaml:`hidden` to
74+
:yaml:`true`.
75+
76+
`alias`
77+
A command can be made available under a different name. Set to :yaml:`true`
78+
if your command name is an alias.
79+
80+
If you want to set a command as `non-schedulable <console-command-tutorial-registration-tag>`_
81+
it has to be registered via tag not attribute.
82+
83+
.. _console-command-tutorial-registration-tag:
84+
85+
Tag `console.command` in the `Services.yaml`
86+
--------------------------------------------
87+
88+
You can register the command in :file:`Configuration/Services.yaml` by adding the service
89+
definition of your class as a tag :yaml:`console.command`:
90+
91+
.. code-block:: yaml
92+
:caption: packages/my_extension/Configuration/Services.yaml
93+
94+
services:
95+
# ...
96+
97+
MyVendor\MyExtension\Command\DoSomethingCommand:
98+
tags:
99+
- name: console.command
100+
command: 'examples:dosomething'
101+
description: 'A command that does nothing and always succeeds.'
102+
# Also an alias for the command can be configured
103+
- name: console.command
104+
command: 'examples:dosomethingalias'
105+
alias: true
106+
107+
.. note::
108+
Despite using :file:`autoconfigure: true` the commands
109+
have to be explicitly defined in :file:`Configuration/Services.yaml`. It
110+
is recommended to always supply a description, otherwise there will be
111+
an empty space in the list of commands.
112+
113+
.. _deactivating-the-command-in-scheduler:
114+
.. _schedulable:
115+
116+
Making a command non-schedulable
117+
================================
118+
119+
A command can be set as disabled for the scheduler by setting :yaml:`schedulable`
120+
to :yaml:`false`. This can only be done when registering the command via
121+
`tag <console-command-tutorial-registration-tag>`_ and not via attribute:
122+
123+
124+
.. code-block:: yaml
125+
:caption: packages/my_extension/Configuration/Services.yaml
126+
127+
services:
128+
# ...
129+
130+
MyVendor\MyExtension\Command\DoSomethingCommand:
131+
tags:
132+
- name: console.command
133+
command: 'examples:dosomething'
134+
description: 'A command that does nothing and cannot be scheduled.'
135+
schedulable: false
136+
137+
138+
139+
.. _writing-custom-symfony-console-command-context:
140+
141+
Context of a command: No request, no site, no user
142+
==================================================
143+
144+
Commands are called from the console / command line and not through a web
145+
request. Therefore, when the code of your custom command is run by default there
146+
is no `ServerRequest <https://docs.typo3.org/permalink/t3coreapi:typo3-request>`_
147+
available, no backend or frontend user logged in and a request is called without
148+
context of a site or page.
149+
150+
For that reason Site Settings, TypoScript and TSconfig are not loaded by default,
151+
Extbase repositories cannot be used without taking precautions and there are many
152+
more limitations.
19153

20154
.. _writing-custom-commands-extbase:
21155

@@ -36,9 +170,117 @@ Instead, use the :ref:`Query Builder <database-query-builder>` or
36170

37171
.. _writing-custom-commands-backend-authentication:
38172

39-
Backend authentication
40-
----------------------
173+
Using the DataHandler in CLI commands
174+
-------------------------------------
41175

42176
When using the :ref:`DataHandler <datahandler-basics>` in a CLI command,
43-
backend user authentication is required. For more information, refer to:
177+
backend user authentication is required. For more information see:
44178
:ref:`dataHandler-cli-command`.
179+
180+
.. _writing-custom-commands-backend-user:
181+
182+
Initialize backend user
183+
-----------------------
184+
185+
A backend user can be initialized inside the :php:`execute()` method as follows:
186+
187+
.. literalinclude:: _Tutorial/_DoBackendRelatedThingsCommand.php
188+
:caption: packages/my_extension/Classes/Command/DoBackendRelatedThingsCommand.php
189+
:emphasize-lines: 20
190+
191+
This is necessary when using the :ref:`DataHandler <datahandler-basics>`
192+
or other backend permission-handling-related tasks.
193+
194+
.. _console-command-tutorial-fe-request:
195+
.. _console-command-tutorial-fe-request-example:
196+
197+
Simulating a frontend request in TYPO3 Commands
198+
-----------------------------------------------
199+
200+
Executing a TYPO3 command in the CLI does not trigger a frontend (web)
201+
request. This means that several request attributes required for link generation
202+
via Fluid or TypoScript are missing by default. While setting the `site`
203+
attribute in the request is a first step, it does not fully replicate the
204+
frontend behavior.
205+
206+
.. seealso::
207+
See chapter :ref:`frontend-requests-simulation`.
208+
209+
A minimal request configuration may be sufficient for
210+
generating simple links or using `FluidEmail <https://docs.typo3.org/permalink/t3coreapi:mail-fluid-email>`_:
211+
212+
.. literalinclude:: _Tutorial/_SendFluidMailCommand.php
213+
:caption: packages/my_extension/Classes/Command/DoBackendRelatedThingsCommand.php
214+
215+
.. note::
216+
Simulating a frontend request in CLI is possible but requires
217+
all bootstrapping steps to be manually carried out. While basic functionality,
218+
such as link generation, can work with a minimal setup, complex
219+
TypoScript-based link modifications, access restrictions, and
220+
context-aware rendering require additional configuration and may still
221+
behave differently from a real web request.
222+
223+
224+
.. _writing-custom-commands-interaction:
225+
226+
Create a command with arguments and interaction
227+
===============================================
228+
229+
.. _writing-custom-commands-arguments:
230+
231+
Passing arguments
232+
-----------------
233+
234+
Since a command extends :php:`Symfony\Component\Console\Command\Command`,
235+
it is possible to define arguments (ordered) and options (unordered) using the Symfony
236+
command API. This is explained in depth on the following Symfony Documentation page:
237+
238+
.. seealso::
239+
240+
* `Symfony: Console Input (Arguments & Options) <https://symfony.com/doc/current/console/input.html>`__
241+
242+
Both arguments and properties can be registered in a command implementation by
243+
overriding the `configure()` method. You can call methods `addArgument()` and
244+
`addOption()` to register them.
245+
246+
This argument can be retrieved with :php:`$input->getArgument()`, the options with
247+
:php:`$input->getOption()`, for example:
248+
249+
.. literalinclude:: _Tutorial/_CreateWizardCommand.php
250+
:caption: packages/my_extension/Classes/Command/SendFluidMailCommand.php
251+
252+
.. _writing-custom-commands-user-interaction:
253+
254+
User interaction on the console
255+
-------------------------------
256+
257+
You can create a :php:`SymfonyStyle` console user interface using the
258+
:php:`$input` and :php:`$output` parameters of the :php:`execute()` function:
259+
260+
.. literalinclude:: _Tutorial/_CrazyCalculatorCommand.php
261+
:caption: packages/my_extension/Classes/Command/CrazyCalculatorCommand.php
262+
263+
The :php:`$io` variable can be used to generate output and prompt for
264+
input.
265+
266+
.. _writing-custom-commands-dependencyInjection:
267+
268+
Dependency injection in console commands
269+
========================================
270+
271+
You can use :ref:`dependency injection (DI) <Dependency-Injection>` in console
272+
commands via constructor injection or method injection.
273+
274+
.. literalinclude:: _Tutorial/_MeowInformationCommand.php
275+
:caption: packages/my_extension/Classes/Command/MeowInformationCommand.php
276+
:emphasize-lines: 12-13
277+
278+
.. _writing-custom-commands-more:
279+
280+
More about Symfony console commands
281+
===================================
282+
283+
* See implementation of existing command controllers in the Core:
284+
:file:`typo3/sysext/*/Classes/Command`
285+
* `Symfony Command Documentation <https://symfony.com/doc/current/console.html>`__
286+
* `Symfony Commands: Console Input (Arguments & Options) <https://symfony.com/doc/current/console/input.html>`__

0 commit comments

Comments
 (0)