Rapid Application Development toolkit for building Administrative Web Applications

RADICORE for PHP - Functions, Methods and Variables

By Tony Marston

10th March 2006
Amended 1st July 2008

As of 10th April 2006 the software discussed in this article can be downloaded from www.radicore.org

Introduction
Abstract Table Class
- Sequence of Events
- Notes on Public Methods
- Notes on Internal (private) Methods
- Notes on Customisable Methods
- Class Properties
Non OO functions
Session Variables
Global Variables
Amendment History

Introduction

The RADICORE library consists of functions, methods and variables which exist in different 'include' files, such as the following:

dml.mysql.class.inc This is the Data Access Object for MySQL version 4.0 or lower.
dml.mysqli.class.inc This is the Data Access Object for MySQL version 4.1 or higher.
dml.oracle.php4.class.inc This is the Data Access Object for Oracle using the OCI8 extension for PHP 4.
dml.oracle.php5.class.inc This is the Data Access Object for Oracle using the OCI8 extension for PHP 5.
dml.pgsql.class.inc This is the Data Access Object for PostgreSQL version 8.0 or higher.
error.inc This contains the default error handler.
include.general.inc This contains general purpose functions.
include.jump.inc This contains addJump, clearJump and findJump.
include.session.inc This contains functions to do with session handling.
include.subsystem.inc There is a separate copy for each subsystem. It is referenced at the start of include.general.inc to provide the opportunity to execute custom code whenever a script within that subsystem is run and before a database object is created. With this it is possible to amend the include_path setting, or include another file containing more functions.
include.xml.php4.inc This contains the XML and XSL functions for PHP 4.
include.xml.php5.inc This contains the XML and XSL functions for PHP 5.
std.datevalidation.class.inc This contains functions for validating and formatting all dates.
std.encryption.class.inc This contains functions for password encryption and decryption.
std.pdf.class.inc This is for the functions which produce PDF output.
std.singleton.php4.inc An implementation of the singleton design pattern for PHP 4.
std.singleton.php5.inc An implementation of the singleton design pattern for PHP 5.
std.table.class.inc This is the abstract table class from which each database table class is extended.
std.validation.class.inc This contains the processing behind _validateInsert and _validateUpdate.

In the following sections there are some elements which you can reference in your code while there are others which should only be referenced by the framework. The "framework only" elements have been given a different background colour, as follows:

This element is only to be referenced by the framework, not user code

If you try to use any of these elements in your code the results may be unexpected.


Abstract Table Class

Each database table within a RADICORE application has its own table class which contains specific information regarding that particular database table. This class inherits a great deal of common code from the abstract table class. It is the abstract table class that contains the methods which are accessed from all the controllers, and it is the abstract table class which communicates which the database through the data access object (DAO).

Each operation, which starts from the controller and may end in the database, contains a series of distinct steps or stages. Some of these steps in the abstract table class are in fact nothing more than empty methods, and as they contain no code they have no effect on that operation. If any of these empty methods is copied from the abstract table class (superclass) into an application table class (subclass) it will override the method in the superclass. This means that any method found in the subclass will be executed instead of a method with the same name that may be defined in the superclass. This then provides an opportunity to insert code into that empty method so that it can be executed at the appropriate stage of the operation.

These empty methods are known as "customisable methods" in RADICORE as they are predefined and waiting to be filled with custom code. The signature (API) and the return parameter cannot be changed, only what happens in between. Note that within any subclass it is possible to create additional methods other than those mentioned below, but these additional methods will not be executed unless they are called from one of the pre-defined customisable methods.

The following naming conventions are used for methods within the abstract table class:

PrefixMeaning
(none)A public method which can be accessed from outside.
'_'A private method which should only be accessed from inside.
'_cm_'A method which is defined within the abstract table class but is empty of any code. It is therefore called within a sequence of operations but does nothing. A copy can be inserted into any subclass in order to define code that needs to be executed at that point in the sequence.
'_dml_'Internal methods which pass control to the Data Access Object (DAO) in order to send Data Manipulation Language (DML) statements to the database.

In the following sections certain function/method arguments are defined as follows:

  1. $rowdata/$fieldarray - an associative array of 'name=value' pairs containing fields from a single database occurrence. Note that this may also contain fields which have been obtained from other sources (e.g. a sql JOIN).
  2. $rows - an indexed array containing multiple database occurrences, where the index is treated as the row/occurrence number, and each row contains $rowdata for that occurrence.
  3. $where - a string that contains selection criteria in a format which can be used as the WHERE clause in an SQL query, such as:
    field1='value1' AND field2='value2' .....
    

Sequence of Events

In the following table the column labelled 'Entry Point' indicates the method which may be called from outside, either from a controller or another table class. The column labelled 'Sequence' shows other methods which may be called internally, and in what sequence.

Entry PointSequence
cascadeDelete ($where)
  1. $rows = getData_raw ($where)
  2. for each row: deleteRecord ($rowdata)
cascadeNullify ($update_array, $where)
  1. $rows = getData_raw ($where)
  2. for each row: updateRecord ($rowdata)
clearScrollArray ()  
commit ()
  1. _examineWorkflow ($this->fieldarray)
  2. $DML->commit ($this->dbname)
deleteMultiple ($rows)
  1. for each row: deleteRecord ($rowdata)
deleteRecord ($rowdata)
  1. isPkeyComplete($rowdata, $this->PkeyNames)
  2. _cm_pre_deleteRecord ($rowdata)
  3. deleteRelations ($rowdata)
  4. _dml_deleteRecord ($rowdata)
  5. _cm_post_deleteRecord ($rowdata)
deleteRelations ($rowdata)
  1. $child->cascadeNullify ($update_array, $where)
  2. $child->cascadeDelete ($where)
deleteScrollItem ($index)  
deleteSelection ($selection)
  1. _cm_deleteSelection ($selection)
eraseRecord ($rowdata)
  1. isPkeyComplete($rowdata, $this->PkeyNames)
  2. _cm_pre_eraseRecord ($rowdata)
  3. eraseRelations ($rowdata)
  4. _dml_deleteRecord ($rowdata)
  5. _cm_post_eraseRecord ($rowdata)
eraseRelations ($rowdata)
  1. $child->cascadeNullify ($update_array, $where)
  2. $childrows = $child->getData_raw ($where)
  3. for each row: $child->eraseRecord ($childrow)
fetchRow ($resource)
  1. $rowdata = _dml_fetchRow ($resource)
  2. $rowdata = _cm_post_fetchRow ($rowdata)
fileUpload ($input_name, $temp_file)
  1. $output_name = _cm_fileUpload ($input_name, $temp_file, $wherearray)
formatData ($rowdata)
  1. _cm_formatData ($rowdata)
free_result ($resource)
  1. $resource = $DML->_dml_free_result ($resource)
getClassName ()  
getCount ($where)
  1. _dml_getCount ($where)
getData ($where)
  1. $where = _cm_pre_getData ($where, $where_array, $fieldarray)
  2. isPkeyComplete ($where_array, $this->PkeyNames)
  3. $where_str = _sqlAssembleWhere ($where, $where_array)
  4. $data_raw = _dml_getData ($where)
  5. _processInstruction ($data_raw)
  6. _cm_post_getData ($data_raw, $where)
getData_raw ($where)
  1. $data_raw = _dml_getData ($where)
getData_serial ($where)
  1. $where = _cm_pre_getData ($where, $where_array)
  2. $where_str = _sqlAssembleWhere ($where, $where_array)
  3. $resource = getData_serial ($where)
getExpanded ()
  1. return $this->expanded
getExtraData ($input)
  1. getForeignData ($rowdata)
  2. _cm_getExtraData ($where, $firstrow)
  3. _cm_changeConfig ($where, $firstrow)
getFieldSpec ()
  1. return $this->fieldspec
getFieldSpec_original ()
  1. return $this->fieldspec
getForeignData ($rowdata)
  1. _cm_getForeignData ($rowdata)
  2. $parent->getData ($where)
getInitialData ($where)
  1. _cm_getInitialData ($where_array)
getInitialDataMultiple ($where)
  1. _cm_getInitialDataMultiple ($where_array)
getLastIndex ()  
getNodeData ($expanded, $where)
  1. _cm_getNodeData ($expanded, $where, $wherearray)
  2. _processInstruction ($rowdata)
getPkeyArray ($rowdata, $next_task)
  1. getPkeyNames ()
  2. _cm_getPkeyNames ($pkeynames, $task_id, $pattern_id)
getPkeyNames ()
  1. return $this->primary_key
getScrollIndex ()  
getScrollItem ($index)
  1. findJump ($next_index, $curr_index)
  2. array2where ($scrollItem, $pkeyNames)
getScrollSize ()  
getValRep ($item, $where)
  1. _cm_getValRep ($item, $where)
getWhere ()
  1. _cm_getWhere ()
initialise ($where, $selection)
  1. _getInitialValues()
  2. _getInitialWhere($this->sql_where)
  3. _cm_initialise ($where, $selection)
  4. _cm_changeConfig ($where)
  5. _cm_filterWhere()
  6. _cm_setJavaScript ($javascript)
  7. _examineWorkflowInstance ($where)
initialiseFileDownload ($where)
  1. $fieldarray = getData_raw ($where)
  2. _cm_initialiseFileDownload ($fieldarray)
initialiseFilePicker ()
  1. _cm_initialiseFilePicker ()
initialiseFileUpload ($where)
  1. _cm_initialiseFileUpload ($wherearray)
insertMultiple ($rows)
  1. _cm_pre_insertMultiple ($rows)
  2. for each row: insertRecord ($rowdata)
  3. _cm_post_insertMultiple ($rows)
insertOrUpdate ($rowdata)
  1. $rowdata = _cm_pre_insertOrUpdate ()
  2. $pkeynames = getPkeyNames ()
  3. either: $rowdata = insertRecord ($rowdata)
  4. or: $rowdata = updateRecord ($rowdata)
  5. $rowdata = _cm_post_insertOrUpdate ()
insertRecord ($rowdata)
  1. _cm_getInitialData ($rowdata)
  2. _cm_pre_insertRecord ($rowdata)
  3. $insertarray = _validateInsert ($rowdata)
  4. _cm_commonValidation ($insertarray, $rowdata)
  5. _cm_validateInsert ($insertarray)
  6. _dml_insertRecord ($insertarray)
  7. _cm_post_insertRecord ($insertarray)
outputCSV ($resource)
  1. $string = _cm_pre_output ($string)
  2. $fieldarray = fetchRow ($resource)
  3. $fieldarray = formatData ($fieldarray)
  4. $string = _cm_post_output ($string)
outputPDF_DetailView ($resource, $structure)
  1. $filename = _cm_pre_output ($filename)
  2. $string = $PDF->detailView ($resource)
  3. $string = $PDF->output ($name, $destination)
  4. startTransaction ()
  5. $string = _cm_post_output ($string)
  6. commit() or rollback()
outputPDF_ListView ($resource, $structure)
  1. $filename = _cm_pre_output ($filename)
  2. $string = $PDF->listView ($resource)
  3. $string = $PDF->output ($name, $destination)
  4. startTransaction ()
  5. $string = _cm_post_output ($string)
  6. commit() or rollback()
popupCall ($popupname, $where, $script_vars, $fieldarray, $settings)
  1. _cm_popupCall ($popupname, $where, $fieldarray, $settings)
popupReturn ($fieldarray, $return_from, $select_array)
  1. _cm_popupReturn ($fieldarray, $return_from, $select_array)
  2. _cm_getInitialData ($fieldarray)
  3. getForeignData ($fieldarray)
  4. _cm_post_popupReturn ($fieldarray, $return_from, $select_array)
reset ($where)
  1. $this->setSqlSearch(null)
  2. $this->setOrderBy(null)
  3. $this->setOrderBySeq(null)
  4. $this->initialise($where)
rollback ()
  1. $DML->rollback ($this->dbname)
setInstruction ($instruction)
  1. $this->instruction = $instruction
setLookupData ($input)
  1. _cm_changeConfig ($where, $fieldarray)
  2. _cm_getExtraData ($where, $fieldarray)
setParentData ($parent_data)
  1. _cm_setParentData ($fieldarray, $parent_data)
setScrollArray ($where)
  1. _cm_setScrollArray ($where, $where_array)
startTransaction ()
  1. _cm_getDatabaseLock ()
  2. $DML->startTransaction ($this->dbname)
unFormatData ($fieldarray)
  1. _cm_unFormatData ($fieldarray)
updateLinkData ($rows, $postarray)
  1. _cm_pre_updateLinkData ($rows, $postarray)
  2. for each row, one of:
    1. insertRecord ($rowdata)
    2. updateRecord ($rowdata)
    3. deleteRecord ($rowdata)
  3. _cm_post_updateLinkData ($rows, $postarray)
updateMultiple ($rows, $postarray)
  1. _cm_pre_updateMultiple ($rows)
  2. for each row: updateRecord ($rowdata)
  3. _cm_post_updateMultiple ($rows)
updateRecord ($rowdata)
  1. _cm_pre_updateRecord ($rowdata)
  2. $updatearray = _validateUpdate ($rowdata)
  3. $originaldata = _dml_ReadBeforeUpdate ($where, $resuse_previous_select)
  4. _cm_commonValidation ($updatearray, $originaldata)
  5. _cm_validateUpdate ($updatearray, $originaldata)
  6. _dml_updateRecord ($updatearray, $originaldata)
  7. _cm_post_updateRecord ($fieldarray, $originaldata)
updateSelection ($selection, $replace)
  1. _cm_updateSelection ($selection, $replace)
validateDelete ($rowdata, $parent_table)
  1. _cm_validateDelete ($rowdata, $parent_table)
  2. $child->getCount($where)
  3. $rows = $child->getdata ($where)
  4. for each row: $child->validateDelete ($pkey, $parent_table)
validateSearch ($postarray)
  1. _cm_validateSearch ($postarray)

Notes on Public Methods

boolean = $object->cascadeDelete ($where)
$where is a string in the format of a WHERE clause in an SQL query.

The steps in this operation are as follows:

$this->errors will contain any error messages.

boolean = $object->cascadeNullify ($update_array, $where)
$update_array is an associative array which identifies the field(s) to be updated (usually 'foreign_key=NULL').
$where is a string in the format of a WHERE clause in an SQL query.

The steps in this operation are as follows:

$this->errors will contain any error messages.

$fieldarray = $object->clearEditableData (fieldarray)
$fieldarray (IN) is is an associative array containing the details of a single database occurrence.
$fieldarray (OUT) will be the input array with any amendments.

This will examine each field if $fieldarray, and if it is editable (i.e. the noedit attribute is not set), the current value will be nullified.

void $object->clearScrollArray ()

This is used to delete the contents of $this->scrollarray.

$errors = $object->commit ()
$errors will be an array of zero or more error messages.

This will call _examineWorkflow() and either issue a commit or rollback depending on the result. Note that this has no effect on tables which do not support database transactions, such as MyISAM tables.

$rows = $object->deleteMultiple ($rows)
$rows (IN) is an indexed array of database occurrences, and each occurrence is an associative array of name=value pairs.
$rows (OUT) is the same array.

For each record identified in $rows it will call the deleteRecord() method.

$this->errors will contain any error messages.

$this->numrows will contain the count of deleted records.

$this->messages will contain a message in the format 'N records were deleted from TABLENAME'.

$rowdata = $object->deleteRecord ($rowdata)
$rowdata (IN) is an associative array containing the details of a single database occurrence.
$rowdata (OUT) is the same array.

The steps in this operation are as follows:

$this->errors will contain any error messages.

Note that the deletion may have been verified beforehand by a call to validateDelete().

void $object->deleteRelations ($rowdata)
$rowdata is an associative array containing the details of a single database occurrence.

This will examine the contents of $this->child_relations for the database occurrence identified in $rowdata, and for each child record found belonging to that relationship it will perform the action indicated by its type:

$this->errors will contain any error messages.

$where = $object->deleteScrollItem ($index)
$index is the index number an entry in $this->scrollarray.
$where will contain a string which identifies the next available occurrence.

This is used to delete an item from $this->scrollarray, and to return the primary key of the next available entry.

$msg = $object->deleteSelection ($selection)
$selection is a string in the format of a WHERE clause in an SQL query and may identify one or more database occurrences.
$msg will contain a message in the format 'N rows were updated'.

This passes control to _cm_deleteSelection() to perform the relevant processing for those records which match the selection criteria.

$this->numrows will contain the count of records which were deleted.

$rowdata = $object->eraseRecord ($rowdata)
$rowdata (IN) is an associative array containing the details of a single database occurrence.
$rowdata (OUT) is the same array.

The sequence of events is as follows:

This will effectively delete the selected record, its children, the children of its children, and so on all the way down to the bottom of the relationship hierarchy.

$this->errors will contain any error messages.

void $object->eraseRelations ($rowdata)
$rowdata is an associative array containing the details of a single database occurrence.

This will iterate through the contents of $this->child_relations and perform the following on any related occurrence:

$this->errors will contain any error messages.

$rowdata = $object->fetchRow ($resource)
$resource is a database resource created by getData_serial().
$rowdata will contain an associative array of all the fields from a single database occurrence.

This is used to return database records one at a time instead of in multiples. After each iteration the resource pointer will be advanced to the next occurrence, and $rowdata will return FALSE when end-of-file is reached.

The actual steps are as follows:

$output_name = $object->fileUpload ($input_name, $temp_file)
$input_name is the name of the file being uploaded from the client.
$temp_file is a copy of the file in the temporary directory.
$output_name is the file name to be used on the server.

This is used to deal with the file being uploaded from the client before it is written to the server, for example changing it's name into something more meaningful. A temporary copy of the file is available in $temp_file so that its contents may be checked, such as verifying that an image file has the correct dimensions.

This is a wrapper for _cm_fileUpload().

$rowdata = $object->formatData ($rowdata)
$rowdata (IN) is an associative array containing the details of a single database occurrence.
$rowdata (OUT) is the same array after any values have been formatted.

This is called when the data is being transferred to the XML file for output to the user. It will take the contents of $rowdata and, using the field specifications in the $this->fieldspec array, will format any values, such as dates and numbers, before they are displayed to the user. For example, a date such as '2006-01-02' will be converted into '02 Jan 2006'.

It will also call _cm_formatData() to perform any custom formatting.

This is the opposite of unformatData().

$result = $object->free_result ($resource)
$resource is a database resource created by getData_serial().
$result will return either TRUE or FALSE.

This is used to free a resource created by getData_serial() and processed by fetchRow().

$name = $object->getClassName ()
$name will contain the name, in lower case.

This will return the name of the current class so that it can be used as the identity of the current database table when adding data to an XML document. Where the current class is a subclass with a numerical suffix, as in _s01, this will be removed. For example:

A numerical suffix is used when the purpose of the subclass is to contain some different business logic. A non-numeric suffix is used when data from the same database table needs to be inserted into multiple zones within the same XSL stylesheet, in which case the data for each zone comes from an object with a different class name, such as mnu_task_snr and mnu_task_jnr. This is described in Using subclasses to provide alias names

$count = $object->getCount ($where)
$where is a string which identifies what needs to be counted.
$count will contain the count of entries.

If the $where string is in the format column='value' the following statement will be constructed and executed:

$count = $this->getCount("column='X'");
  will execute:
SELECT count(*) from $this->tablename WHERE column='X'

If the $where string begins with 'SELECT ' it will be assumed to be a complete SQL statement and will be executed without any modification, as with the following examples:

$count = $this->getCount("SELECT MAX(seq_no) FROM table27 WHERE column='X'");
$count = $this->getCount("SELECT SUM(quantity) FROM order_item WHERE order_id=42");
$rows = $object->getData ($where)
$where is a string in the format of a WHERE clause in an SQL query and may identify one or more database occurrences.
$rows will be an indexed array of different database rows (occurrences) and each row will be an associative array of field names and values.

This is called from within each page controller to process any selection or search criteria passed down by the parent screen, or from a child SEARCH screen, before constructing an SQL query to retrieve data from the database. Because this uses strings in the $where clause which are constructed by the framework it may not be suitable for $where clauses which are constructed manually inside any object. In these cases the getData_raw() method may be more appropriate.

The following optional variables are also used to construct the SQL query:

The steps in this operation are as follows:

$this->numrows will contain the count of records retrieved from the database.

$rows = $object->getData_raw ($where)
$where is a string in the format of a WHERE clause in an SQL query and may identify one or more database occurrences.
$rows will be an indexed array of different database rows (occurrences) and each row will be an associative array of field names and values.

This calls _dml_getData() without adjusting any related object properties beforehand, and without formatting the data afterwards.

When retrieving another table's data from within a table object this method should be used instead of getData() where the reformatting of the $this->sql_select, $this->sql_from and $where variables inside _sqlAssembleWhere() may cause problems, especially with complex combinations of AND, OR and NOT.

The following optional variables are also used to construct the SQL query:

$this->numrows will contain the count of records retrieved from the database.

$resource = $object->getData_serial ($where)
$where is a string in the format of a WHERE clause in an SQL query and may identify one or more database occurrences.
$resource will be a resource that can be processed by the fetchRow() method, and subsequently released by the free_result() method.

This is similar to getData(), but instead of returning an array of occurrences it returns a resource from which individual occurrences can be obtained one at a time using fetchRow(). This is useful for batch jobs in which an unknown number of database occurrences need to be processed as it could cause problems if all those occurrences were retrieved and loaded into an array before they were processed. With this method it is possible to fetch and process a row before fetching the next row.

The following optional variables are also used to construct the SQL query:

The steps in this operation are as follows:

$this->numrows will contain the count of records retrieved from the database.

Here is some sample code:

$where = "workitem_status='EN' AND deadline <= '$now'";
$workitem_result = $workitem->getData_serial($where);
while ($row = $workitem->fetchRow($workitem_result)) {
    ... process contents of $row ...
} // while
$result = $workitem->free_result($workitem_result)
$array = getExpanded ()
$array will contain a list of nodes which have been expanded.

When viewing a tree structure it is possible to expand a node so that its children will appear in the display. This will identify those nodes which have been expanded so that the system will retrieve its children.

$array = getExtraData ($input)
$input can be either a string (in the format of a WHERE clause) or an associative array. A string will be converted into an array.
$array will be the same as $input, but after any changes have been made.

This retrieves data that may be of use during the transaction which would not otherwise be made available, such as for INSERTS. The contents of $input may be a WHERE string, or it may be an array of database records. The sequence of steps is as follows:

$array = $object->getfieldspec ()
$array will be an associative array of field names and their specifications.

This will return the current contents of the $this->fieldspec. Note that it may have been amended during the processing of the current task.

$array = $object->getfieldspec_original ()
$array will be an associative array of field names and their specifications.

This will return the contents of the $this->fieldspec array after it has been reloaded from the <tablename>.dict.inc file which was exported from the Data Dictionary. This is done immediately prior to any INSERT or UPDATE operations to remove any changes made in custom code as these changes may be out of step with the physical database structure and could cause a fatal error.

$rowdata = $object->getForeignData ($rowdata)
$rowdata (IN) is an associative array containing the details of a single database occurrence.
$rowdata (OUT) will be the same array, but after any changes have been made.

This will first call _cm_getForeignData() to perform any custom processing.

Then it will examine the contents of $this->parent_relations. For each relationship it will perform the following:

Here is an example of the code:

    foreach ($this->parent_relations as $reldata) {
        if (isset($reldata['parent_field'])) {
            // may be more than one parent_field, so turn it into an array of separate field names
            $parent_fields = extractFieldNamesIndexed($reldata['parent_field']);
            // construct WHERE clause to read from parent table
            $where = '';
            foreach ($reldata['fields'] as $fldchild => $fldparent) {
                if (strlen($fldchild) < 1) {
                    // 'Name of child field missing in relationship with $tblchild'
                    $this->errors[] = getLanguageText('sys0110', strtoupper($tblchild));
                    break;
                } // if
                if (!isset($fieldarray[$fldchild]) or strlen($fieldarray[$fldchild]) == 0) {
                    // foreign key field is missing, so stop further processing
                    $where = '';
                    break;
                } // if
                if (empty($where)) {
                    $where = "$fldparent='" .addslashes($fieldarray[$fldchild]) ."'";
                } else {
                    $where .= " AND $fldparent='" .addslashes($fieldarray[$fldchild]) ."'";
                } // if
            } // foreach
            if (empty($where)) {
                // $where is empty, so set foreign field(s) to empty
                foreach ($parent_fields as $ix => $parent_field) {
                    $fieldarray[$parent_field] = null;
                } // foreach
            } else {
                if (isset($fieldarray[$parent_fields[$ix]]) AND !empty($fieldarray[$parent_fields[$ix]])) {
                    // (last) parent field is already there, so do nothing
                } else {
                    $tblparent = $reldata['parent'];
                    // instantiate an object for this table
                    if (array_key_exists('subsys_dir', $reldata)) {
                        $dir = $_SERVER['DOCUMENT_ROOT'] .getParentDIR() .'/' .$reldata['subsys_dir'] .'/';
                    } else {
                        $dir = NULL;
                    } // if
                    if (!class_exists($tblparent)) {
                        require_once $dir ."classes/$tblparent.class.inc";
                    } // end
                    $parentobj = new $tblparent;
                    $parentobj->sql_select = $reldata['parent_field'];
                    $parent_data = $parentobj->getData($where);
                    if (count($parent_data) > 0) {
                        // copy specified parent field(s) into $fieldarray
                        foreach ($parent_fields as $ix => $parent_field) {
                            $fieldarray[$parent_field] = $parent_data[0][$parent_field];
                        } // foreach
                    } else {
                        // not found, so set foreign key(s) to empty
                        foreach ($reldata['fields'] as $fldchild => $fldparent) {
                            $fieldarray[$fldchild] = null;
                        } // foreach
                    } // if
                } // if
            } // if
        } // if
    } // foreach

Click on the following hyperlink for a description of getLanguageText().

$array = $object->getInitialData ($input)
$input is either a string in the format of a WHERE clause, or an associative array.
$array will be an associative array containing initial values.

This is used with INPUT tasks to supply any initial values before the screen is displayed to the user. Without it all the fields would be blank.

The steps in this operation are as follows:

$array = $object->getInitialDataMultiple ($input)
$input can be either a string (in the format of a WHERE clause) or an associative array. A string will be converted into an array.
$array will be the same as input, but after any initial values have been added.

This is a wrapper for _cm_getInitialDataMultiple().

This is used in the ADD4 transaction pattern to create the records that will be inserted by calling insertMultiple().

This is also used in the ADD5 transaction pattern to create a number of blank records that will be displayed in the screen into which the user can then enter data.

$index = $object->getLastIndex ()
$index is the highest index number in $this->scrollarray.
$array = $object->getNodeData ($expanded, $where)
$expanded is either an indexed array which identifies the nodes which are to be expanded, or a string containing 'ALL' to signify all available nodes.
$where is a string which is used as selection criteria.
$array will be an indexed array of different database occurrences, and each occurrence will be an associative array of field names and values.

The steps in this operation are as follows:

$array = $object->getPkeyArray ($rowdata=null, $next_task=null)
$rowdata is an optional associative array of name=value pairs for a single database occurrence.
$next_task is as associative array with details of the next task
$array will be the same as the input array, but will only contain those fields which exist within the primary key.

If $rowdata is not supplied then $this->fieldarray will be used instead.

The processing sequence is as follows:

The remaining fields will then be used to construct a string in the format of the WHERE clause of an sql SELECT statement.

$array = $object->getPkeyNames ()
$array will be an indexed array of field names.

This is used to obtain a list of all the fields which comprise the primary key in the current table. It will obtain the relevant information from $this->primary_key.

$index = $object->getScrollIndex ()
$index is the current pointer into $this->scrollarray.
$where = $object->getScrollItem (&$index)
$index (IN) is a key to an entry in $this->scrollarray.
$index (OUT) will contain an index number which may be different.
$where will contain the primary key of the entry indicated by $index.

The processing sequence is as follows:

$size = $object->getScrollSize ()
$size is the current count of items in $this->scrollarray.
$output = $object->getWhere ($next_task)
$output is the $where string from the object.
$next_task is an associative array which contains details of the child task.

This is called when a navigation button is pressed in order to extract the $where string from the main object in the current task so that it can be passed to the next task.

The _cm_getWhere() method is called in case this string needs to be customised.

See also: Appendix I: Passing context between objects.

$array = $object->getValRep ($item, $where)
$item is the name of the list to be returned as there may be more than one.
$where is an optional string containing selection criteria.
$array will contain the output as an associative array.

This is used to obtain the contents of a dropdown list or radio group. The term "ValRep" stands for "Value/Representation" where "Value" is what is held internally and "Representation" is what is shown to the user. The list may either be hard-coded, or extracted from a database table. The implementation details are defined in _cm_getValRep().

$where = $object->initialise ($where, $selection)
$where (IN) is a string in the format of a WHERE clause in an SQL query.
$selection is an optional string similar to $where
$where (OUT) is the version of $where (IN) after any amendments have been applied.

This is used in all forms to perform any initialisation when the form is first activated. It does the following:

Note that the $selection string is only available with tasks of type ADD2, which is called from a LIST2 task. The $where string will identify the parent entity, and if anything was selected from the child entity in will be identified in the $selection string.

All INPUT screens will also use the getInitialData() method.

If $mode is equal to "search" then the following actions will be taken:

void $object->initialiseFileDownload ($where)
$where is a string in the format of the WHERE clause in an SQL query.

This is used in a file download transaction to specify default values for the following:

The processing sequence is as follows:

void $object->initialiseFilePicker ()

This is used in a file picker transaction to specify default values for the following:

The _cm_initialiseFilePicker() method is called to perform any custom processing.

void $object->initialiseFileUpload ($where)
$where is a string in the format of a WHERE clause in an SQL query, as passed down by the previous screen.

This is used in a file upload transaction to specify default values for the following:

The _cm_initialiseFileUpload() method is called to perform any custom processing.

Once the user identifies the file to be uploaded and presses the SUBMIT button control is passed to the fileUpload() method.

$rows = $object->insertMultiple ($rows)
$rows (IN) is an indexed array containing the details of each row to be inserted.
$rows (OUT) is the same array after it has been processed, but may contain changes.

This uses data which is typically created with the getInitialDataMultiple() method.

The processing sequence is as follows:

$this->errors will contain any error messages.

$this->numrows will contain the count of inserted records.

$this->messages will contain a message in the format 'N records were inserted into TABLENAME'.

$rowdata = $object->insertRecord ($rowdata)
$rowdata (IN) is an associative array containing the details of a single row to be inserted.
$rowdata (OUT) is the same array after it has been processed, but may contain changes.

The steps in this operation are as follows:

$this->errors will contain any error messages.

$array = $object->insertOrUpdate ($array)
$array (IN) may be either an indexed array containing data for several database rows, or an associative array containing data for a single database row.
$array (OUT) is the same array after it has been processed, but may contain changes.

The steps in this operation are as follows:

$this->errors will contain any error messages.

$output = $object->outptCSV ($resource)
$resource is a database resource created by getData_serial().
$output will be a string containing all the retrieved data in CSV (comma separated values) format.

The steps in this operation are as follows:

$string = $object->outputPDF_DetailView ($resource, $structure)
$resource is a database resource created by getData_serial().
$structure is the contents of the report structure file.
$string is the PDF output if 'destination' is set to 'string'.

This method is used to produce output in PDF format (detail view). It has the following steps:

$string = $object->outputPDF_ListView ($resource, $structure)
$resource is a database resource created by getData_serial().
$structure is the contents of the report structure file.
$string is the PDF output if 'destination' is set to 'string'.

This method is used to produce output in PDF format (list view). It has the following steps:

$where = $object->popupCall ($popupname, $where, $script_vars, $fieldarray, $settings)
$popupname identifies the popup screen which is to be processed.
$where (IN) is the WHERE clause being processed by the current screen.
$script_vars is the set of variables for the current screen that will be saved in the $_SESSION array.
$fieldarray is an associative array containing the data for the current database occurrence.
$settings is a string containing optional settings for the popup screen.
$where (OUT) is the WHERE clause that will be passed to the popup screen.

If any screen contains a popup button, and the user presses this button, this method will be called to define the parameters which are to be passed to the popup form, which will then be activated. The current form will be suspended while the popup form has control, and will be automatically reactivated as soon as the popup form terminates (refer to popupReturn()).

Although a value may be brought forward in $where it may not be applicable in the popup form, so by default the output value will be empty. This behaviour may be customised in _cm_popupCall().

Currently the default value in $settings is select_one=true which will cause the SELECT column to be displayed as a radio group so that only one entry can be selected at any one time. This can be reversed by specifying select_one=false which will then cause the SELECT column to be displayed as a series of checkboxes.

$rowdata = $object->popupReturn ($rowdata, $return_from, $selection)
$rowdata (IN) is an associative array containing the current data for a database occurrence.
$return_from is the name of the popup form which has just been processed.
$selection is a string which identifies what was selected in the popup or filepicker form.
$rowdata (OUT) will contain the input array adjusted to include whatever was selected.

If any screen contains a popup button, and the user presses this button, this method will be called after the user makes a selection in the popup form and presses the CHOOSE button to return to the current form. This is so that the selected item can be merged with the existing data for the current form.

If the selection was a filename then this name will be added to $rowdata, _cm_popupReturn() will be called in case any custom processing is required, and the function will exit.

If the selection was a database occurrence then $selection will contain the primary key (which may be a compound key) of that occurrence. The selection will be passed to _cm_popupReturn() for any custom processing before it is added to $rowdata, then passed to _cm_getInitialData(), getForeignData() and _cm_post_popupReturn().

The steps in this operation are as follows:

void = $object->reset ($where)
$where is a string in the format of a WHERE clause in an SQL query.

This is used when the RESET button is pressed. This button is available in those transactions where the user can modify the selection and sorting criteria to alter how the current set of data is displayed. By pressing this button the user will remove any additional selection and sorting criteria and return the transaction to its original state. This is done by performing the following:

boolean = $object->rollback ()

If a database update fails this will rollback (undo) any changes made since the previous call to startTransaction(). Note that this has no effect on tables which do not support database transactions, such as MyISAM tables.

$array = $object->setFieldArray ($fieldarray)
$fieldarray is an array which can either contain a single associative array representing a single database row, or an indexed array of associative arrays representing several database rows.

This inserts the array into the specified object, replacing any array which currently exists.

$array = $object->setInstruction ($instruction)
$instruction is an array which identifies particular rows and the action to be taken on each of those rows.

This takes any instructions passed back by a child form which has just terminated, and loads them into $this->instruction for the current object so that they may be processed in a subsequent call to $this->_processInstruction().

$array = $object->setLookupData ($input)
$input is either an associative array, or a WHERE string which will be converted into an array.
$array will contain the input data, but as an associative array.

This is used to re-obtain any lookup data, such as will be used as the contents of any dropdown lists or radio groups.

The steps in this operation are as follows:

$childData = $object->setParentData ($parentData)
$parentData is the data from the parent object.
$childData will contain the data from the child object, possibly amended by $parent data.

This is used in tasks with the pattern ADD5 or MULTI4 where both the parent (outer) and child (inner) areas are amendable. In these cases it may be useful to have any changes in the parent object made available to the child object so that they can be incorporated into the child's data.

This is a wrapper for the _cm_setParentData() method.

$where = $object->setScrollArray ($where)
$where (IN) is a string in the format of a WHERE clause in an SQL query.
$where (OUT) will contain the primary key of the first entry in the newly-constructed array.

This is used in a MULTI1 transaction pattern to create $this->scrollarray, which is an array of primary keys for records which may or may not currently exist in the database. After the array has been created using _cm_setScrollArray() the display will start at the first occurrence, and the user will be able to step through all the occurrences using the standard scrolling mechanism. An UPDATE operation will perform an INSERT if the selected occurrence does not currently exist in the database.

boolean = $object->startTransaction ()

This will call _cm_getDatabaseLock() to issue any database locks before telling the database that a new transaction has started. This will terminate with the next commit or rollback.

$rowdata = $object->unFormatData ($rowdata)
$rowdata (IN) is an associative array containing the data from a single database occurrence.
$rowdata (OUT) will contain the input data after any reformatting has been performed.

This will take any data which has been formatted for the user, such as dates and numbers, and convert them back into internal format. For example, a date such as '02 Jan 2006' will be converted into '2006-01-02'.

It will also call _cm_unformatdata() to perform any custom unformatting.

This is the opposite of formatData().

$rows = $object->updateLinkData ($rows, $postarray)
$rows (IN) is an indexed array which contains the current data for several database occurrences.
$postarray is an array which shows which occurrences in $rows were SELECTED or NOT SELECTED.
$rows (OUT) will contain the updated data for those database occurrences.

This is used in the LINK1 transaction pattern to update the link table in a many-to-many relationship. The contents of $postarray will be processed to ensure that a database occurrence exists where SELECTED=TRUE and does not exist where SELECTED=FALSE.

The steps in this operation are as follows:

$this->errors will contain any error messages.

$rows = $object->updateMultiple ($rows, $postarray)
$rows (IN) is an indexed array containing the data for several database occurrences.
$postarray (optional) contains any changes.
$rows (OUT) will contain the updated data for those database occurrences.

The steps in this operation are as follows:

$this->errors will contain any error messages.

$this->messages will contain a message in the format 'N records were updated on TABLENAME'.

$this->numrows will contain a count of the records which were updated.

$rowdata = $object->updateRecord ($rowdata)
$rowdata (IN) is an associative array containing the data for a single database occurrence.
$rowdata (OUT) will contain the updated data for that database occurrence.

The steps in this operation are as follows:

$this->errors will contain any error messages.

$msg = $object->updateSelection ($selection, $replace)
$selection a string in the format of a WHERE clause in an SQL query.
$replace a string in the format of a SET clause in an SQL query.
$msg will contain a message in the format 'N records were updated on TABLENAME'.

This is intended to issue an SQL query in the format:

UPDATE <tablename> SET $replace WHERE $selection

The actual processing will be performed within _cm_updateSelection() to allow customisation.

$this->numrows will contain a count of the records which were updated.

$rowdata = $object->validateDelete ($rowdata, $parent_table=null)
$rowdata (IN) is an associative array containing the data for a single database occurrence.
$parent_table is empty by default, but during cascade deletes it identifies the table from which the delete has been initiated.
$rowdata (OUT) will contain the updated data for that database occurrence.

This will check that the database record identified in $rowdata can be deleted without causing problems.

The steps in this operation are as follows:

$this->errors will contain any error messages.

$postarray = $object->validateSearch ($postarray)
$postarray (IN) an associative array containing input data.
$postarray (OUT) the same array after any changes have been made.

This will the input data from a SEARCH screen to be processed before it is passed back to the previous task for use in the WHERE clause of an sql SELECT statement.

This will call _cm_validateSearch() to perform any custom processing.


Notes on Internal (private) Methods

void $PDF->detailView ($this, $resource)
$this is the database object from which this method was called.
$resource is a database resource created by getData_serial().

This method will perform the following steps:

void $PDF->listView ($this, $resource)
$this is the database object from which this method was called.
$resource is a database resource created by getData_serial().

This method will perform the following steps:

$string $PDF->output ($name, $destination)
$name is the name of the PDF file.
$destination is the place where the document will be sent.
$string will contain the output if $destination = 'S'.

If $name is empty then the output will be sent to the browser ($destination = 'I') with the name doc.pdf.

$destination can have one of the following values:

void $this->_dml_deleteRecord ($rowdata)
$rowdata is an associative array containing the data for a single database occurrence.

This will use the contents of $rowdata and the list of primary keys in the $this->fieldspec array to build a WHERE clause, then construct and execute a query in the following format:

DELETE FROM $tablename WHERE $where

If the audit flag is turned on for this table it will also write the details out to the audit database.

$count = $this->_dml_deleteSelection ($selection)
$selection is a string in the format of a WHERE clause in an SQL query, and may identify multiple database occurrences.
$count will identify how many records were actually processed.

This will construct and execute a query in the following format:

DELETE FROM $tablename WHERE $selection

If the audit flag is turned on for this table it will also write the details out to the audit database.

$rowdata = $this->_dml_fetchRow ($resource)
$resource is a database resource created by _dml_getData_serial().
$rowdata will contain an associative array of data from the next available row, or FALSE if no more rows exist.

This is used after a call to getData_serial() to return the database records one at a time.

$rows = $this->_dml_getData ($where)
$where is a string in the format of a WHERE clause in an SQL query.
$rows will contain a two-level array of retrieved data. The first level will be indexed by row number, and each row will contain an associative array of name=value pairs.

As well as using the $where string this method will also use the following optional strings:

  1. $sql_select
  2. $sql_from
  3. $sql_groupby
  4. $sql_having
  5. $sql_orderby

The first step is to construct and execute a query in the following format:

SELECT count(*) FROM $from_str $where_str $group_str $having_str

If the returned count is zero then the function immediately exits, otherwise the value is used with the $pageno and $rows_per_page variables to construct the LIMIT and OFFSET portions of the subsequent SELECT statement.

If $lock_rows is set then $lock_str will be set as follows:

A complete SQL query will be constructed from the various component parts, some of which may be NULL, as follows:

$this->query = "SELECT $select_str FROM $from_str
                       $where_str
                       $group_str 
                       $having_str
                       $sort_str 
                       $limit_str 
                       $lock_str"
if (!$result = <DBMS>_query($this->query)) {
    trigger_error($this, E_USER_ERROR);
} // if     

If you wish to view the SQL statements that are constructed and issued take a look at $GLOBALS['log_sql_query'].

All resulting data will be converted into a two-level array - the first level will be indexed by row number, and each row will contain an associative array of name=value pairs. All column names will be converted into lower case. This is done using code similar to the following:

$array = array();
while ($row = DBMS_fetch_assoc($result)) {
    $array[] = array_change_key_case($row, CASE_LOWER);
} // while
return $array;
$resource = $this->_dml_getData_serial ($where)
$where is a string in the format of the WHERE clause in an SQL query.
$resource will be a database resource which can be used to access all the retrieved rows.

This is similar to _dml_getData(), but instead of returning an array of occurrences it returns a resource from which individual occurrences can be obtained using fetchRow().

$rowdata = $this->_dml_insertRecord ($rowdata)
$rowdata (IN) is an associative array containing the data for a single database occurrence which is be be inserted.
$rowdata (OUT) is the same data after it has been inserted, which may now include any auto-generated values.

This will remove any field from the array which does not exist in the table, such as the SUBMIT button which exists in the $_POST array created by the web server.

If any field has the autoinsert option set it will insert a value according to the data type:

If any field in the primary key has the auto_increment option set then ensure that is has no value in $rowdata otherwise no new value will be generated. If there is no auto_increment option then perform a lookup with the supplied primary key to see if a duplicate record already exists. If it does then generate an error message and terminate the insert.

If the table contains any candidate (unique) keys then perform a lookup on each one to check for duplicates. If any is found then generate an error message and terminate the insert.

It will then construct and execute a query in the following format:

INSERT INTO $tablename SET field1='value1', field2='value2',...

If any field in the primary key has the auto_increment option set then obtain the value which has just been generated and insert it into the output array.

If the audit flag is turned on for this table it will also write the details out to the audit database.

$rowdata = $this->_dml_ReadBeforeUpdate ($where, $reuse_previous_select)
$where is a string in the format of the WHERE clause of an SQL query.
$reuse_previous_select is boolean, taken from $this->reuse_previous_select.
$rowdata will contain a two-level array of retrieved occurrences - the first is indexed by row number, and each row will contain an associative array of name=value pairs.

If $reuse_previous_select is FALSE (the default setting) this will construct and execute a query in the following format:

SELECT * FROM $tablename WHERE $where FOR UPDATE

If $reuse_previous_select is TRUE this will construct and execute a query using the current contents of $this->sql_select, $this->sql_from, et cetera. This is for those cases where the current SELECT statement contains a field from a JOINed table, and this field must be included in the re-read so that it is available in the $originaldata arguments of the _cm_commonValidation() and _cm_validateUpdate() methods.

This read is done for the following reasons:

In theory the contents of $where should identify the primary key of an existing occurrence, therefore $rowdata should contain no more than one record. If $fieldarray contains a field called 'rdcversion' (Radicore Version Number) then this will be included in the $where string. This special field (an INTEGER with AUTO-UPDATE set) will be incremented with each update, so can be used to prevent simultaneous updates of the same record. Please refer to FAQ 70 for more details.

$rowdata = $this->_dml_updateRecord ($updatearray, $originaldata)
$updatearray contains an associative array of updated details for a single database occurrence.
$originaldata contains an associative array of original details for the same database occurrence, as provided by _dml_ReadBeforeUpdate().
$rowdata will contain the data after it has been updated.

This will remove any field from the array which does not exist in the table, such as the SUBMIT button which exists in the $_POST array created by the web server.

If any field has the autoupdate option set it will insert a value according to the data type:

This will use the contents of $updatearray and the list of candidate keys in the $this->fieldspec array to perform a lookup to check for duplicates. If any is found then it will generate an error message and terminate the update.

This will use the contents of $updatearray and the list of primary keys in the $this->fieldspec array to build a WHERE clause, then construct and execute a query in the following format:

UPDATE $tablename SET field1='value1', field2='value2',... WHERE $where
$count = $this->_dml_updateSelection ($selection, $replace)
$selection is a string in the format of a WHERE clause in an SQL query, and may identify multiple database occurrences.
$replace is a string in the format of a SET clause in an sql UPDATE statement.
$count will identify the number of records which were processed.

This will construct and execute a query in the following format:

UPDATE $tablename SET $replace WHERE $selection
$errors = $this->_examineWorkflow ($input)
$input may be an associative array containing the details of a single database occurrence, or a WHERE string which will be converted into an associative array.
$errors will contain an array of error messages, and will be empty if no errors are detected.

This is performed whenever a task (user transaction) completes successfully in order to find out one of the following:

For further details please consult An activity based Workflow Engine for PHP.

$fieldarray = $this->_getInitialValues ()
$fieldarray is an associative array of name=value pairs.

This function will look for records on the INITIAL_VALUE_USER table using the current task and user identity. If none are found it will look on the INITIAL_VALUE_ROLE table using the current task and role identity. These records provide initial values for fields within the current task.

If any are found the details are added to $fieldarray. This is loaded into $this->initial_values during the initialise() method, and how it is handled after that depends on the behaviour of the current task:

$where = $this->_getInitialWhere ($where)
$where (IN) is a string in the form of a WHERE clause in an SQL query.
$where (OUT) is the input string after it has been amended.

This will turn the $where string into an array, merge it with the contents of $this->initial_values (without overwriting any non-null values), then convert the result back into a string.

void $this->_examineWorkflowInstance ($where)
$where is a string in the format of the WHERE clause in an SQL query, and should contain the primary key of a single database occurrence.

This is performed at the start of a task (user transaction) to find out if it is a workitem within a workflow instance. If it is it will perform the following:

For further details please consult An activity based Workflow Engine for PHP.

$rows = $this->_processInstruction ($rows)
$rowdata (IN) is an indexed array containing the data for a number of database occurrences.
$rowdata (OUT) is the same array after any modifications have been made.

This looks for any instructions set by the previous task and adjusts the current set of data accordingly. At present the only instructions available are:

  1. The setting of the SELECT checkbox in a LIST or TREE VIEW screen.
  2. The expanding of a node in a TREE VIEW screen.

For examples of how to set values please refer to $this->instruction.

$where = $this->_sqlAssembleWhere ($where, $where_array)
$where (IN) is a string in the format of the WHERE clause in an SQL query.
$where_array is the same as $where (IN) but in the form of an associative array.
$where (OUT) will be a string containing any adjustments.

This will also use the following class variables:

This will look at the various components that will be used in the construction of the sql SELECT statement to see if they need adjustment, as follows:

$where = $this->_sqlAssembleWhereLink ($where, $where_array)
$where (IN) is a string in the format of the WHERE clause in an SQL query.
$where_array is the same as $where (IN) but in the form of an associative array.
$where (OUT) will be a string containing any adjustments.

In a LINK1 transaction three table names are provided:

  1. OUTER - from which a single occurrence will be read using the primary key passed down from the previous transaction.
  2. INNER - from which all occurrences will be read.
  3. LINK - which lies between the OUTER and INNER tables.

This information will be used to construct an sql SELECT statement similar to the following:

SELECT outer.outer_id, inner.inner_id, inner_desc, 
       CASE WHEN link.inner_id IS NULL THEN 'F' ELSE 'T' END AS selected
FROM outer 
CROSS JOIN inner 
LEFT JOIN link ON (outer.outer_id=link.outer_id AND inner.inner_id=link.inner_id)
WHERE outer.outer_id='x' 
[AND link.inner_id IS NULL/IS NOT NULL]
$sql_from = $this->_sqlForeignJoin (&$sql_select, $sql_from, $parent_relations)
$sql_select (IN) is a list of field names in the same format as the SELECT clause in an sql query.
$sql_from (IN) is a list of table names in the same format as the FROM clause in an sql query.
$parent_relations is an array from $parent_relations.
$sql_select (OUT) will contain any amendments.
$sql_from (OUT) will contain any amendments.

This will use the information contained in $parent_relations to amend the contents of $sql_select and $sql_from. The processing sequence is as follows:

For more details please refer to Using Paren