System Event Hooks

1 views Markdown

The ten hooks over the installation itself: add-ons, announcements, imports, tasks, versions, the site map and certificates.

Overview

These hooks watch the installation itself rather than a customer: which add-on was installed, which announcement went out, which transfer finished, whether a new version appeared.

Three of them face outward: the site map towards search engines, the certificate sweep towards your alerting, and the transfer page towards the parties looking at it.

Reference

Following an add-on being installed

actionaddon.installed
AdminModules after install

Runs after an add-on package is installed. Being installed does not mean it is switched on.

Parameters 2
$modulestringThe key of the installed add-on.
$activatedboolWhether it was switched on during the install. A false means it sits on disk but does not run.
Return 1
voidThe return is ignored.
Listener
Hook::add('action:addon.installed', 10, function ($module, $activated) {
    // Installed does not mean switched on.
    if ($activated) Acme::onEnabled($module);
});

Following an add-on status change

actionaddon.status_changed
AdminModules one of two values

Runs when an add-on is switched on or off.

Parameters 2
$keystringThe key of the add-on.
$statusstringThe new state: enable or disable.
Return 1
voidThe return is ignored.
Listener
Hook::add('action:addon.status_changed', 10, function ($key, $status) {
    if ($status === 'disable') Acme::pauseIntegration($key);
});

Following an add-on being deleted

actionaddon.deleted
AdminModules after deletion

Runs after an add-on is removed.

Parameters 1
$modulestringThe key of the removed add-on.
Return 1
voidThe return is ignored.
Listener
Hook::add('action:addon.deleted', 10, function ($module) {
    Acme::cleanupIntegration($module);
});

Following an announcement being saved

actionannouncement.saved
AdminAnnouncements create and edit

Runs after an announcement is saved.

Parameters 3
$savedIdintThe id of the announcement.
$dataarrayThe saved data: title, message, type, target country and language, product group, server, date range and status.
$isNewboolTrue when newly added, false when updated.
Return 1
voidThe return is ignored.
Listener
Hook::add('action:announcement.saved', 10, function ($savedId, $data, $isNew) {
    // Carry only a new announcement to the outside channel.
    if ($isNew) Acme::broadcast($data['title'] ?? '', $data['message'] ?? '');
});

Following an import finishing

actionimport.completed
Imports per data type

Runs when a transfer from another system finishes. It fires per data type: customers, products and invoices each finish separately.

Parameters 3
$platformstringThe platform data came from.
$typestringThe type of data transferred.
$resultarrayWhat the transfer produced: progress, counters and status.
Return 1
voidThe return is ignored.
Listener
Hook::add('action:import.completed', 10, function ($platform, $type, $result) {
    // It fires per type: this does not mean "everything is done".
    Acme::noteImport($platform, $type, $result);
});

Following a task being saved

actiontask.saved
AdminTasks create and edit

Runs when a task inside the panel is saved.

Parameters 2
$idintThe id of the task.
$is_newboolTrue when it was newly created.
Return 1
voidThe return is ignored.
Listener
Hook::add('action:task.saved', 10, function ($id, $is_new) {
    if ($is_new) Acme::mirrorTask($id);
});

Following a new version being spotted

actionupdates.new_version_detected
Updates notice only

Runs when a new core version is spotted. Nothing is upgraded: this is only news.

Parameters 2
$responsearrayWhat the new version carries: its number, type and change list.
$current_versionstringThe version currently installed.
Return 1
voidThe return is ignored.
Listener
Hook::add('action:updates.new_version_detected', 10, function ($response, $current_version) {
    // Nothing is upgraded here, it is only reported.
    Acme::notifyOps('new version: ' . ($response['version'] ?? '?'));
});

Adding addresses to the site map

filtersitemap.links
Sitemap per language

Runs while the site map is produced. Announce your own pages to search engines here.

Parameters 2
$linksarrayby linkThe list of full addresses. Add or remove freely. Empty entries and repeats are cleaned as the output is made; the order holds.
$ctxarrayby linkContext: the language of this map and the address keys the active theme does not serve. The hook runs once per language: build your address for that language.
Return 1
voidThe return is ignored; you add to the list.
Listener
Hook::add('filter:sitemap.links', 10, function (&$links, &$ctx) {
    // The hook runs once per language.
    foreach (Acme::publicPages($ctx['lang'] ?? '') as $url) $links[] = $url;
});

Reporting certificates about to expire

filterssl.expiring_services
cronjobs returns a contribution

Runs while certificates nearing their end are collected. Add certificates the core does not know about here.

Parameters 1
$maxDaysintThe warning window: how many days ahead to report.
Return 1
array|nullYou return your own contribution: the services nearing their end, each with the days left. The core merges every return, so give your share rather than the whole list.
Listener
Hook::add('filter:ssl.expiring_services', 10, function ($maxDays) {
    // Return only YOUR share: the core merges them all.
    return Acme::expiringCerts($maxDays);
});

Enriching the transfer verification page

filterlicense.transfer.verify_context
LicenseTransfer passed by link

Runs while the licence transfer verification page is shown. Add information of your own here.

Parameters 1
$ctxarrayby linkThe page context: the transfer state and record, the service, and the parties handing over and receiving.
Return 1
voidThe return is ignored; you write over the context.
Listener
Hook::add('filter:license.transfer.verify_context', 10, function (&$ctx) {
    $ctx['acme_note'] = Acme::transferNote((int) ($ctx['transfer']['id'] ?? 0));
});

Pitfalls

An import finishes per data type

The import event fires separately for each type: customers finish, then products, then invoices. Reading one call as "the whole import is done" starts work on half the data.

The certificate hook wants a contribution, not a list

In the expiry sweep you return your own share. The core merges every return, so handing back the whole list duplicates records.

Was this helpful?

Thanks for your feedback!

Still Need Help?

Our support team is here around the clock for anything you can't find above.