Tutorial: Create a console command from scratch
A console command is always inside an extension. If you want to create one, kickstart a custom extension or use your site package extension.
Table of contents
Creating a basic command
In this section we will create an empty command skeleton with no parameters or user interaction.
See also
Create a class called
Do
which extends
\Symfony\
.
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
#[AsCommand(
name: 'myextension:dosomething',
description: 'A command that does nothing and always succeeds.',
aliases: ['examples:dosomethingalias'],
)]
class DoSomethingCommand extends Command
{
protected function configure(): void
{
$this->setHelp('This command does nothing. It always succeeds.');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->info('Command needs to be implemented. ');
return Command::SUCCESS;
}
}
The following two methods should be overridden by your class:
configure
() - As the name suggests, this is where the command can be configured. Add a help text and/or define arguments and options.
execute
() - Contains the command logic. Must return an integer. It is considered best
practice to return the constants
Command::
orSUCCESS Command::
.FAILURE
The above example can be run via the command line. If a newly created or edited command is not found, clear the cache first:
vendor/bin/typo3 cache:flush
vendor/bin/typo3 examples:dosomething
typo3/sysext/core/bin/typo3 cache:flush
typo3/sysext/core/bin/typo3 examples:dosomething
The command will return without a message as it does nothing but state that it has succeeded.
Example console command implementations
A command with parameters and arguments
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use T3docs\Examples\Exception\InvalidWizardException;
#[AsCommand(
name: 'myextension:createwizard',
)]
final class CreateWizardCommand extends Command
{
protected function configure(): void
{
$this
->setHelp('This command accepts arguments')
->addArgument(
'wizardName',
InputArgument::OPTIONAL,
'The wizard\'s name',
)
->addOption(
'brute-force',
'b',
InputOption::VALUE_NONE,
'Allow the "Wizard of Oz". You can use --brute-force or -b when running command',
);
}
protected function execute(
InputInterface $input,
OutputInterface $output,
): int {
$io = new SymfonyStyle($input, $output);
$wizardName = $input->getArgument('wizardName');
$bruteForce = (bool)$input->getOption('brute-force');
try {
$this->doMagic($io, $wizardName, $bruteForce);
} catch (InvalidWizardException) {
return Command::FAILURE;
}
return Command::SUCCESS;
}
private function doMagic(SymfonyStyle $io, mixed $wizardName, bool $bruteForce): void
{
// do your magic here
}
}
This command takes one argument
wizard
(optional) and one option (optional),
which can be added on the command line:
vendor/bin/typo3 examples:createwizard [-b] [wizardName]
typo3/sysext/core/bin/typo3 examples:createwizard [-b] [wizardName]
Sending a FluidMail via command
<?php
declare(strict_types=1);
namespace T3docs\Examples\Command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use TYPO3\CMS\Core\Core\Bootstrap;
use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\Mail\FluidEmail;
use TYPO3\CMS\Core\Mail\MailerInterface;
use TYPO3\CMS\Core\Site\SiteFinder;
#[AsCommand(
name: 'myextension:sendmail',
)]
class SendFluidMailCommand extends Command
{
public function __construct(
private readonly SiteFinder $siteFinder,
private readonly MailerInterface $mailer,
) {
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
Bootstrap::initializeBackendAuthentication();
// The site has to have a fully qualified domain name
$site = $this->siteFinder->getSiteByPageId(1);
$request = (new ServerRequest())
->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_FE)
->withAttribute('site', $site);
$GLOBALS['TYPO3_REQUEST'] = $request;
// Send some mails with FluidEmail
$email = new FluidEmail();
$email->setRequest($request);
// Set receiver etc
$this->mailer->send($email);
return Command::SUCCESS;
}
}