Management Panel Data and Gates

3 views Markdown

The management panel away from the screen. 23 filters change lists and forms, 6 gates sit on staff actions, and 19 hooks report an event.

Overview

The panel's strongest hooks are here. List and form filters touch nearly every screen, because lists and forms come from one structure. You write one filter and it runs on dozens of screens.

That power cuts both ways. A filter that does not pick its target touches the whole panel. Each filter hands you the table or form name, and checking it is your job.

Reference

The ones that change data

The main ones among twenty-three. Most hand the value over by reference and ignore the return. The operation filters carry a mixed contract acting on what you return.

filter:admin.table.rows Every list row — the cells, the row classes, the raw record. The row changes by reference; the return is ignored.
filter:admin.table.columns The list columns; you add, drop and reorder them. The array changes by reference; the return is ignored.
filter:admin.form_builder The fields the form builder produces.
filter:admin.dashboard.statistics The number cards on the dashboard.
filter:admin.dashboard.widgets The list of dashboard boxes.
filter:admin.menu_management The menu tree.
filter:admin.notifications The notifications reaching staff.
filter:admin.bubble_counts The counter bubbles on the menu.
filter:admin.health_status The system health indicator.
filter:admin.settings_save The settings about to be saved.
filter:admin.operation.before Before an operation runs — you can stop it or hand back its output.
filter:admin.operation.after After an operation ran, before the answer leaves.
filter:api.response An API answer — the body going to consumers outside the panel.

The ones that stop

All six sit on staff and permission work. Returning a non-empty string stops the action, and the operator reads that text as the error.

gate:admin.staff_create Opening a new staff account. Returning a non-empty string vetoes it; that text becomes the error.
gate:admin.staff_delete Deleting a staff account. Returning a non-empty string blocks the deletion; that text becomes the error.
gate:admin.privilege_save Saving a privilege group.
gate:admin.department_delete Deleting a department.
gate:admin.editor_upload Uploading a file from the editor.
gate:admin.password_change Changing a password.

The ones that report

action:admin.staff_created A staff account was opened.
action:admin.settings_saved Settings were saved.
action:admin.activity_logged An activity was recorded in the panel.
action:security.settings_updated Security settings changed.
action:admin.two_factor_changed Two-step verification was switched on or off.

A filter with a target

coremio/hooks/acme-admin.php
// The second parameter IS THE TABLE NAME. Without checking it the filter runs on every list.
Hook::add('filter:admin.table.rows', 10, function (&$row, $table_name) {
    if ($table_name !== 'serviceList') return null;

    $id = (int) ($row['model']['id'] ?? 0);
    if (Acme::flagged($id)) $row['attributes']['class'] = 'table-warning';
});

Pitfalls

A filter that skips the table name hits every list

Row and column filters run on every list in the panel. Skip the name check in the second parameter and a rule meant for the service list lands on invoices, customers and tickets. Make your first line the name check.

Adding a column does not fill the cell

The column filter opens the heading and nothing else. The cell value for that column comes from the row filter. Writing one without the other leaves an empty column, or a cell that shows up nowhere.

The operation filter acts on what you return

The before-operation filter carries a mixed contract. An error array stops the operation. A variables array changes the inputs. An output array answers without running it at all. A wrong key name silently means "carry on".

The row filter runs once per row

On a hundred-row list the row filter runs a hundred times. A query inside it turns the list into a hundred queries. Gather what you need once into a static variable and read only that inside the listener.

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.