Triggers provide advanced users with the ability to write their own PHP
scripts for such things as validating user input, and to have their code
executed at the appropriate time. Triggers are files that are included via
an include()
statement and conditionally executed by
phpMyEdit.class.php. SQL triggers are included before or
after insert, update, or delete of record. FORM triggers are included before
displaying the form that will allow the corresponding operation, or after the
user canceled this form.
For SQL triggers, the operation sequence is this: before, main, after. If any operation fails, not only should the next operation(s) not be executed, but the previous ones are 'rolled back' as if they never happened. If a database is not able to do this, it is not 'transaction-safe'.
Triggers are risky in basic MySQL as there is no native transaction support. It is not transaction-safe by default. There are transaction-safe table types in MySQL that can be conditionally built (see MySQL-Max), but phpMyEdit is currently not set up to support real transactions. What that means is that if an operation fails, the database may be left in an intermediate and invalid state.
The programmer must understand and accept these risks prior to using the phpMyEdit triggers mechanism. If the triggers are used, they execute within the namespace or scope of the phpMyEdit class.
Triggers must return true
or false
to indicate success or failure.
There are following types of phpMyEdit triggers:
'pre' triggers are usually used to check conditions before displaying the operation's page. For example, users may be allowed to View all records but can only Edit a subset of them. Another usage is to lock the record in order to avoid other users to start to change it at the same time.
'before' triggers are usually used to verify conditions prior to executing the main operation. For example, they can be of some use for input validation.
'after' triggers are usually used to perform follow-up operations after the main operation. For example, to update secondary tables to enforce referential integrity or to update aggregate tables.
'cancel' triggers are usually used to perform follow-up operations after users cancel the form. For example, if a record is locked using a 'pre' triggers, then a 'cancel' trigger can unlock it.
If 'pre' triggers fail, users are sent back to the list, except for the 'update' case, where users are sent back to view page if the pre-update trigger fails.
Example 3-21. Select triggers
// Before displaying the view page $opts['triggers']['select']['pre'] = 'categories.TSP.inc'; // After canceling the view page $opts['triggers']['select']['cancel'] = 'categories.TSC.inc';
Example 3-22. Insert triggers
// Before displaying the add/copy page $opts['triggers']['insert']['pre'] = 'categories.TIP.inc'; // After requesting save or more in the add/copy page $opts['triggers']['insert']['before'] = 'categories.TIB.inc'; $opts['triggers']['insert']['after'] = 'categories.TIA.inc'; // After canceling the add/copy page $opts['triggers']['insert']['cancel'] = 'categories.TIC.inc';
Example 3-23. Update triggers
// Before displaying the edit page $opts['triggers']['update']['pre'] = 'categories.TUP.inc'; // After requesting save or apply in the edit page $opts['triggers']['update']['before'] = 'categories.TUB.inc'; $opts['triggers']['update']['after'] = 'categories.TUA.inc'; // After canceling the edit page $opts['triggers']['update']['cancel'] = 'categories.TUC.inc';
Example 3-24. Delete triggers
// Before displaying the delete page $opts['triggers']['delete']['pre'] = 'categories.TDP.inc'; // After requesting delete in the delete page $opts['triggers']['delete']['before'] = 'categories.TDB.inc'; $opts['triggers']['delete']['after'] = 'categories.TDA.inc'; // After canceling the delete page $opts['triggers']['delete']['cancel'] = 'categories.TDC.inc';
Please note that ['select']['after']
and
['select']['before']
triggers currently do not exist.
In the following sample are steps during a View, Edit, Apply and Cancel
operation described. All involved triggers return true
.
['select']['pre']
trigger is included (if defined)true
is returned then continue, else go back to list page['update']['pre']
trigger is included (if defined)true
is returned then continue, else go back to view page['update']['before']
trigger is included (if defined)true
is returned then continue, else, back to list without updating['update']['after']
trigger is included (if defined)['update']['pre']
trigger is included (if defined)true
is returned then continue, else go back to view page['update']['cancel']
trigger is included (if defined)In every trigger file you have available following usable variables. Some of them affect only a particular action.
$this | object reference |
$this->dbh | initialized MySQL database handle |
$this->key | primary key name |
$this->key_type | primary key type |
$this->key_delim | primary key deliminator |
$this->rec | primary key value (update and delete only) |
$newvals | associative array of new values (update and insert only) |
$oldvals | associative array of old values (update and delete only) |
$changed | array of keys with changed values |
$this
object reference. All variables occur in
'before' triggers as well as in 'after' triggers.
Only class properties occurs in 'pre' and 'cancel' triggers currently.
It is recommended to use the $this->myQuery()
method in order
to perform database queries for fetching additional data or doing inserts or
updates to other database tables.
You may set several triggers for the same operation. This allows to isolate code, to share more easily triggers between multiple calling scripts and to reuse code produced by another phpMyEdit users.
The order triggers are executed in is important. It is set by the keys of the
chained triggers. As soon as one of the chained trigger fail, the overall
return value is set to false
, and following triggers are
not executed. If none of chained triggers failed, then the return value is
true
.
Example 3-25. Chained update before triggers
$opts['triggers']['update']['before'][1] = 'lock.TUA.inc'; $opts['triggers']['update']['before'][0] = 'check.TUB.inc';
In this example, when the user clicks on the Save
button during editing a record, check.TUB.inc will be run
first. If it returns true
, then
lock.TUB.inc will be run as well. If one of these
triggers fails, update of the database won't be performed, just like if a
simple ['update']['before']
trigger failed. Note that
although the overall return value of 'cancel' triggers does not inluence
phpMyEdit behavior, the return value of each chained trigger is important.