Contao periodically executes some tasks via its own cron functionality. The following is a list of tasks executed by Contao’s own bundles:
Task | Interval |
---|---|
Generate calendar RSS feeds | daily |
Purge expired comment subscriptions | daily |
Purge temp folder | daily |
Purge search cache | daily |
Generate XML sitemap | daily |
Purge expired registrations | daily |
Purge expired Opt-In tokens | daily |
Generate news RSS feeds | daily |
Purge expired newsletter subscriptions | daily |
By default the cron tasks are executed after a response is sent back to the visitor when a request to the Contao site has been made.
It is recommended to run PHP via PHP-FPM, otherwise cron execution and search indexing will block any subsequent request by the same user.
You can disable the front end cron by going to System » Settings » Cron job settings and enabling the setting Disable the command scheduler. After disabling the front end cron you should periodically let Contao executes its cron jobs, by either making a request to a web URL, or by executing them via the command line.
In order to trigger cron job execution via a web URL, a request to the _contao/cron
,
route, e.g. https://example.org/_contao/cron
, needs to be made. In a Linux crontab
you could use the following instructions for example:
* * * * * wget -q -O /dev/null https://example.org/_contao/cron
This feature is available in Contao 4.9 and later.
You can also execute the cron jobs directly via the command line:
$ vendor/bin/contao-console contao:cron
This is also the recommended way of periodically executing Contao’s cron jobs. In a Linux crontab you could use the following instructions for example:
* * * * * php /path/to/contao/vendor/bin/contao-console contao:cron
There is no HTTP request context available on the command line. However, Contao needs this to generate the sitemap for example. You can set the domain either in the settings of your website roots or you can define a default domain in your application configuration. See the Symfony Routing Documentation for more details.
# config/parameters.yaml
parameters:
router.request_context.host: 'example.org'
router.request_context.scheme: 'https'
Registering custom cron jobs is similar to registering to hooks.
You can register your own cron jobs using the $GLOBALS['TL_CRON']
arrays. It is
an associative array with the following keys, representing the available intervals:
minutely
hourly
daily
weekly
monthly
To register your own job, add another array item with the class and method
of your cron job to one of the intervals in your config.php
:
// contao/config/config.php
$GLOBALS['TL_CRON']['hourly'][] = [\App\Cron\ExampleCron::class, 'onHourly'];
// src/Cron/ExampleCron.php
namespace App\Cron;
class ExampleCron
{
public function onHourly(): void
{
// Do something …
}
}
This feature is available in Contao 4.9 and later.
Cron jobs can also be registered using the contao.cronjob
service tag with the following
options:
Option | Description |
---|---|
interval |
Can be minutely , hourly , daily , weekly , monthly , yearly or a full CRON expression, like */5 * * * * . |
method |
Will default to __invoke or onMinutely etc. when a named interval is used. Otherwise a method name has to be defined. |
# config/services.yaml
services:
App\Cron\ExampleCron:
tags:
-
name: contao.cronjob
interval: '0 */2 * * *'
method: onEveryTwoHours
You can also use the Contao\CoreBundle\ServiceAnnotation\CronJob
service annotation
to tag the service accordingly:
// src/Cron/ExampleCron.php
namespace App\Cron;
use Contao\CoreBundle\ServiceAnnotation\CronJob;
/**
* @CronJob("hourly")
*/
class ExampleCron
{
public function __invoke(): void
{
// Do something
}
}
The annotation can either be used on the class or on individual methods. When it
is used on the class, either the __invoke
method will be used - or an auto generated
method name (e.g. onMinutely
), if present.
If you need an interval like */5 * * *
you need to escape either the *
or /
with \
, since */
would close the PHP comment.
In some cases a cron job might want to know in which “scope” it is executed in -
i.e. as part of a front end request or as part of the cron command on the command
line interface. The Cron
service will pass a scope parameter to the cron job’s
method.
namespace App\Cron;
use Contao\CoreBundle\Cron\Cron;
class HourlyCron
{
public function __invoke(string $scope): void
{
// Do not execute this cron job in the web scope
if (Cron::SCOPE_WEB === $scope) {
return;
}
// …
}
}
Contao keeps track of a cronjob’s last execution in the tl_cron_job
table. Thus,
if you want to test a cron job even though it has already been executed within
its defined interval, either truncate the whole table or delete the entry for the
specific cron job you want to test. If the table is empty every cronjob will be
executed on the first cron call. After that only on its defined interval.
In Contao 4.4, the table is called tl_cron
and it contains only the last execution
times of the named intervals, not the last execution time of individual cron jobs.