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');
| Parameter | Type | Default | Description |
|---|---|---|---|
$column | string | - | Column whose displayed value is transformed |
$callback | callable|string | - | Function name (resolved via the functions.php convention) or a closure |
$path | ?string | null | Explicit 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:
| Hook | Fires |
|---|---|
before_create | Before the empty Add form is built |
before_list | Before the grid's row data is fetched |
before_insert | Before a new row is written |
after_insert | After a new row is written |
before_update | Before an existing row is written |
after_update | After an existing row is written |
before_remove | Before a row is deleted |
after_remove | After 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');
| Parameter | Type | Default | Description |
|---|---|---|---|
$message | string | - | Toast text |
$type | string | '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);
| Parameter | Type | Default | Description |
|---|---|---|---|
$enabled | bool | true | Whether to write audit-log rows for this table's changes |