Custom commands
Not everything on a site happens on a browser request: a mailing, cleaning up old records or a nightly report is started from the terminal or on a schedule. Such tasks are written as custom commands, which are run like the built-in ones: bin/cake name.
Creating
Commands live in the src/Command folder:
bin/cake bake command Stats// src/Command/StatsCommand.php
namespace App\Command;
use Cake\Command\Command;
use Cake\Console\Arguments;
use Cake\Console\ConsoleIo;
class StatsCommand extends Command
{
public function execute(Arguments $args, ConsoleIo $io): int
{
$io->out('Hello from the command!');
return static::CODE_SUCCESS;
}
}The code of a command is in the execute() method. The $io object prints text to the terminal. The method returns an exit code: CODE_SUCCESS means all is well and CODE_ERROR means an error.
Running
bin/cake statsThe command name comes from the class name: StatsCommand gives stats, SendReportCommand gives send_report. The terminal shows "Hello from the command!".
Working with the database
public function execute(Arguments $args, ConsoleIo $io): int
{
$total = $this->fetchTable('Articles')->find()->count();
$io->out("Articles in the database: $total");
return static::CODE_SUCCESS;
}A command has no $this->Articles, so the table is obtained with fetchTable(). After that it is used as in a controller.
Arguments and options
An argument is a required value after the command name, and an option is an optional setting with two hyphens. They are described in a separate method:
use Cake\Console\ConsoleOptionParser;
protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
{
return $parser
->addArgument('email', ['help' => 'Where to send the report', 'required' => true])
->addOption('limit', ['help' => 'How many articles', 'default' => '10']);
}
public function execute(Arguments $args, ConsoleIo $io): int
{
$email = $args->getArgument('email');
$limit = (int) $args->getOption('limit');
$io->success("A report on $limit articles was sent to $email");
return static::CODE_SUCCESS;
}bin/cake stats admin@example.com --limit=5The command prints "A report on 5 articles was sent to admin@example.com". The help texts are shown by bin/cake stats --help.
Output
| Method | What it does |
|---|---|
$io->out('…') | Prints a line |
$io->success('…') | A green success message |
$io->warning('…') | A warning |
$io->error('…') | An error message |
$io->ask('Continue?') | Asks a question and returns the answer |
Running on a schedule
On a server commands are started by the cron scheduler. A line is added with the crontab -e command:
0 9 * * 1 cd /var/www/blog && bin/cake stats admin@example.comThe report is sent every Monday at nine in the morning.
Common mistake
Cron runs a command outside the project folder and with a different set of environment variables. Without cd /var/www/blog && at the start of the line bin/cake is not found and the task silently does not run. Always include the change to the project folder and check the run by hand with the same line.