Events
When working with complex data, it can often be useful to perform some additional action when Editor updates the database based on information from the client-side. Consider for example the following use case:
- Modifying the Editor instance or form fields based on that action being taken
- Deleting files from the file system when rows are removed
- Logging information to a database about an action that a user has taken.
to name just a few!
To make this possible, the PHP Editor
class provides an event listener / callback option similar to the events that the client-side Javascript will trigger.
Listening for events
Events listeners can be added using the Editor->on()
method which takes two arguments:
- The event name to listen for
- A callback function which defines the action to take. The arguments passed to the callback are event dependent. The return value for the
pre*
named events can be used to cancel actions (see below), while the other event handlers to not use any returned value.
Multiple listeners for the same event can be added simply by calling the Editor->on()
method multiple times. The events will be executed in the same sequence that they were added.
Available events
The Editor
class will trigger the following events - the arguments passed into the function are also documented (please note that the events are shown below in the order that they are triggered for each action and that where a data array is passed into the event handler, it is passed by reference):
Get
preGet
(cancellable) - Triggered immediately prior to reading row data from the database (since 1.6)$editor
- The Editor instance that triggered the event$id
- Row id being selected if only a single row is to be selected (i.e. after an edit). Otherwise this value will benull
indicating that all rows will be selected.
postGet
- Triggered immediately after row information has been read from the database (since 1.6)$editor
- The Editor instance that triggered the event&$data
- Data array of rows that have been read from the database$id
- Row id being selected if only a single row is to be selected (i.e. after an edit). Otherwise this value will benull
indicating that all rows will be selected.
Create
preCreate
(cancellable) - Triggered prior to creating a new row and before data validation occurs (allowing validation to be set, or a value to be set and then validated)$editor
- The Editor instance that triggered the event&$values
- The values submitted by the client-side
validatedCreate
- Triggered immediately prior to creating a new row and after validation as passed (since 1.9.3).$editor
- The Editor instance that triggered the event&$values
- The values submitted by the client-side
writeCreate
- Data has been written to the database, but not yet read back, allowing the database to be updated before the data is gathered to display in the table (since 1.6.2)$editor
- The Editor instance that triggered the event$id
- ID of the row that was created&$values
- The values submitted by the client-side
postCreate
- Triggered immediately after a new row has been created$editor
- The Editor instance that triggered the event$id
- ID of the newly created row&$values
- The values submitted by the client-side&$row
- The newly created row's data, as read from the database
Edit
preEdit
(cancellable) - Triggered prior to updating an existing row and before data validation occurs.$editor
- The Editor instance that triggered the event$id
- ID of the row to be edited&$values
- The values submitted by the client-side
validatedEdit
- Triggered prior to updating an existing row and after data validation has passed (since 1.9.3).$editor
- The Editor instance that triggered the event$id
- ID of the row to be edited&$values
- The values submitted by the client-side
writeEdit
- Data has been written to the database, but not yet read back, allowing the database to be updated before the data is gathered to display in the table (since 1.6.2)$editor
- The Editor instance that triggered the event$id
- ID of the row to be edited&$values
- The values submitted by the client-side
postEdit
- Triggered immediately after an existing row has been updated$editor
- The Editor instance that triggered the event$id
- ID of the row that has been edited&$values
- The values submitted by the client-side&$row
- The updated row's data, as read from the database
Delete
preRemove
(cancellable) - Triggered immediately prior to deleting an existing row$editor
- The Editor instance that triggered the event$id
- ID of the row to be deleted&$values
- The values submitted by the client-side (i.e. the row's data set)
postRemove
- Triggered immediately after a row has been deleted$editor
- The Editor instance that triggered the event$id
- ID of the row that has been deleted&$values
- The values submitted by the client-side (i.e. the row's data set)
Upload
preUpload
(cancellable) - Triggered immediately prior to a file upload being processed (since 1.6.2)$editor
- The Editor instance that triggered the event$data
- Data submitted by the upload form
postUpload
- Triggered after a file has been uploaded and information about it read from the database (since 1.6.2)$editor
- The Editor instance that triggered the event$id
- ID of the database record for the uploaded file (or the file's unique name if a database record is not used)$files
- The file information that has been read from the database&$data
- Data submitted by the upload form
Please note that for multi-row creation, editing and deletion, the events are triggered once for each row.
Cancellable events
The pre*
events are all cancellable as of Editor 1.6, allowing the server-side process to optionally decide if a row should be processed or not. This can be useful as a form of data validation, disallowing users from certain actions (although please note that this is not a replacement for validation - no error will be shown to the end user if the processing of a row is cancelled!).
To cancel the processing of a row return false
from the event handler. Any other rows that were also submitted, which are not cancelled themselves, will be correctly processed and the client-side table appropriately updated.
Examples
Modifying fields
It is quite common to wish to store information in the database that is not directly settable by the end user, and furthermore, to have different information stored based on the action that has been triggered from the client-side. This can easily be achieved with events and the methods of the Field
class.
Consider the case where we have information about the user who is using the session available in a PHP session variable ($_SESSION['username']
). We wish to store in the database this information for who created the entry and who last updated the item.
This can be achieved using the preCreate
and preEdit
methods:
Editor::inst( $db, 'staff' )
->fields(
Field::inst( 'first_name' ),
Field::inst( 'last_name' ),
Field::inst( 'position' ),
Field::inst( 'email' ),
Field::inst( 'office' ),
Field::inst( 'created_by' )->set( Field::SET_CREATE ),
Field::inst( 'last_updated_by' )->set( Field::SET_EDIT )
)
->on( 'preCreate', function ( $editor, &$values ) {
$editor
->field( 'created_by' )
->setValue( $_SESSION['username'] );
} )
->on( 'preEdit', function ( $editor, $id, &$values ) {
$editor
->field( 'last_updated_by' )
->setValue( time() );
} )
->process( $_POST )
->json();
- Lines 1-10 - Simple Editor initialisation with 7 fields
- Line 8 - The
created_by
field value is configured to be written only on the create action - Line 9 - Likewise the
last_updated_by
field is configured to be written only on edit - Line 11 -
preCreate
event handler - Lines 12-13 - Get the
created_by
field instance from Editor so we can modify it using theField
API. - Line 14 - Set the value to be written to the database
- Lines 16-20 - Likewise for the updated by field
- Line 22 - Process the data submitted by the client-side
Logging changes
As a further example of how to use these PHP events, consider the case where we want to log information to a database table that details what user made a change, what the change was and when. For this we can use use either the pre*
or post*
events, but we will use the post*
events here which ensures that data is logged only if it was successfully inserted into the database.
Consider the following code:
function logChange ( $db, $action, $id, &$values ) {
$db->insert( 'staff-log', array(
'user' => $_SESSION['username'],
'action' => $action,
'values' => json_encode( $values ),
'row' => $id,
'when' => date('c')
) );
}
Editor::inst( $db, 'staff' )
->fields(
Field::inst( 'first_name' ),
Field::inst( 'last_name' ),
Field::inst( 'position' ),
Field::inst( 'email' ),
Field::inst( 'office' )
)
->on( 'postCreate', function ( $editor, $id, &$values, &$row ) {
logChange( $editor->db(), 'create', $id, $values );
} )
->on( 'postEdit', function ( $editor, $id, &$values, &$row ) {
logChange( $editor->db(), 'edit', $id, $values );
} )
->on( 'postRemove', function ( $editor, &$id, &$values ) {
logChange( $editor->db(), 'delete', $id, $values );
} )
->process( $_POST )
->json();
- Line 1 - In order to maintain the principle of Don't Repeat Yourself (DRY) define a common function that can be used to insert a log record into the database
- Line 2 - Use the
Database->insert()
method of the PHP libraries to perform the insert - Line 3 - Read user name from the PHP session - you will need to update this to match where you store this information
- Lines 3-7 - Data to insert into the
staff-log
database table - Lines 11-18 - Simple Editor initialisation
- Line 20 -
postCreate
event handler - Line 21 - Call the
logChange
function with the required information - Lines 23-28 -
postEdit
andpostRemove
event handlers. - Line 29 - Process the data submitted by the client-side
PHP API documentation
The PHP API developer documentation for the Editor PHP classes is available for detailed and technical discussion about the methods and classes discussed above.