@@ -12,10 +12,144 @@ interface (CLI) commands. Custom commands allow extension developers to
1212provide their own functionality for use on the command line or in the TYPO3
1313scheduler.
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: `\S ymfony\C omponent\C onsole\C ommand\C ommand ` 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: `\S ymfony\C omponent\C onsole\A ttribute\A sCommand ` 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
42176When 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\C omponent\C onsole\C ommand\C ommand `,
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