Panel Analytics Hooks

2 views Markdown

The six hooks over report figures, date ranges, charts and live counters.

Overview

Every number on the report pages passes through these hooks: summary figures, time series, distributions and finance totals. Beside them sits the read-only event of the live counters.

One rule runs through all of them: keep the shape. The chart library and the queries that follow expect particular keys; a missing or mismatched structure quietly yields an empty report.

Reference

Following a live metric poll

actionadmin.analytics.realtime_polled
admin/analytics read only

Runs when the live counters on the board refresh. It repeats at regular intervals while the page is open.

Parameters 1
$statsarrayThe live metrics: how many are online, visitors in the last five minutes, and map markers. A copy is passed: changing it has no effect. It is deliberately an event, not a filter.
Return 1
voidThe return is ignored; the data cannot be changed.
Listener
Hook::add('action:admin.analytics.realtime_polled', 10, function ($stats) {
    // A copy is passed: changing it has no effect.
    Acme::pushMetric('online', (int) ($stats['online_count'] ?? 0));
});

Changing the report date range

filteradmin.analytics.date_range
admin/analytics keys must survive

Runs after the date range picked by the user is resolved. Every report query uses that range.

Parameters 2
$resultarrayby linkThe resolved range: start, end, the previous period’s start and end, and the day count. ? Every key must survive: a missing one breaks the queries that follow and the report comes out empty.
$rangestringThe raw range text from the user.
Return 1
voidThe return is ignored; you write over the data.
Listener
Hook::add('filter:admin.analytics.date_range', 10, function (&$result, $range) {
    // Every key must stay: a missing one empties the report.
    $result['start'] = Acme::fiscalStart($result['start']);
});

Changing the summary figures

filteradmin.analytics.kpis
admin/analytics shape follows the section

Runs once the summary figures at the top of a report page are worked out.

Parameters 3
$kpisarrayby linkThe values worked out. ? Its shape follows the section: the keys in the client report are not the keys in the service report. Check the section before reaching for a key.
$sectionstringThe report section: clients, services or support.
$rangearrayThe active date range.
Return 1
voidThe return is ignored; you write over the data.
Listener
Hook::add('filter:admin.analytics.kpis', 10, function (&$kpis, $section, $range) {
    // The shape follows the section: check it first.
    if ($section !== 'clients') return;

    $kpis['acme_churn'] = Acme::churnRate($range);
});

Changing the time series

filteradmin.analytics.trend_series
admin/analytics equal lengths required

Runs once the chart data is worked out.

Parameters 3
$trendarrayby linkLabels and one or more value series. ? The labels and the series must be the same length; the chart draws its axes from that. Keep the existing series keys and add a new series under its own key.
$reportstringThe report key: income, expense, profit and loss, clients, services or support.
$rangearrayThe active date range.
Return 1
voidThe return is ignored; you write over the data.
Listener
Hook::add('filter:admin.analytics.trend_series', 10, function (&$trend, $report, $range) {
    // Labels and series must be the same length.
    if ($report !== 'income') return;

    $trend['acme_forecast'] = Acme::forecast(count($trend['labels'] ?? []));
});

Changing the distribution data

filteradmin.analytics.distribution
admin/analytics fixed item shape

Runs once the distribution chart data is worked out.

Parameters 4
$dataarrayby linkThe distribution items. Each item must carry a label and a value; the chart library expects that shape and any other quietly yields an empty chart.
$entitystringWhat is distributed: clients, services or tickets.
$typestringThe kind: status, country, language, product, period, priority, department, staff or response time.
$rangearrayThe active date range.
Return 1
voidThe return is ignored; you write over the data.
Listener
Hook::add('filter:admin.analytics.distribution', 10,
    function (&$data, $entity, $type, $range) {
        // Every item must carry a label and a value.
        if ($entity === 'client' && $type === 'country')
            $data = Acme::mergeSmallCountries($data);
    });

Changing the finance summary

filteradmin.analytics.invoice_report_totals
admin/analytics currency filtered

Runs once the summary totals of a finance report are worked out.

Parameters 4
$totalsarrayby linkThe summary totals: count, amount, day count, daily average and currency.
$reportstringWhich report: income, expense, profit and loss, tax, cancelled, refunded or payment method.
$rangearrayThe active date range.
$currency_idintThe currency filtered on; a zero means the base currency.
Return 1
voidThe return is ignored; you write over the data.
Listener
Hook::add('filter:admin.analytics.invoice_report_totals', 10,
    function (&$totals, $report, $range, $currency_id) {
        // A zero currency means the base currency.
        if ($report === 'income') $totals['acme_target'] = Acme::monthlyTarget($currency_id);
    });

Pitfalls

Dropping a date-range key empties the report

Every key in the range array is read by the queries that follow. Removing one or renaming it breaks the figure and chart queries; what appears on screen is not an error but an empty report, which makes it hard to spot.

Labels and series must be the same length

If the label count and the value count part ways in a time series the chart axes slip. Build a new series to the length of the existing labels, and keep the series keys already there.

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.