/

Callbacks, Lifecycle Hooks & Logging

Reach into how a cell displays, how a field's control renders, and what happens at every stage of a save - plus an audit trail of every change.

Column callbacks - custom cell display

->column_callback($column, $callback, $path = null) transforms a LIST column's displayed value. It runs for every row, list-view only, called with ($value, $fieldname, $primary_key, $row, $xcrud). A plain string return is auto-escaped for safety; to return real markup, wrap it with Xcrud::html($html, $text = null).

function status_badge($value, $fieldname, $primary_key, $row, $xcrud)
{
    $class = $value === 'active' ? 'badge-success' : 'badge-muted';

    return Xcrud::html('<span class="badge ' . $class . '">' . htmlspecialchars($value) . '</span>');
}

$xcrud->column_callback('status', 'status_badge');
ParameterTypeDefaultDescription
$columnstring-Column whose displayed value is transformed
$callbackcallable|string-Function name (resolved via the functions.php convention) or a closure
$path?stringnullExplicit file to load the function from, instead of the default core/functions.php

See Custom Cell Rendering: Badges & Avatars for more Xcrud::html() examples like badges and avatars.

Field callbacks - custom form controls

->field_callback($field, $callback, $path = null) replaces one field's form control with custom HTML, called with ($value, $field, $primary_key, $list, $xcrud) ($list is the row being edited, null for a new record). The returned HTML is trusted and must include its own name="{field}" control for the value to round-trip on save.

function rating_stars($value, $field, $primary_key, $list, $xcrud)
{
    return '<input type="number" name="' . $field . '" min="1" max="5" value="' . (int) $value . '">';
}

$xcrud->field_callback('rating', 'rating_stars');

Lifecycle hooks

Eight hooks run at fixed points around a save/remove, each taking $callback, ?string $path = null - loaded via the same functions.php convention (or an explicit path) as the callbacks above:

HookFires
before_createBefore the empty Add form is built
before_listBefore the grid's row data is fetched
before_insertBefore a new row is written
after_insertAfter a new row is written
before_updateBefore an existing row is written
after_updateAfter an existing row is written
before_removeBefore a row is deleted
after_removeAfter a row is deleted
function orders_after_insert($data, $primary_key, $xcrud)
{
    $xcrud->toast('Order #' . $primary_key . ' created.');
}

$xcrud->after_insert('orders_after_insert');

Toast notifications

->toast($message, $type = 'success') queues a toast notification from inside a hook or button function. $type is a free-form string; the client recognizes success/error/info/warning for styling, falling back to a plain-colored toast for anything else.

$xcrud->toast('Payment recorded.', 'success');
ParameterTypeDefaultDescription
$messagestring-Toast text
$typestring'success'success, error, info, or warning

Audit trail with set_logging()

->set_logging($enabled = true) writes every create/update/delete this table's form makes to a logs table: table name, action, the logged-in user, the record id, the new field values, and - for update/delete, where a previous state exists to capture - the row's own values immediately before the change (old_record). Off by default, since it adds an extra write (and, for update/delete, an extra read) on every save.

$xcrud->set_logging(true);
ParameterTypeDefaultDescription
$enabledbooltrueWhether to write audit-log rows for this table's changes