ARK log
The Ark log is a multipurpose log which is used to store a variety of data related to the system and to data. The log is also used to provide wiki-like trackback information about user edits to data, see the section below on edit/delete logging for more detail on how this works.
Contents
Theory
Logging level flags are used to indicate the level of logging required by the system. These are set in the main system conf file config/settings.php.
Method
Most simple log events are handled using the logEvent() function which accepts a plain $logvars string that may contain whatever values you want to store in the 'vars' field of the log. This provides a neat way to store error messages or sql statements.
Scripts which are not involved in database actions should make use of this function for logging variables.
In the case of database activity, the logging functions are executed within the edtData functions themselves and are activated by sending the respective functions a logging level switch.
Edit/Delete Logging
Ark provides wiki-like storage of edit and delete history. This not only provides useful information on the data creation process, but it also allows 'undo' functionality.
Edit Handling
Edits of data are handled inside the 6 edtData functions which are customised to handle each of the 6 ark data types. The desired logging level should be passed to the edt function either hard wired (NOT recommended) or by passing the logging flag from the settings file.
If the correct logging level flags are set, the edt function will then execute the logging routine.
The old data in the mysql_fetch_array() format eg:
('field_name' => 'old_field_value')
In this way the entire old record will be stored int he array. This array is then serialize() and inserted into the log as the vars field. No other user defined vars should be set in this case. Should any other vars be required, a second log event is recommended.
In this way, the original cre_by and cre_on data of each record is stored in the log.
The cre_by and cre_on of the log entry will provide user and timedate information for the edit itself (mod_by and mod_on).
The edit itself is linked to the old record by two pieces of information, a log_type and a ref_no. The log type information will define the original table of the data and the type of event that was logged. The reference number will indicate the id number of the row in that table in which the data was originally stored. This provides a link back to the current record (of which the log entry is now 'history').
2 functions have been provided for extracting edit information: The first is getNumEdts which will simply return a number of edits for a given piece of data. The second is getEdt which will return a php array of the vars field which can be accessed using the the exact syntax used after a mysql_fetch_array command. Meaning htt the array can be used within existing code.
Delete Handling
Deletes are handled in a similar way to edits, with the vars of the old record being stored in the same kind of array. The major difference is the way in which the edit is linked back to the place where it was deleted.
When a text is deleted, the record is moved to the log and the connection to the original record is made using the log type field and the ref_no field. Note that when a text is deleted, it no long makes reference to a text id, rather it makes refernce to the record from which it was deleted and the type of text that it was.
In practice this means that we need to store 5 searchable values for each deleted record:
- table - The table in which this record was stored (typically the cor_tbl_class
- itemkey - The item key such as cxt_cd
- itemval - The value of that item key such as FBN05_202
- type - The type (id) of record for this class of data (in the case of text class data this might be short_desc=1)
- typemod - The module in which the lut resides that contains this data type
The log 'ref' therefore contains a concatenation of these fields and the 'refid' contains a concatenation of these values. This has the advantage of allowing the 'ref' to define the 'refid' in a transparent and extensible way without requiring alterations to the table structure. The downside is that this is a rather clumsy way to handle data. It should be noted that only log data should be handled in this manner and that it is not anticipated that this data will be frequently accessed.
In practice this concatenation takes the form of serialized arrays. Thus the live array of the log 'ref' would look something like:
([0] => 'table', [1] => 'itemkey', [2] => 'itemval', [3] => 'type', [4] => 'typemod')
DEV NOTE: It may be desirable to bin this idea and just use this as human readable information for reference
In practice the log 'refid' field would contain the serialized array of these values. For convenience the keys should be replaced with the names found in the 'ref' field. Therefore the live array of the log 'refid' would look something like:
('table' => 'cor_tbl_txt', 'itemkey' => 'cxt_cd', 'itemval' => 'FBN05_202', 'type' => '1', 'typemod' => 'cor')
Bear in mind that once this array has been serialised it will look like this:
a:5:{s:5:"table";s:11:"cor_tbl_txt";s:7:"itemkey";s:6:"cxt_cd";s:9:"itemvalue";s:9:"FBN05_202";s:4:"type";N;s:7:"typemod";s:3:"cxt";}
This is not very human readable, but bear in mind that we wont bear searching on a text based string in order to retrieve the row. In order to retrive this row, it will be neccessary to serialize an array containing all the necessary name=value pairs and then to use the serialized string as the search string in the sql.
As an example of how to use the logCmplxEvent() function see below. It is important to note that the 'type' has been forced to "int".
$logvars = getRow($db, 'cor_tbl_txt', 253 , FALSE); settype($logvars['txttype'], "int"); $log_ref = array('table', 'itemkey', 'itemvalue', 'type', 'typemod'); $log_refid = array('table' => 'cor_tbl_txt', 'itemkey' => $logvars['itemkey'], 'itemvalue' => $logvars['itemvalue'], 'type' => $logvars['txttype'], 'typemod' => $logvars['typemod']); $logtype = 'deltxt'; logCmplxEvent($db, $logtype, $log_ref, $log_refid, $logvars, $cre_by, $cre_on);
Edit Chains
Edit chains of records related to a deleted record are maintained; with the deleted record becoming the decapitated head of the edit chain, It is therefore neccessary to store the original id of the record so that it can be identified as the lead record in the chain.
Retrieveing values from the Log
In order to get stuff back from the log try to make use of the getLogVars() function which returns an array fo the values in the log. A switch can be used to specify if the function should be used to return all values in a multidim array or just the first or last edits.
Edit Retrieval
// TEMP - 243 has a lot of edits $test = getLogVars($db, 'cor_tbl_txt', 243, 'multi'); foreach ($test AS $editlog) { $testrow = $editlog['vars']; printf("Logged Text: %s<br>", $testrow['txt']); printf("Cre by: %s<br>", $testrow['cre_by']); printf("Cre on: %s<br>", $testrow['cre_on']); printf("Text Edited over by: %s<br>", $editlog['mod_by']); printf("Edit made on: %s<br>", $editlog['mod_on']); printf("Id of log entry: %s<br><br>", $editlog['id']); }
Delete Retrieval
Retrieving deletes from the log is slightly more complicated than edits as we have to target an entire item as well as the type of relationship that the record had with that item (see above). In order to generate the correct search keys, we need to generate the serialized 'ref' and 'refid'. Otherwise, the function works exactly the same as in the case of edit retrival. Bear in mind the 'type' is NOT in quotes which means that it becomes an 'int' NOT a string.
$ref = serialize(array('table', 'itemkey', 'itemvalue', 'type', 'typemod')); $refid = serialize(array('table' => 'cor_tbl_txt', 'itemkey' => 'cxt_cd', 'itemvalue' => 'FBN05_378', 'type' => 7, 'typemod' => 'cxt')); $test = getLogVars($db, $ref, $refid, 'multi'); foreach ($test AS $editlog) { $testrow = $editlog['vars']; printf("Logged Text: %s<br>", $testrow['txt']); printf("Cre by: %s<br>", $testrow['cre_by']); printf("Cre on: %s<br>", $testrow['cre_on']); printf("Text Edited over by: %s<br>", $editlog['mod_by']); printf("Edit made on: %s<br>", $editlog['mod_on']); printf("Id of log entry: %s<br><br>", $editlog['id']); }