﻿RADICORE for PHP - news

2024-05-11, version 2.28.1-patch
Database changes:
- none

Other changes:
- fixes bug in TCPDF library reported in https://forum.radicore.org/index.php?t=msg&th=3529
- fixes deprecation notices in TCPDF library caused by optional arguments followed by required arguments.


2024-05-01, version 2.28.0
Database changes:
- none

Other changes:
- upgraded TCPDF library to version 6.3.2
- updated numerous classes to replace call to getFieldSpec_original(), which has been deprecated, to call loadFieldSpec() instead.
- fixed bug in std.filepicker1.inc to deal with undefined variable $search, and to deal with the ‘previous search’ button.
- fixed bug in std.multi4.inc where it reset the value of $inner_where incorrectly.
- fixed bug in std.pdf.class.inc to make FAQ134 work correctly.
- fixed bug in std.search1.inc which incorrectly removed a field from $fieldarray.
- fixed bug in convertTimeZone() method within std.table.class.inc.
- fixed bug in formatData() method within std.table.class.inc which failed to call convertTZ function because $errors was not empty.
- fixed bug in getData() method within std.table.class.inc to exit if call to _cm_post_getData() raised an error.
- fixed bug in getEmailParams() method within std.table.class.inc which failed to set ‘email_from’ address and ‘email_to’ address.
- updated getPickerDir() method within std.table.class.inc to add an optional $search argument.
- updated getWhere() method within std.table.class.inc to call $this->getPkeyNamesAdjusted() instead of $this->getPkeyNames().
- fixed bug in initialiseFilePicker() method within std.table.class.inc to set the quicksearch bar in the correct place.
- fixed bug in std.update1.inc to ignore any previous messages after performing an update.
- updated std.validation.class.inc so that if a numeric value is entered in a dropdown control which is defined as 'string' it will be treated as blank. This is to deal with FAQ181.

2023-10-14, version 2.27.0
Database changes:
- none

Other changes:
- added optional constant ERROR_LOG_MAILFROM to config.inc file.
- updated error.inc so that the ‘from’ address for any emails will be set to ERROR_LOG_MAILFROM (if present) in the config.inc file instead of the default address of ‘webmaster@{$_SERVER['HTTP_HOST']}’
- updated error.inc so that if a call to fread or fwrite generates a warning containing ‘fail’ or ‘abort’ it will be converted into an error.
- updated include.library.inc to set the 2nd argument of the call to http_build_query() to an empty string instead of null.
- updated include.library.inc to add more error checking in the ‘getForeignKeyValues()’ function.
- updated include.library.inc to add an optional 4th argument to the ‘getPostArray()’ function.
- updated include.library.inc to make the ‘html2text()’ function more effective.
- updated include.library.inc to include a new ‘reduceHyperlinks()’ function to convert hyperlinks into plain text.
- updated include.library.inc to allow the $extra_headers argument on the ‘send_email()’ function to be either an array or a sting.
- updated include.session.inc to set SKIP_CSRF_CHECK to false in an earlier place if it is not currently defined.
- updated include.session.inc to skip the check for an AWS load balancer if the current script is running via the command line.
- updated include.session.inc to include correct validation for the SSO (Single Sign On) option.
- updated include.session.inc so that the ‘runInBackground()’ function will fail with a suitale error message if headers have already been sent.
- updated include.swiftmailer.inc (deprecated) so that an HTML mail is sent correctly with a separate version in plain text.
- updated include.symfony_mailer.inc to fix bug in handling of replyTo/cc/bcc addresses.
- updated include.xml.php5.inc to include the ability of adding the zone identity to column names in those screens which deal with more than one entity and the same column name is used in more than one entity in order to keep their values separate.
- updated include.xml.php5.inc to deal with NULL values in function arguments which were deprecated in PHP 8.1.
- updated language_detection.inc to deal with NULL values in function arguments which were deprecated in PHP 8.1.
- updated output4_header.class.inc to allow the ‘selected’ field to be specified as ‘select’.
- updated std.add1.inc so that if the ‘submitStay’ button was pressed it restarts the current task properly.
- updated std.add5/6/7.inc to fix bugs with the calls to getPostArray() and updateFieldArray().
- added std.control_record.class which should be inherited by classes used in UPDATE3 tasks as this contains the default processing. Tis replaces the need to inherit from mnu_control.class.inc.
- updated std.currency.class.inc to deal with NULL values in function arguments which were deprecated in PHP 8.1.
- updated std.encryption.class.inc to deal with NULL values in function arguments which were deprecated in PHP 8.1.
- updated std.filepicker1.inc to fix bug when changing the ‘orderby’ value in the screen.
- updated std.list2.inc to set the correct value in the $where string when returning to a search screen.
- updated std.multi2/3/4/5/6.inc to add missing zone identity on the call to getPostArray()
- updated std.output3.inc to set $batch_errors[‘where’] to the correct value.
- updated std.output4.inc to move he call to $dbinner->setAction() to a better place.
- updated std.pdf.class.inc to deal with NULL values in function arguments which were deprecated in PHP 8.1.
- updated std.table.class.inc to deal with NULL values in function arguments which were deprecated in PHP 8.1.
- updated std.table.class.inc so that the insertMultiple() method will ignore any record which has ‘rdc_to_be_ignored’ set.
- updated std.table.class.inc so that the popupReturn() method can deal properly with a $selection arument which contains the keys for multiple selections as well as a single selection.
- updated std.table.class.inc so that the updateFieldArray() function includes an extra argument which identifies the object’s zone.

2023-04-04, version 2.26.0
Database changes:
- added column ‘task_id_quicknav’ to MNU_TASK table. Please run script menu\sql\mysql\alter_table(2023-01-14).sql to update the MENU database.

Other changes:
- made changes to various scripts to convert NULL to an empty string before calling any function that requires a string.
- updated mnu_control.class.inc to tighten rules regarding switching password encryption ON and OFF and changing the authentication method.
- updated mnu_user.class.inc to prevent switching password encryption between ON and OFF when the authentication method is not INTERNAL or SSL.
- fixed bug in mnu_saved_selection.class.inc which failed to update is_selected in mnu_saved_selection_data table.
- fixed bug in custom_pre_eraseRecord() method of std.table.class.inc which failed to call _cm_pre_eraseRecord() method if there were no errors.
- fixed bug in std.update3.inc which failed to deal with changes made to $fieldarray during validation process.

2023-02-04, version 2.25.0
Database changes:
- run script menu\sql\mysql\alter_table(2023-01-14).sql to alter the structure of the MENU database
- run script menu\sql\mysql\menu.menu_export(2023-02-03).sql to alter the contents of the MENU database

Other changes:
- added column task_id_quicknav to the MNU_TASK table in order to provide a Quick navigation button on LIST screens.
- modified std.data_field.xsl to allow the quicknav button to be displayed as an image.
- fixed bug in mnu_user.class.inc which failed to set the password length to 255 when authorisation is set to ‘SSL’.
- updated numerous scripts to remove deprecation notices generated by PHP 8.2

2023-01-01, version 2.24.0
Database changes:
- none

Other changes:
- fixed bug in 'include.library.inc' which failed to deal correctly with bitwise operators in the $where string.
- fixed bug in ‘include.library.inc’ where the function ‘where2indexedArray()’ failed to deal with a value containing ‘-’ (hyphen).
- Modified 'std.update3.inc' to include a SUBMITstay button in the action bar. 
- Modified Menu Control Data to allow the password length to be to be changed to a value up to 40 characters.
- Modified Menu Control data to allow the number of special (non-alphanumeric) charactersto be defined for new passwords.
- Modified Menu Control Data to allow the format of the salt used for password encryption to be varied. 
- Modified Menu Control Data to add SSL encryption as an authentication type, along with a variable cipher method.
- Added Symfony Mailer as an option for sending emails, to replace SwiftMailer which is no longer supported.
- fixed bug in audit_tbl_s01.class.inc which failed to deal correctly with the passed WHERE string.
- updated dict_table_s02.class.inc to include ‘nameof_extra_names_db/tbl’ and ‘nameof_extra_values_db/tbl’ when exporting data to ‘<table>.dict.inc’ file.
- fixed bug in ‘std.add5/6/7.inc’, ‘std.link1.inc’, std.multi2/3/4/5/6.inc’ where a custom button in one zone caused an update in an inner zone.
- updated ‘include.session.inc’ so that ‘initsession()’ function uses $GLOBALS['use_https'] to set use of HTTPS to either ON or OFF.
- fixed bug in ‘std.validation.class.inc’ so that ‘validateField()’ method excludes the econds prtion of a time field when the size is set to 5 characters.
- updated ‘std.pdf.class.inc’ so that it calls ‘$dbobject->changeConfig()’ to perform any configuration changes before producing any output.
- updated ‘std.csv.class.inc’ so that it calls ‘$dbobject->changeConfig()’ to perform any configuration changes before producing any output.

2022-11-01, version 2.23.0
Database changes:
- amended the DICT database to add new columns to the ‘dict_table’ table. Please run script dict\sql\mysql\alter_table(2022-08-11).sql to implement these changes.

Other changes:
- modified ‘audit_ssn_s01.class.inc’ in the AUDIT subsystem to correct the way in which the time period is reported in the log file.
- updated ‘audit_tbl.class.inc’ so that any dates and times entered in the search screen are converted from the user’s timezone to the server timezone before the database lookup.
- modified the DICT subsystem to add new columns to the ‘dict_table.class.inc’ and ‘dict_table.detail.screen.inc’.
- updated ‘std.table.class.inc’ to fix bug in the custom_initialise() method where the 2nd argument should be passed by reference.
- updated ’std.table.class.inc’ to fix bug in getColumnNames() method where it reset $this->fieldspec in the wrong place.
- updated ‘std.table.class.inc’ to move some code in the getExtraData() method to a separate method.
- updated ‘std.table.class.inc’ so that the _cm_getForeignKeyValues() method is called on the child object with the parent object as an argument instead of being called on the parent object with the child object as an argument.
- updated ‘std.table.class.inc’ so that the getInitialData() method will not ignore entries in $this->fieldspec if both the ‘nondb’ and ‘mustvalidate’ attributes are set.
- updated ‘std.table.class.inc’ so that the getOrderBySeq() and setOrderBy() methods work more accurately.
- updated ‘std.table.class.inc’ to remove the call to the setJavaScript() method. This has been moved to ‘include.xml.php5.inc’.
- updated ‘std.table.class.inc’ so that the insertRecord() and updateRecord() methods deal properly with fields which have the ‘nondb’ attribute set in $this->fieldspec.
- updated ‘std.table.class.inc’ so that the loadFieldSpec() method deals with the new data which is available in the ‘<table>.dict.inc’ file.
- updated ‘std.table.class.inc’ so that the popupReturn() method will initialise any fields to be returned from parent table.
- updated ‘std.table.class.inc’ so that the set_column_scale() method will set the scale of the functional currency to the correct value.
- updated ‘std.table.class.inc’ so that the setJavaScript() method will return an empty array instead of NULL.
- updated ’std.table.class.inc’ so that the sqlSelectInit() method will deal properly with any SQL variables passed into scripts using the LINK1 pattern.
- updated ‘std.table.class.inc’ so that the _sqlAssembleWhere() method will call the selectAllColumns() method using the $fieldspec array from the correct object.
- updated ‘std.search1.inc’ to remove a redundant call to the getExtraDataMethod().
- updated ‘include.library.inc’ so that the extractOperatorValue() function will return the default values for $operator and $delimiter if none are found in the input string.
- updated ‘include.library.inc’ so that the getForeignKeyValues() function will call the getForeignKeyValues() method on the cgild object instead of the parent object.
- updated ‘include.library.inc’ to include a function called round_up() which can be used to round ndecimal numbers UP instead of DOWN with the standard PHP round() function.
- updated ‘include.library.inc’ so that the selectAllColumns() function will work properly if the subject table has been given an alias name in the SELECT list.
- updated ‘include.library.inc’ so that the splitNameOperatorValue() function will detect and deal with more regex patterns.
- updated ‘include.library.inc’ so that the splitWhereByRow() function will detect and deal with more regex patterns.
- updated ‘include.xml.php5.inc’ so that the addData2XMLdoc() method calls $dbobject->setJavaScript().
- updated ‘include.xml.php5.inc’ so that the addData2XMLdoc() method will not call $dbobject->formatData() if the pattern is ‘OUTPUT4’.
- updAted ‘std.multi4.inc’ so that if $return_from is not empty it will set $dbouter->skip_getdata to TRUE.
- updated ‘dml.mysqli/oracle/pgsql/sqlsrv.class.inc’ to add the $tablename argument to the adjust_derived_query() method.
- updated ‘dml.mysqli/oracle/pgsql/sqlsrv.class.inc’ to set $sort_str to the correct value before performing a SELECT query.
- updated ‘include.session.inc’ to output the correct error message if the unserialize of the session data obtained from the database fails.
- updated ‘output4.header.class.inc’ tests the corect variable $before setting rowdata[’selected’] to the relevant value.
- updated ‘std.link1.inc’ so that it calls the initialise() method on the $dblink object.
- updated ‘std.output4.inc’ so that it does not reset $dbinner->fieldspec.
- updated ‘std.list2.inc’ so that when used in a POPUP2 task and returning from a POPUP1 task in which ‘choosenull’ was selected it will stop processing the current POPUP2 task and return to the previous task instead.
- updated ‘std.currency.class.inc’ so that it will not replace a zero value with blanks.
- updated ‘std.update1.inc’ so that it will call $dbobject->setPageNo() with the correct value before calling $dbobject->getData().
- updated ‘std.add1/2/5/6/7.inc’ to ensure that a call to $dbobject->getExtraData() is made after the $_POST array has been processed.

2022-07-01, version 2.22.0
Database changes:
- none

Other changes:
- amended all database classes (dml.???.class.inc) to include the ability to work with non-recursive Common Table Expressions (CTE) with any number of expressions.
- amended ‘std.table.class.inc’ and 'include.library.inc' to deal will some of the options presented with having multiple non-recursive CTEs.
- fixed bug in ‘std.multi4.inc’ which disabled the scrolling through multiple rows of the outer entity after the first row was displayed.

2022-06-07, version 2.21.0
Database changes:
- none

Other changes:
- checked that code will run in PHP 8 without any errors.
- updated xsl/std.list1.xsl to set the “multiple” argument when calling the “display_horizontal” template. This was to fix a small bug.
- fixed bug in audit_tbl_s01.class.inc which caused task audit_dtl(list)3 to misbehave if the $where string was empty and the $parent_data variable contained columns with null values.
- updated dict_database_s02.class.inc to set the SVN variables to empty when exporting the database details.
- updated dict_table_s02.class.inc to set the SVN variables to empty when exporting a table’s structure file.
- updated wf_workitem.class.inc to include transition_name in the SELECT list.
- modified logon.php, logon.class.inc and mnu_user.class.inc to check for usage of Amazon Web Services Application Load Balancer (AWSALB).
- modified dml.???.class.inc to convert sort string from literal ‘NULL’ to actual NULL. This will prevent an empty $orderby string from being set to the primary key by default.
- modified function 'append2ScriptSequence' in include.library.inc to remove check for duplicate task_id as the same task could be used on different records.
- modified function ‘array_update_associative’ in include.library.inc to error if $array1 is not associative and the $object->rows_per_page != 1.
- modified function ‘array_update_associative’ in include.library.inc to set a blank date to ‘9999-12-31’ if that field has ‘infinityisnull’ set to ‘y’.
- modified function ‘convertTZdate’ in include.library.inc to convert an empty time to ‘12:00:00’ instead of ‘00:00:00’.
- added function ‘getParentKeyValues’ to include.library.inc to return the primary key for $parentOBJ.
- modified function ‘logstuff’ in include.library.inc to include an extra $force argument which will force the input to be logged even if the constant LOGSTUFF has not been set.
- modified function ‘number_unformat’ in include.library.inc to trim() the input before it is processed.
- modified function ‘send_email’ in include.library.inc so that if the SWIFTMAILER option is being used it will deal properly with any Cc or Bcc values if they are supplied.
- modified function ‘splitWhereByRow’ in include.library.inc to return immediately if the input has already been converted into an array, and to add a 4th regex pattern.
- modified function ‘unqualifyWhere’ in include.library.inc to ignore any field value which is enclosed in quotes.
- modified function ‘where2array’ in include.library.inc so that if the input string starts with ‘(’ and ends with ‘)’ with no embedded ‘(’ or ‘)’ characters then the start and end characters will be removed.
- modified function ‘where2indexedArray’ in include.library.inc to include an extra regex pattern for ‘function() [NOT] IN ...’.
- modified function ‘chooseButton’ in include.session.inc so that if multiple rows were selected then they are returned as an array of primary keys instead of a string containing a single primary key.
- modified function ‘initSession’ in include.session.inc to ignore any CSRF checking if the QUIT button has been pressed.
- modified function ‘initSession’ in include.session.inc so that if $_SESSION[‘awsalb’] it will instantiate awsalb_class.class.inc and call the verifyToken method to validate the passed credentials.
- modified function ‘createXMLdoc’ in include.xml.php5.inc to remove the default ‘root’ from the $root_name argument.
- modified ’std.add1.inc’ to replace two calls to $dbobject->errors with just one.
- modified ’std.add2.inc’ to replace two calls to $dbobject->errors with just one.
- modified ’std.add4.inc’ to allow it to be run from the command line.
- modified ‘std.curl.class.inc’ so that CURLOPT_HEADER is only set if the $curlopt_header argument is not empty.
- modified ‘std.curl.class.inc’ so that it checks the $error_no variable instead of $err.
- modified ‘std.list1.inc’ so that it returns $dbobject->sql_where instead of $sql_where if no entries are found after processing the criteria from a search screen.
- modified ’std.multi1.inc’ to replace two calls to $dbobject->errors with just one.
- modified ‘std.multi4.inc’ to call $dbouter->getFieldArray() after call to $dbinner->getExtraData() in case $dbinner->getExtraData() contained a call to ->setParentData().
- modified ‘std.output4.inc’ so that each call to $dbinner->validateUpdate() includes the current $rownum.
- modified ‘std.search1.inc’ so that it only ignores a field with the ‘noedit’ attribute set if the ‘control’ attribute is not set to ‘hidden’.
- updated the ‘array_update_associative’ method in ‘std.table.class.inc’ so that the call to $this->custom_pre_array_UpdateAssociative() is made before the call to $this->convertTimeZone() instead of after.
- updated ‘std.table.class.inc’ so that the ‘custom_pre_arrayUpdateAssociative()’ and ‘_cm_pre_array_update_associative()’ methods pass the $postarray argument by reference so that it may be updated.
- fixed bug in the ‘custom_adjustColumnNames’ method in ‘std.table.class.inc’ so that it uses the variable $column_names instead of $columnnames.
- updated ‘std.table.class.inc’ so that the ‘deleteRecord()’, ‘validateDelete()’, ‘insertMultiple()’, ‘insertRecord()’, ’updateMultiple() and ‘updateRecord()’ methods will use $fieldarray['rdc_skip_validation'] as well as $this->skip_validation to skip over any validation routines.
- updated ‘std.table.class.inc’ to include calls to ‘_cm_pre_deleteSelection()’ and ’_cm_post_deleteSelection()’ within the ’deleteSelection’ method.
- updated ‘std.table.class.inc’ to include a call to ‘_cm_pre_formatData()’ within the ‘formatData()’ method. This will be called before the standard formatting and the call to ‘_cm_formatData()’.
- updated ‘std.table.class.inc’ so that the call to ’getData()’ returns an empty array instead of nothing if the call to isPkeyComplete() detects an error.
- updated ‘std.table.class.inc’ so that the call to ’getInitialData()' will leave a field alone if it is currently a non-empty array.
- updated ‘std.table.class.inc’ so that the ‘getOrderBy()’ method will set $orderby to the literal ‘NULL’ if it is not empty but contains only spaces. This will be converted to actual NULL in the relevant database object.
- updated ‘std.table.class.inc’ so that the ‘getWhere()’ method will copy the $offset argument to $this->offset so that it is available in calls to subsequent methods.
- updated ‘std.table.class.inc’ to create a new ‘loadFieldSpec()’ method which is an alias for ‘getFieldSpec_original()’.
- updated ‘std.table.class.inc’ so that the ‘popupReturn()’ method will convert the string $selection argument into an array of strings indexed by row number. If it is an associative array it will turn it into an indexed array for row number zero. This will enable the receiving task to deal consistently with the selection from a popup screen regardless of whether it was a single row or multiple rows.
- updated ‘std.table.class.inc’ so that when the RESET button is pressed the ‘sqlSelectInit()’ method will set the $object->sql_* variables to their correct initial values instead of NULL.
- updated ‘std.table.class.inc’ so that the ‘updateFieldArray()’ method does not call the ‘array_update_associative()’ function more than once.
- updated ‘std.table.class.inc’ so that the ‘updateSelection()’ method will convert an array which is indexed by row number into a single string.
- updated ‘std.table.class.inc’ so that the ‘validateUpdate()’ method will function correctly if the $fieldarray argument indicates a row in an object which contains multiple rows.
- updated ‘std.table.class.inc’ to allow the ‘_cm_deleteSelection()’ method to either delete the selected records (which is the default operation) or to nullify the foreign key fields in the selected rows.
- updated ‘std.table.class.inc’ so that the ‘deleteSelection()’ method will call new methods called ‘_cm_pre_deleteSelection()’ and ‘_cm_post_deleteSelection()’.
- updated ‘std.table.class.inc’ so that the ‘_sqlAssembleWhere()’ method will not attempt to modify the $object->sql_select string if $object->temporary_table is set.
- updated ‘std.table.class.inc’ so that the ‘_sqlForeignJoin()’ method will not add another JOIN to the current query if the count of JOINs goes over 50 as this will overflow the limit in the RDBMS. Any missing JOINs will be handled separately in the getForeignData() method.

2021-09-01, version 2.20.0
Database changes:
- none

Other changes:
- fixed bug in audit_table.s01.class.inc so that when used as the middle table in a LIST3 screen it will allow the $where string to be empty.
- updated various classes which create output files to include the SVN keywords $Date: 2024-05-01 16:20:01 +0100 (Wed, 01 May 2024) $, $Author: tony $ and $Revision: 49 $ which will be updated with current values whenever the file is subject to a Subversion COMMIT operation:
-- dict_database_s02.class.inc (which produces sql/<database>.dict_export.sql)
-- dict_table_s02.class.in (which produces classes/<table>.class.inc and classes/<table>.dict.inc)
-- dict_table_s04.class.inc (which produces <table>(<pattern>).php)
-- mnu_subsystem_s01.class.inc (which produces text/<subsys>.menu_export.txt and sql/<subsys>.menu_export.sql)
- updated logon.class.inc so that if $_SESSION[‘timezone_server’] is set but $_SESSION[‘timezone_client’] is not it will set $_SESSION['timezone_client'] to the default value of ‘UTC’.
- updated mnu_motd.class.inc to add missing 3rd argument to method _cm_validateDelete().
- updated mnu_user_role.class.inc to add missing 3rd argument to method _cm_validateDelete().
- updated wf_place.class.inc to add missing 3rd argument to method _cm_validateDelete().
- updated error.inc so that includes any output from libxml_get_errors().
- updated dml.mysqli/pgsql/oracle/sqlsrv.class.inc so that the insertRecord() method will process the ‘autoinsert’ keyword if a field’s value is currently set to its default value as defined in the $fieldspec array.
- updated include.library.inc so that append2ScriptSequence() will not add $task_id to $_SESSION['script_sequence']) if it is already there.
- updated include.library.inc so that filterWhere1Where2() will take into account any leading or trailing spaces when comparing two values.
- updated include.library.inc to fix bug in getPostArray() which ignored a field’s value if it was an array and the $multiple argument was FALSE.
- updated include.library.inc so that qualifyOrderby() does not qualify a column name with its table name if the $sql_from string does not reference more than one table.
- updated include.library.inc so that qualifyWhere() will not try to qualify the contents of an expression if it is enclosed in ‘(’ and ‘)’ and there are no intervening ‘(’ or ‘)’ characters.
- updated include.library.inc to include a new function rebuildSelectString().
- updated include.library.inc to include a new function removeEmailSubFolder().
- updated include.library.inc to add an extra regex pattern to splitWhereByRow().
- updated include.library.inc to fix bug in where2indexedArray().
- updated include.session.inc so that if constant SKIP_CSRF_CHECK is TRUE then it will skip all CSRF checking.
- updated std.validation.class.inc so that the arguments on the implode() function are set in the correct order for PHP 8.
- updated std.validation.class.inc to prevent a primary or unique key from containing either a single or double quote.
- fixed bug in include.xml.php5.inc which sometimes failed to set the ‘checkbox_multi’ attribute which caused that field to be displayed incorrectly.
- updated std.table.class.inc to fix wrong spelling of the 2nd argument on the call to the _cm_convertSearchExpression() method.
- updated std.table.class.inc so that the format() method will not set a date or datetime field to NULL if it contains an invalid date so that it will still be visible on the screen alonmg with the error message.
- updated std.table.class.inc to include new method loadFieldSpec() which will act as an alias for getFieldSpec_original().
- updated std.table.class.inc so that the initialise() method will not call selection2PKeyOnly() if $settings[‘pkeyonly’] is set to ‘N’.
- updated std.table.class.inc so that if the insertRecord() method finds a non-empty field which has the ‘autoinsert’ or ‘autoupdate’ propert set and which has a ‘default’ value defined then it will be set to that default value.
- updated std.table.class.inc so that the insertRecord() method will finish by setting $this->dbchanges to the array of values which have just been inserted.
- updated std.table.class.inc so that if the validateDelete() method reads multiple rows from a child table then it will include the row number on each call to the _cm_validateDelete() method.
- updated std.table.class.inc to add a 3rd argument called $rownum to the _cm_validateDelete() method.
- updated std.table.class.inc so that the _sqlAssembleWhere() method so that after replacing the ‘*’ character in the $this->sql_select string with a list of column names it will remove any which have been specified in the $this->drop_from_sql_select array.
- updated std.table.class.inc to fix a bug in the _sqlProcessJoin() method.
- updated tasks which produce PDF or CSV output so that instead of displaying the output at the end of that task it is passed back to the calling task instead so that it can be displayed after the output task has terminated. This is because if the output is displayed in the task in which it is generated that task cannot then exit and return control to the calling task as headers have alreay been sent. This makes the framework believe that the output task is still active even though the screen that is deing displayed is that of the calling screen at the point when the navigation button for the output task was pressed.
-- updated the relevant std.outputX.inc tasks to load the output into a variable called $script_vars[‘output_buffer’] instead of displaying it so it can exit.
-- updated include.session.inc so that the initSession() function can detect that the $script_vars[‘output_buffer’] variable is not empty, which is then displayed instead of that task’s own screen.
-- updated all the page controllers which produce HTML output to not do so if the contents of $script_vars[‘output_buffer’]  was displayed instead.

2021-06-01, version 2.19.0
Database changes:
- none

Other changes:
- updated all dml.???.class.inc files to deal with derived tables as discussed in http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq179
- updated the getForeignKeyValues() function to call the getForeignKeyValues() method which in turn calls the _cm_getForeignKeyValues() hook method as explained in http://www.tonymarston.net/php-mysql/functions-and-variables.html#notes._cm_getforeignkeyvalues
- updated the clearEditableData() method so that it calls the _cm_clearEditableData() hook method. This is used is search screens when the CLEAR button is pressed.
- updated std.table.class.inc to fix a bug in the convertTimeZone() method.
- updated std.table.class.inc so that the formatData() method deals with values ‘IS NULL’ and ‘IS NOT NULL’ in search screens.
- updated std.table.class.inc so the the getOrderBy() does not prefix column names with table names when either a CTE or  derived table is being used.
- updated std.table.class.inc to fix a bug in the getWhere() method which was triggered from a zone containg multiple rows.
- updated std.table.class.inc to move code from the initialise() method to a new initialiseSearch() method.
- updated std.search1.inc so that it calls the new initialiseSearch() method.
- updated std.table.class.inc so that the popupReturn() method so that $select_array will be correctly set to either an associative array or an indexed array of associative arrays depended on how many rows were selected.
- updated std.table.class.inc so the the scriptNext() and scriptPrevious() methods will save and restore the current value for $GLOBALS['transaction_has_started'].
- updated std.table.class.inc so that the setOrderBy() method inserts the correct value into $this->sql_orderby_seq.
- updated std.table.class.inc to automatically set $this->reuse_previous_select to TRUE if $this->sql_select is not empty or FALSE if it is.
- updated std.table.class.inc to fix a bug in the _dml_ReadBeforeUpdate() method.
- updated std.output4.inc so that it contains the ‘select all’ and ‘unselect all’ links.
- updated std.filepicker.inc to set the $rows_per_page value to 50 instead of 100.
- updated various std.<pattern>.inc scripts to fix small bugs or remove redundant code.
- updated std.pdf.class.inc so that the outputPDF_DetailView() method does not performa COMMIT if $this->errors is not empty.
- updated std.validation.class.inc to ignore ‘size’ attribute on boolean data types, and to set correct values for ‘true’ and ‘false’ attributes if the ‘optionlist’ is set to either ‘boolean_YN’, ‘boolean_TF’ or ‘boolean_10’.
- updated std.session.inc to fix bug with $_POST[‘select’] in transaction patterns other than SEARCH.
- updated std.session.inc so that the initSession() function will properly report when reading the session data fails beacuse of an error when it is being unserialised.
- updated include.xml.php5.inc so that if $fieldarray from any object contains an entry with an empty key it will not write it out to the XML document as this will cause an error.
- update include.xml.php5.inc so that it will perform array_unique() on the $messages array to remove any duplicate entries.
- updated std.datevalidation.class.inc so that the getInternalDateTime() method will use the value in $this->date_format_input if the value in $fieldspec[‘date_format’] is empty. 
- updated std.datevalidation.class.inc so that the getInternalDateTime() method can deal better with different date formats.
- updated include.library.inc so that the array_remove_nulls() function can also deal with the string value ‘IS NULL’.
- updated include.library.inc to improve the qualifyOrderBy() and unqualifyOrderBy() functions.
- updated include.library.inc to improve the qualifyWhere() function.
- updated include.library.inc so that the send_email() function will set the ‘from’ address to either GLOBALS['MAIL_FROM_OVERRIDE'] or the MAIL_FROM_OVERRIDE constant if any is present.
- DICT subsystem: updated the ORDER BY processing in dict_database_s02.class.inc which is used the export the database info.
- MENU subsystem: updated mnu_subsystem(pdf).php so that it uses a subquery instead of a GROUP BY.
- MENU subsystem: updated mnu_pattern(list1).php, mnu_role(list1).php, mnu_role(popup1).php and mnu_subsystem(list1).php so that the values for $sql_select and $sql_from are set in the class instead of the component script.
- MENU subsystem: fixed bugs in mnu_user_role_s01.class.inc and mnu_user_role_s02.class.inc so that the MOVE UP and MOVE DOWN tasks work properly.
- MENU subsystem: fixed bugs in mnu_favourite_s01.class.inc and mnu_favourite_s02.class.inc so that the MOVE UP and MOVE DOWN tasks work properly.
- MENU subsystem: updated mnu_user.class.inc to fix bug when the login type is EMAIL instead of USER_ID and the browser language on the login screen is different from the language_id on the user’s MNU_USER record, which is not known until after the login process has completed.
- MENU subsystem: updated mnu_task.class.inc to add a call to the _cm_getForeignKeyValues() method.
- MENU subsystem: updated mnu_role_s01.class.inc to add a call to the _cm_getForeignKeyValues() method.
- MENU subsystem: updated mnu_role.class.inc to use a derived table in its sql query.
- MENU subsystem: updated mnu_control.class.inc so that the getControlData() methods initially sets $result to an empty array instead of NULL.

2021-01-04, version 2.18.1 patch

I have discovered that adding a UTF-8 byte order mark to files which are to be read by PHP has unintended side effects, so this patch file contains the fixes to remove tha byte order mark.

2021-01-01, version 2.18.0
Database changes:
- none

Other changes:
- DICT subsystem: fixed bug in dict_database_s02.class.inc where it included an invalid column (subsys_name) in the export file.
- DICT subsystem: updated dict_database_s02.class.inc so that the export file <subsystem>.dict_export.sql includes a Byte Order Mark (BOM) for UTF-8.
- DICT subsystem: updated dict_table_s02.class.inc so that the export file <table>.dict.inc includes a BOM for UTF-8.
- MENU subsystem: updated mnu_subsystem_s01.class.inc so that the export file <subsystem>.menu_export.sql includes a BOM for UTF-8.
- MENU subsystem: fixed bug in mnu_todo.class.inc where it failed to convert due_date to the user’s timezone before being displayed.
- MENU subsystem: updated sys.language_array.inc to include UTF-8 characters for Thai dates.
- std.csv.class.inc: updated output file to include a BOM for UTF-8 so that Thai characters are displayed properly.
- std.table.class.inc: removed properties $this->lock_tables and $this->lock_standard_tables as they only apply to MyISAM tables, not INNODB tables. 
- std.table.class.inc: fixed bug in convertTimeZone() method when dealing with Thai dates.
- std.table.class.inc: fixed bug in currency_flip() method to deal with different decimal places between the two currencies.
- std.table.class.inc: changed getExtraData() method to exclude call to $this->getForeignData() if $this->no_foreign_data is set.
- std.table.class.inc: fixed bug in initialise() method which tried to process screen fields from an alternative language table when the task did not have a screen.
- std.table.class.inc: fixed bug in insertMultiple() method to skip further processing if _cm_pre_insertMultiple() method places anything in $this->errors.
- std.table.class.inc: updated insertRecord() method so that it will call _cm_post_insertRecord() if $this->errors is empty OR _cm_post_insertRecord_with_errors() if not.
- std.table.class.inc: updated updateRecord() method so that it will call _cm_post_updateRecord() if $this->errors is empty OR _cm_post_updateRecord_with_errors() if not.
- std.table.class.inc: updated popupReturn() method so that the call to $this->getExtraData() is done after the call to _cm_post_popupReturn() instead of before.
- std.table.class.inc: fixed bug in updateMultiple() method to skip further processing if _cm_pre_updateMultiple() method places anything in $this->errors.
- std.table.class.inc: updated _sqlAssembleWhere() method so that if $this->sql_orderby is empty it will insert the name(s) of the primary key field(s).
- include.session.inc: updated childForm() function so that it will call ->getSearch() on the current object so that any search criteria can be passed to the child form which is about to be activated.
- include.session.inc: updated initialise() function so that if $GLOBALS[’XSLT_client_side’] is set (in the config.inc file) then client-side XSL transformations will be permanently ON, otherwise this feature can be manually turned ON and OFF by adding either ‘csxslt=on’ or ‘csxslt=off’ to the current URL in the browser’s address bar.
- std.datevalidation.class.inc: fixed bugs when translation to/from Thai dates which use UTF-8 characters as well as the Buddhist calendar.
- std.multi2.inc: removed duplicated check on $dbinner->errors after call to $dbinner->getExtraData().
- std.multi4.inc: fixed bug which disallowed scrolling through multiple selections of the outer entity.
- error.inc: updated errorHandler() to deal with change made for PHP 8.
- include.library.inc: updated array_update_associative() to deal correctly with the ‘select’ column.
- include.library.inc: fixed bug in where2indexedArray() function after call to findClosingParenthesis().
- include.xml.php5.inc: ignore any entry in $fieldarray[‘rdc_rowspecs’] which does not have an entry in $this->fieldspecs.

2020-11-09, version 2.17.0
Database changes:
- none

Other changes:
- AUDIT subsystem: updated the search screen to allow filtering by tran_seq_no.
- DICT subsystem: fixed bug in dict_column_s01.class.inc where the _cm_getInitialDataMultiple() method returned $insert_array instead of $rows.
- MENU subsystem: fixed bug in mnu_user.class.inc which had an extraneous ‘)’ in an SQL query.
- MENU subsystem: fixed bug in mnu_subsystem_s01.class.class.inc so that it does not execute the _cm_commonValidation() and _cm_validateUpdate() methods in the parent class.
- MENU subsystem: fixed bug in mnu_task_s02.class.class.inc so that it does not execute the the _cm_commonValidation(), _cm_post_updateRecord() and _cm_validateUpdate() methods in the parent class.
- WORKFLOW subsystem: fixed bug in wf_workitem.class.inc where it referred to ’mnu_task.task_desc’ instead of ’mnu_task.task_name’.
- MYSQL driver: fixed bug in buildKeyString() so that if any component in a primary key is null then the entire key is treated as null.
- MYSQL driver: fixed bug in getCount() so that it will allow any number of whitespace characters between the leading ‘(’ and the word ‘SELECT’.
- MYSQL driver: fixed bug in getData() so that it builds the correct query when there is a WHERE and/or HAVING string.
- MYSQL driver: fixed bug in updateRecord() where it reported the wrong WHERE string following an error with a candidate key.
- MYSQL driver: fixed bug in updateRecord() where it failed to abort if there was an error with the UPDATE query.
- MYSQL driver: for MySQL version 8.0.16 and above it will allow the use of column constraints instead of the deprecated ‘unsigned’ attribute.
- std.ADD2.inc: avoid generating message “N records were inserted into XXXX” is $this->no_display_count is set to TRUE;
- std.ADD2.inc: include call to $dbobject->setFinalAction() at end of processing of GET request.
- std.ADD2.inc: include call to $dbobject->runImmediateTask() prior to generation of HTML output.
- std.ADD7.inc: add code to regenerate $inner_where when processing the ‘SubmitStay’ button.
- std.ADD7.inc: add call to $dbouter->getFieldArray() after processing popup for $dbinner in case its data has changed.
- std.MULTI4.inc: fix bug to deal correctly with setting of $dbobject->use_scrollarray.
- std.MULTI4.inc: keep $inner_where separate from $outer_where.
- std.MULTI4.inc: include calls to $dbouter->getFieldArray() and $dbinner->getFieldArray() after processing a popup form in case any data has been chganged.
- std.OUTPUT2.inc: add call to ob_flush() at end of script.
- std.OUTPUT3.inc: add call to ob_flush() before returning to previous screen.
- std.OUTPUT5.inc: add call to ob_flush() at end of script.
- std.SEARCH1.inc: if a field is empty but has both $fieldspec[‘optionlist’] and $fieldspec[‘initial_value’] set then load that initial value.
- std.CSV.class.inc: fix bug which caused $dbobject->formatData to be called twice on the first row.
- std.DATEVALIDATION.class.inc: remove redundant ‘return false;’ lines after throwing an error.
- std.PDF.class.inc: fixed bug which prevented a barcode or image from appearing in a line without other cells.
- std.SINGLETON.php5.inc: added code to throw an error if the requested file does not exist.
- std.VALIDATION.class.inc: added code to deal with a decimal number with precision = 38 and scale = 0.
- include.XML.php5.inc: amended addData2XMLdoc() so that if $dbobject does not contain a value for $this->zone then the default value of ‘main’ is used instead.
- include.XML.php5.inc: amended addData2XMLdoc() so that when $fieldspec is refreshed then so is the screen structure in $this->structure. This will allow the screen structure to be amended in the _cm_formatData() method.
- include.XML.php5.inc: amended addData2XMLdoc() so that when a button for anther task is created it is in the format ‘task#{$zone}#{$task_id}’. If it is in a zone which contains multiple rows then '[offset={rownumber}]' will be appended.
- include.XML.php5.inc: amended addData2XMLdoc() so that when loading the contents for a checkbox with an optionlist which contains ‘_no_undef’ then it is displayed as a checkbox instead of a dropdown list with an additional ‘undefined’ option.
- include.XML.php5.inc: amended buildXML() to use $this->javascript instead of $javascript so as not to lose any entries.
- include.LIBRARY.inc: amended append2ScriptSequence() to force $next to be the first in the queue if $next[‘immediate’] is set.
- include.LIBRARY.inc: amended array2string() to add an option 2nd argument called $separator with a default value of ‘&’.
- include.LIBRARY.inc: amended array2where() so that $dbobject->getFieldSpec() is not called if that method does not exist.
- include.LIBRARY.inc: amended check_task_button() to include '[offset={$offset}]' in the output value if $osset is not zero.
- include.LIBRARY.inc: amended extractSelectList() to deal with more combinations in the input string.
- include.LIBRARY.inc: amended several functions to replace code with a call to splitWhereByRow().
- include.LIBRARY.inc: amended findClosingParenthesis() to simplify the code using a better regular expression.
- include.LIBRARY.inc: amended qualifyField() to deal with an entry in the SELECT list which is in the format ‘func(field)’.
- include.LIBRARY.inc: amended removeDuplicateFromSelect() to deal with a select string containing ‘tablename.*’.
- include.LIBRARY.inc: amended selection2PKeyOnly() to deal correctly with an entry which is not in $fieldlist.
- include.LIBRARY.inc: amended selection2where() to verify that the selected rows have an entry in $pkeyarray.
- include.LIBRARY.inc: amended where2indexedArray() to fix bugs in some regular expressions.
- include.SESSION.inc: amended childForm() to extract ‘offset’ if it is available in the input string. This deals with a button which is pressed in a zone containing multiple rows.
- include.SESSION.inc: amended childForm() so that calls to $dbobject->getWhere() include the $offset value.
- include.SESSION.inc: amended childForm() so that calls to $dbobject->getSearch() include $task_array.
- include.SESSION.inc: amended scriptNext() so that when processing an entry from $_SESSION['script_sequence'] which contains the option ‘no_messages’ the contents of $this->messages are not forwarded to the next script.
- std.TABLE.class.inc: added $save_initial_where variable so that if a WHERE string for an INNER entity is validated and modified in the _cm_initialise() method then this value will override the one constructed from its parent entity.
- std.TABLE.class.inc: amended commit() so that if $this->fieldarray is empty but $this->parent_data is not then it will call _examineWorkflow() on the parent object.
- std.TABLE.class.inc: added convertSearchExpression() and _cm_convertSearchExpression() will is called in the initialise() method in order to allow the contents of $search to be modified.
- std.TABLE.class.inc: amended _cm_customButton() to include a 3rd argument to identify the row number for use in a zone which contains multiple rows.
- std.TABLE.class.inc: amended various method calls so that if they return FALSE it will be converted into an empty array.
- std.TABLE.class.inc: amended getData() method to replace contents of $where argument with $this->save_initial_where if it is not empty.
- std.TABLE.class.inc: amended getExtraData() method to remove the check of $this->no_foreign_data before calling getForeignData().
- std.TABLE.class.inc: amended getForeignData() method so that after calling _cm_getForeigndata() it will skip further processing if either $this->no_foreign_data or $fieldarray['rdc_no_foreign_data’] is set.
- std.TABLE.class.inc: added _cm_adjustColumnNames() method to allow list of field names in the primary key to be adjusted.
- std.TABLE.class.inc: amended getPkeyArray() to call _cm_adjustColumnNames() after _cm_getPkeyNames().
- std.TABLE.class.inc: added getSearch() and _cm_getSearch() methods to allow the $this->sql_search string to be adjusted before it is passed to the next script.
- std.TABLE.class.inc: amended getWhere() to include a 2nd argument called $offset so that when $this->fieldarray contains multiple rows the $where string is constructed from the current/selected row instead of the first row.
- std.TABLE.class.inc: amended initialise() method so that when called in a search screen it will pass any search criteria through the convertSearchExpression() method before the screen is displayed.
- std.TABLE.class.inc: amended insertRecord() method so that _cm_post_insertRecord() method is called even if $this->errors is not empty.
- std.TABLE.class.inc: amended popupCall() so that if contents of $popupname argument is changed it will update the relevant $this->fieldspec entry to record the name change.
- std.TABLE.class.inc: amended popupReturn() so that when searching through $this->parent_relations to see if there are any differences between the column names used in the parent table and those used in this child table. By default it will stop at the first entry which contains the reurned column names, but if there are multiple entries the correct table name can be identified by setting $fieldarray[‘rdc_table_id’] = ‘whatever’ in the _cm_popupReturn() method.
- std.TABLE.class.inc: added runImmediateTask() method.
- std.TABLE.class.inc: added setFinalAction() and _cm_setFinalAction() methods.
- std.TABLE.class.inc: amended updateRecord() method so that _cm_post_updateRecord() is called even if $this->errors is not empty.


2020-06-03, version 2.16.0
Database changes:
- none

Other changes:
- updated ‘include.batch.inc’ to add the $rdc_wait argument to the signature of the batchScriptSequence() function. This is used at the end of the current background task to run another background task, and if set to FALSE it will start the new task but not wait for it to finish before it continues with its own processing.
- updated ‘std.data_field.xsl’ so that the filepicker template encloses picker-image in a <span> instead of a <div>. This fixes the issue reported at http://forum.radicore.org/index.php?t=msg&th=3467
- updated all CSS files to include an entry for ‘span.picker-image’ to replace ‘div.picker-image’.
- updated ‘std.table.class.inc’ so that the startTransaction() method will use the contents of $this->lock_tables (if it is not empty) instead of calling _cm_getDatabaseLock(). This is to allow different calls to startTransaction() in the same process to more easily specify different sets of tables for locking. Please refere to http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq48 for details.
- updated ‘std.table.class.inc’ so that the _cm_getDatabaseLock() method uses $this->lock_tables and $this->row_locks instead of $GLOBALS[‘lock_tables’] and $GLOBALS[’row_locks’].
- updated all ’dml.???.class.inc’ files to simplify the locking mechanism. See https://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq47 for details.
- updated various classes in the DICT subsystem to remove the redundant _cm_getDatabaseLock() method.
- updated various classes in the MENU subsystem to remove the redundant _cm_getDatabaseLock() method.
- fixed bug in ‘dict_table_s01.class.inc’ so that the _cm_getInitialDataMultiple() method returns the correct value.
- fixed bug in ‘mnu_saved_selection.class.inc’ which had ‘=’ instead of ‘==’ inside a condition.
- updated ‘std.list2.inc’ to simplify the creation of $inner_where.
- updated ‘std.search1.inc’ to fix bug concerning numeric columns with precision set to 38.
- updated ‘include.xml.php5.inc’ so that it refreshes the contents of $fieldspec after a call to _cm_formatData() in case anything has changed.
- updated ‘std.enquire1.inc’ so that it will automatically return to the previous script if the _cm_initialise() method puts anything into $this->errors.
- updated ‘include.session.inc’ so that if the runInBackground() method is called from a web service server then it will not try to automatically run the ‘batch_log(filepicker)’ task.
- updated ‘include.library.inc’ so that the append2ScriptSequence() function has an additional $allowed argument which by default is set to false. This will cause any calls made with a web service server to be ignored unless this argument is explicitly set to TRUE.
- updated ‘include.library.inc’ to fix several issues found in the extractOperatorValue() function.
- updated ‘include.library.inc’ to add an extra argument to the mergeWhere() function. See http://www.tonymarston.net/php-mysql/functions-and-variables.html#func.mergewhere for details.
- updated ‘std.table.class.inc’ to fix an issue with the findDBVersion() method.
- updated ‘std.table.class.inc’ to fix an issue with the unsetting of the ‘nodisplay’ option in the $fieldspec array.
- updated ‘std.table.class.inc’ to move code from the getFieldSpec() method to the setFieldAccess() method.
- updated ‘std.table.class.inc’ so that the popupReturn() method deals correctly with a NULL value returned from a filepicker.
- updated ‘std.table.class.inc’ so that the sqlQuickSearch() method deals correctly with numeric fields having a precision of 38.


2020-04-02, version 2.15.0
Database changes:
- none

Other changes:
- modified the FilePicker pattern to include the $picker_include_dir option. See _cm_initialiseFilePicker() for details.
- fixed a bug in the FilePicker pattern which returned the file name as an absolute path instead of a relative path.
- updated ‘dml.mysql.class.inc’ to deal with alias names for expressions when appearing in the HAVING clause for a ‘SELECT count(*) ...’ query.
- updated ‘std.datevalidation.class.inc’ to include more date patterns in the getInternalDate() and getInternalDateTime() methods.
- update ‘std.validation.class.inc’ so that if $this->date_format_input is set in the calling program it will be passed to the date validation class as a temporary override to $_SESSION['date_format_input'].
- updated ‘include.library.inc’ to include the array2string() function which is the reverse of parse_str().
- updated ‘include.library.inc’ to fix a bug in the truncateNumber() function.
- updated ‘std.table.class.inc’ so that in the getExtraData() method the call to changeConfig() is moved from before the call to _cm_getExtraData() to after.
- updated ‘std.table.class.inc’ so that in the getParentData() method the default for the $first_row_only argument is TRUE instead of FALSE.
- updated ‘std.table.class.inc’ so that in the initialise() method for any tasks with the ENQ1 and DEL1 patterns if the passed WHERE contains all the elements of the primary key then any additional elements will be removed.
- updated ‘std.table.class.inc’ so that in the updateRecord() method any changes made to the record will be stored in $this->dbchanges which can then be used in the _cm_post_updateRecord() method.
- updated ‘std.table.class.inc’ so that the _validateInsertPrimary() and _validateUpdatePrimary() method will accept a second variable to be used instead of the $fieldspec array.
- updated ‘include.session.inc’ so that the sessionStart() function is called without the ‘@’ error suppression operator.
- updated ‘std.update3.inc’ so that it will call the quitButton() method when the QUIT/CANCEL button is pressed.


2020-01-09, version 2.14.0
Database changes:
- none

Other changes:
- updated TCPDF library to version 6.2.26.
- updated dml.mysqli.class.inc to deal with the fact that SQL_CALC_FOUND_ROWS has been deprecated in MySQL version 8.0.17 and will be removed in a future release.
- updated dml.sqlsrv.class.inc to modify the way it replaces “now()” with “SYSDATETIME()”.
- updated dml.sqlsrv.class.inc so that the adjustFrom() method will deal correctly with temporary table names.
- updated dml.sqlsrv.class.inc so that the adjustGroupBy() method will deal correctly with the WITH ROLLUP option.
- updated dml.sqlsrv.class.inc so that the adjustSelect() method can deal with more complicated expressions.
- updated dml.sqlsrv.class.inc so that the fixReservedWords() method includes both ‘percent’ and ‘yield’.
- updated dml.sqlsrv.class.inc so that the adjustTempTable() method can deal with statements containing column specifications.
- updated dml.sqlsrv.class.inc so that the getCount() method will work correctly.
- updated dml.sqlsrv.class.inc so that the getData() method deals differently with Common Table Expressions.
- updated dml.sqlsrv.class.inc so that the insertRecord() and updateRecord() methods will enclose each column name in ‘[’ and ‘]’.
- updated include.library.inc to include an optional 4th argument on the array_update_associative() function. 
- updated include.library.inc so that the array2where() function will perform stripslashes() before addcslashes() to prevent double slashes.
- updated include.session.inc to deal with deprecations introduced in PHP 7.4.
- updated nusoap.php from version 1.114 to 1.123.
- updated radicore.simplexmlelement.inc so that addArray() function can deal with 2nd argument being a text node instead of an array.
- updated std.add2.inc to format $errors array correctly before calling the $view->buildXML() method.
- updated std.add7.inc to refetch $inner_data in case it has changed.
- updated std.filepicker.inc to deal properly with multiple levels of subdirectories. This allows the screen to include directories as well as files, and if a directory is chosen the screen will then display that directory’s contents.
- updated std.multi4.inc to call quitButton() method on $dbouter and $dbinner when the QUIT button is pressed.
- updated std.output3.inc to terminate if there is no document to display.
- updated std.pdf_list.class.inc to use the contents of $dbobject->dynamic_column_headings to replace the current set of column headings.
- updated std.search1.inc to ignore contents of $task_button if $errors is not empty.
- updated std.singleton.php5.inc so that if $class variable contains ‘<subsystem>/<class>’ it will deal with <subsystem> being the current working directory or 1 or 2 levels higher.
- updated std.soap.inc so that convertTypes() function looks for an xmlrpc_type of ‘dateTime’ instead of ‘datetime’.
- updated std.soap.inc to add check_response() and display_soap_debug() functions.
- removed std.soap.php4.inc and std.soap.php5.inc as code is now contained in std.soap.inc.
- updated std.table.class.inc to remove $no_convert_timezone as it is redundant.
- updated std.table.class.inc to include the $dbobject->_cm_getFieldArray() method.
- updated std.table.class.inc so that the $dbobject->array_update_associative() method calls the array_update_associative() function in a try/catch block.
- updated std.table.class.inc so that the $dbobject->checkMessageDirectory() method uses the constant TEXT_DIRECTORY if it is set.
- updated std.table.class.inc so that if the $dbobject->getData() method contains all the columns from that table’s primary key in the $where argument then any additional non-pkey columns will be ignored.
- updated std.table.class.inc so that $this->getOrderBy() method will qualify the table name if $this->sql_from contains references to multiple tables.
- update std.tree_view2.inc so that call to $dbinner->initialise() does not lose the contents of the $where argument.


2019-08-01, version 2.13.0
Database changes:
- none

Other changes:
- fixed bug in dict/classes/related_column.class.inc so that if the column data is missing for the related_column(multi4)a/b screens it will automatically fill in the key columns for the parent table.
- updated std.filepicker.inc so that it can deal with a selection which is a directory and not a file.
- updated popup processing so that if the 'allow_input' option is used it will allow javascript events to be added.
- updated std.help.inc to deal with invalid characters in the task_id argument.
- updated include.xml.php5.inc to add 'X-XSS-Protection', 'X-Frame-Options' and 'X-Content-Type-Options' to the header() arguments for the HTML output.
- updated std.datevalidation.class.inc so that it can deal with input dates containing UTF8 characters.
- updated std.csv.class.inc to fix bug when the call to $dbobject->appendToCsv() returns a non-empty value.
- updated include.library.inc to add the array_remove_nulls() function to remove entries from an associative array where the values are empty.
- updated include.library.inc so that the array_update_associative() function will deal with the situation when the input format for dates is different to the output format.
- updated include.library.inc to fix various bugs in the array2where() and where2array() functions.
- added the array2where_missingIsNull() function to include.library.inc which will add '$fieldname IS NULL' to the output instead of ignoring it when a field identified in $fieldlist does not have a corresponding entry in $inputarray.
- updated std.table.class.inc so that various methods which deal with dates can handle the Buddhist calendar which has a 543 difference in the year.
- updated std.table.class.inc so that the fetchRow() method can deal with $this->allow_zero_rows = TRUE;
- updated std.table.class.inc to fix bugs in the getLanguageArray() and getLanguageText() methods so that they will deal with a missing entry for $GLOBALS['classdir'].
- updated std.table.class.inc to fix a bug in the getPkeyArray() method.
- updated std.table.class.inc to fix bug in the getValRep() method so that it will set $GLOBALS['class_dir'] when it needs to.
- updated std.table.class.inc so that the $dbobject->initialise() method, when called in a ENQ1 pattern and the $selection argument contains values for all the primary key columns, then any non-primary key columns will be removed as they are redundant.
- updated std.table.class.inc so that the $dbobject->initialise() method, when called in an ADD1 pattern, will remove any values for the primary key column(s) in the $selection argument as they are redundant.
- updated std.table.class.inc so that the $dbobject->insertMultiple() method will check that any error messages in the $errors array are keyed to the correct row.
- fixed bug in std.add5.inc where it referred to $dbobject->array_update_associative() instead of $dbouter->array_update_associative().
- fixed bugs in dml.sqlsrv.class.inc where it failed in its conversions of queries from MySQL to SQLSRV format.
- updated std.multi4.inc to allow for the situation when $dbouter->use_scrollarray is TRUE.
- updated std.add2.inc to remove some redundant code.
- updated std.add5/6/7.inc, std.link1.inc, std.multi2/3/5/6.inc and std.output4.inc to include a call to the getPostArray() function before call to $dbouter->customButton().
- updated std.list2/3/4.inc to include call to identify_id_column() function after calls to array2where().
- updated std.output1.inc to allow it to be used in a batch job.
- updated std.output1.inc so that if $dbobject->allow_zero_rows is TRUE it will output an empty CSV file (a header line but no data) if there is no data. This overrides the default behaviour which is to return to the user with the error message 'Nothing retrieved from the database'.

2019-05-01, version 2.12.0
Database changes:
- none

Other changes:
- fixed a bug in 'dict_database_s01.class.inc' in the Data Dictionary which caused a problem when importing from a PostgreSQL database. See https://forum.radicore.org/index.php?t=msg&th=3416 for details.
- fixed a bug in 'dict_related_column.class.inc' in the Data Dictionary which failed to show any entries in the $inner area in the update screen if none were initially created in the insert screen.
- updated processing for the DETAIL view in PDF documents so that when using the additional data option, which uses code in the _cm_output_multi() method, it will allow multiple iterations through the 'multi1' to 'multi99' entries using different WHERE strings. Multiple iterations can be requested by putting code in the _cm_output_iterations() method to provide an array of different WHERE strings. By default an empty array will be output which will signify a single iteration with an empty WHERE string.
- updated 'std.table.class.inc' to include the new _cm_output_iterations() method.
- updated 'std.table.class.inc' to add a third argument called $iteration to the _cm_output_multi() method. This will contain the WHERE string for each iteration. If nothing is set in the _cm_output_iterations() method then by default _cm_output_multi() will only cycle once through the 'multi1' to 'multi99' entries with a NULL value for the $iteration argument.
- updated 'std.table.class.inc' so that the array_update_indexed() method calls the $this->array_update_associative() method for each row in the array instead of the array_update_indexed() function for the whole array.
- updated 'std.table.class.inc' so that the customButton() method calls the $this->array_update_associative() method instead of the array_update_associative() function.
- updated 'std.table.class.inc' so that the updateLinkData() method will operate correctly when more than one row of the outer entity has been selected.
- updated 'std.table.class.inc' so that the updateMultiple() method calls the $this->array_update_associative() method instead of the array_update_associative() function.
- updated 'std.table.class.inc' to fix a bug in the updateRecord() method which caused it, in some circumstances, not to read the record that was due to be updated, thus causing an error.
- updated 'std.table.class.inc' to include the _cm_pre_pasteData() and _cm_post_pasteData() methods which will be called by the pasteData() method when the PASTE button is pressed.
- updated 'std.table.class.inc' so that the getData() and getData_serial() methods will examine the SQL_FROM string to see if the current table name has been given an alias. If so then the alias name will be passed to the $DML->getData() method instead of the original name, thus preventing an error when the SQL query is constructed.
- updated 'std.table.class.inc' so that the _sqlAssembleWhere() method will not filter out a fieldname from the WHERE string if it is used as an alias for a field which exists in a table which is mentioned in the FROM string.
- updated 'std.table.class.inc' so that when the _sqlAssembleWhereLink() method constructs its query it will start with whatever is specified in the component script.
- updated 'include.library.inc' to correct some issues encountered in the array2where() function.
- updated 'include.library.inc' to correct an issue encountered in the convert_parent_id_to_child_id() function with the stripping of operators from the contents of the $fieldarray argument.
- updated 'include.library.inc' to correct an issue encountered with the getLanguageArray() method when a require_once fails due to it already having been processed.
- updated 'include.session.inc' to correct an issue in the initSession() function which caused the CSRF check to fail when it should not have.
- updated 'include.session.inc' to correct an issue in the scriptNext() function which failed to check that an entry extracted from the $_SESSION['script_sequence'] array was actually valid.
- updated 'std.validation.class.inc' so that the validateField() method uses a static variable for the $date object so that it does not need to instantiate it more than once in any processing cycle.
- updated the various 'dml.???.class.inc' files so that when filling in any autoinsert or autoupdate fields with the current timestamp they use the server's time instead of the client's time.
- updated 'std.csv.class.inc' so that if the contents of the variable $dbobject->insert_blank_line is set to a non-zero value following a call to $dbobject->formatData() then a blank line will be inserted into the CSV file.
- updated 'std.list2.inc' to insert a call to $dbinner->restart() after the call to $dbinner->initialise().
- updated 'std.search1.inc' to correctly deal with boolean values which may have values containing either true/false, 0/1, T/F or Y/N.
- updated 'std.multi4.inc' to deal correctly with the situation where $dbouter->skip_getData is set to TRUE.
- updated 'std.add1.inc', 'std.add2.inc' and 'std.update1.inc' so that they use the $dbobject->pasteData() method instead of the pasteData() function. This allows the use of the _cm_pre_pasteData() and _cm_post_pasteData() methods.
- updated 'std.update1.inc' to allow an empty $where string if $dbobject->allow_empty_where is set to TRUE.
- updated 'std.add7.inc' to correct an issue which did not place an error following a popup call on the correct line in the inner zone.
- updated 'std.link1.inc' to remove the call to $dblink->array_update_indexed() as the necessary processing is performed within $dblink->updateLinkData().

2019-02-02, version 2.11.0
Database changes:
- run script menu\sql\mysql\menu.menu_export(2019-01-24).sql to update the contents of the MENU database

Other changes:
- modified TREE1 and TREE2 patterns to allow extra fields in the screen.
- added the LIST4, ADD6, ADD7 and TREE3 patterns.
- updated the DICT subsystem to generate tasks from these new patterns.
- updated std.list3.inc to fix bug when using the RESET button.
- updated std.table.class.inc to set $object->no_read_lock to TRUE when accessing tables in the getForeignData() method while a transaction is in progress. This will prevent these tables from being locked.
- updated std.table.class.inc to include $rows_to_be_appended variable. Refer to FAQ176 for details.
- updated std.table.class.inc so that the commit() method removes such flags as 'rdc_to_be_inserted', 'rdc_to_be_updated' and 'rdc_to_be_deleted' from $this->fieldarray as they are redundant after the transaction has been completed.
- updated std.table.class.inc so that the _cm_validateUpdate() method includes an additional $method argument. This can be set to either 'GET' or 'POST' depending on the circumstances under which it was called.
- updated std.table.class.inc so that the fetchRow() method will call $this->_cm_post_fetchRow($row) even when $row is empty in order to allow any end-of-file processing.
- updated std.table.class.inc so that the getForeignData() method will not bother reading the parent table if all the fields identified in $parent fields already have non-NULL values.
- updated std.table.class.inc so that the getInitialDataMultiple() method will always return an array which is indexed by row number so that a single row is not returned as an associative array.
- updated std.table.class.inc so that the initialise() method does not remove the 'curr_or_hist' pseudo-column from the $where/$selection argument.
- updated std.table.class.inc to fix a small bug in the insertMultiple() and updateMultiple() methods.
- updated std.table.class.inc so that the _cm_popupReturn() and _cm_post_popupReturn() methods include an additional $fieldname argument which identifies the field which triggered the popup.
- updated std.table.class.inc to include the _cm_pre_getNodeData() method which is called once before the _cm_getNodeData() method, which may be called several times in a single execution of the script.
- updated std.output6.inc to call the _cm_pre_getNodeData() method.
- updated std.table.class.inc to make array_update_associative() and array_update_indexed() into object methods instead of plain functions.
- updated include.session.inc so that the checkSelection() function can recognise the fact that the task was initiated because of an 'initial_passthru' setting on another task.
- updated include.session.inc so that the childform() function will not pass any row selections to search screens.
- updated std.list2.inc to fix bug where it used $fieldarray instead of $inner_data.
- updated std.pdf.class.inc to allow '*' as a column width in the title area.
- updated std.search1.inc so that it can deal with a javascript submit().
- updated std.multi4.inc so that it updates the database before activating a task initiated from a navigation button.
- updated std.update3.inc so that after the initial activation it provides $fieldarray as an associative array instead of an indexed array.
- fixed bug in std.update4.inc which sometimes failed to call commit().
- updated std.update1.inc to call the $dbobject->array_update_associative() method instead of the array_update_associative() function.
- fixed bug in std.enquire1.inc which failed to deal with navigation buttons correctly.
- updated include.xml.php5.inc so that the _cm_formatData() method can use the $fieldarray['rdc_rowspecs'] and $fieldarray['rdc_fieldspecs'] options.
- updated dml.???.class.inc so that if multiquery() is called with a single query it will return the result of that query instead of just TRUE.
- updated std.validation.class.inc to disallow the wildcard '%' character, or any control characters, from being used in a primary or candidate key.
- updated std.filepicker1.inc so that it forces the $subdir variable to contain forward slashes instead of backslashes.
- updated include.library.inc to include the extractPopupFields() function.
- updated std.list3.xsl to fix a bug with pagination in the 'middle' area.
- updated processing for LINK1 patterns to remove the CROSS JOIN in the generated SQL query.

2018-08-01, version 2.10.0
Database changes:
- none

Other changes:
- updated std.help.inc to add flush() just before exit so that the buffer is cleared before it enters the shutdown_handler() function (which is defined in file error.inc).
- updated std.output3.inc and std.filedownload1.inc to flush the output buffer so that nothing is left over for processing by the shutdown_handler() function.
- updated std.datevalidation.class to improve validation in the getInternalDate() method.
- updated audit_tbl_s01.class.inc and audit_tbl_s02.class.inc to change addslashes() to addcslashes() so as not to escape double-quotes in the WHERE string.
- updated audit_trn.class.inc and audit_ssn.class.inc to fix a missing value in the trn/ssn_datetime field.
- updated php_session.class.inc to change arguments on calls to the logstuff() function.
- updated dml.mysqli.class.inc to set the correct size value for unsigned numbers.
- updated output4.screen.inc in DEFAULT folder to incorporate changes made to the OUTPUT4 pattern.
- updated _cm_pre_getData() method in dict_table.class.inc to deal with the possibility of using an alias name.
- updated logon.class.inc to look for a value to populate $_SESSION['party_id_functional'] in those installations which have a PARTY subsystem.
- updated mnu_task_s02.class.inc to move processing from the _cm_validateUpdate() method to the _cm_pre_updateRecord() method.
- fixed bug in mnu_task_s04.class.inc which did not allow for a user having multiple roles.
- fixed bug in mnu_nav_button.class.inc where the getNavButtons() method selected the 'task_desc' field instead of the 'task_name' field.
- fixed minor bugs in wf_workflow.class.inc, wf_workitem.class.inc and wf_arc.class.inc.
- updated workflow_engine.class.inc so that error messages are obtained from the language file in the correct directory.
- updated include.library.inc to fix bug in array_update_indexed() function.
- updated include.library.inc to cause the array2where() and selection2where() functions to use addcslashes() instead of addslashes() so that only single quotes are escaped.
- updated include.library.inc to allow the getForeignKeyValues() function to work in the direction child-to-parent as well as parent-to-child.
- updated include.library.inc to fix bug in the getPostArray() function.
- updated include.library.inc to allow the getTimeStamp() function to optionally use the user's timezone instead of the server's timezone.
- updated include.library.inc to allow the logStuff() function to deal with the $input argument as an array as well as a string.
- updated include.library.inc to force the logSqlQuery() function to write to the correct directory.
- updated include.library.inc to force the pasteData() function to not overwrite a date with an earlier date.
- updated std.tree_view1.inc and std.tree_view2.inc to call getExtraData() method, and to accept search criteria.
- updated std.tree_view1.inc and std.tree_view2.inc to call the getCollapsed() method.
- updated std.search1.inc to put the call to getInternalDate() in a try/catch block so that it can deal with invalid dates correctly.
- updated std.search1.inc so that if the output from $dbobject->post_search() is an indexed array it will be converted into an associative array.
- updated include.session.inc and include.batch.inc to deal with a BC break that was introduced in version 7.2 (see http://www.tonymarston.net/php-mysql/bc-break-in-7.2.html for details).
- updated include.batch.inc so that the batchScriptSequence() function can properly handle the situation when the scriptSequence() function is used in a CLI/background task.
- updated error.inc to change the sequence in which the data is output to the screen and written to the disk file.
- updated std.pdf.class.inc to allow a field definition in the ???.report.inc file to override the border settings for the current style. This will allow the top/bottom/left/right borders of a cell to be either added or removed.
- updated include.xml.php5.inc so that if a checkbox field does not have a value specified for optionlist it will default to the standard 'boolean' optionlist.
- updated output4_header.class.inc so that the _cm_updateFieldarray() method will allow unwanted values to be removed from the $postarray argument.
- updated std.add1/2.inc to include a call to $dbobject->changeActionButtons() to see if any buttons have been changed or deleted.
- updated std.add1/2.inc to include a call to $dbobject->quitButton() before returning to the previous script.
- updated std.csv.class.inc so that the outputCSV() method will nullify the $csvouth variable after it has been closed so that the controller (std.output1.inc) will not try to close it itself.
- fixed bug in std.link1.inc where it used $fieldarray instead of $outer_data.
- updated std.update1.inc so that if the CANCEL button is pressed it will call $dbobject->quitButton() before returning to the previous script.
- updated std.multi6.inc so that the calls to ->setFieldArray() do not reset $pageno and $numrows.
- updated std.multi6.inc so that the calls to ->updateFieldArray() include the switch which causes the call to _cm_commonValidation() to be skipped. This validation method will instead be called after the data has been re-fetched.
- updated std.multi6.inc to fix the pagination/scrolling issues caused by the $middle entity being allowed to contain either a single row (detail view) or several rows (list view).
- updated std.table.class.inc to include the array variable $drop_from_sql_select which will cause the nominated fields to be dropped from the SELECT clause of the SQL query when the _sqlAssembleWhere() method is called.
- updated std.table.class.inc to include the changeActionButtons() and _cm_changeActionButtons() methods to deal with the circumstances where action buttons are renamed.
- updated std.table.class.inc so that the clearEditableData() method will not clear any field which has the 'noclear' attribute set.
- updated std.table.class.inc to fix bug in currentOrHistoric() method so that it will not fail if the current table does not actually have a start_date and end_date field.
- updated std.table.class.inc so that the fetchRowChild() method will populate the object's $parent_data so that a call to getParentData() will provide the data for this child's parent.
- updated std.table.class.inc so that the formatData() method can handle date and datetime fields properly.
- updated std.table.class.inc so that the getColumnNames() method (as used in output4 patterns) will show a checkbox instead of a dropdown for the 'selected' field.
- updated std.table.class.inc to that the getData_raw() method will call the qualifyWhere() function on the $sql_search variable if it is not empty.
- updated std.table.class.inc so that the getParentData() method now includes an argument ($first_row_only=false) which can be set to TRUE so that the first row is returned as an associative array instead of a possible indexed array.
- updated std.table.class.inc so that when the getData_serial() method calls getParentData() it causes it to return an associative array instead of an indexed array.
- updated std.table.class.inc so that the getExtraData() method includes an extra argument ($no_foreign_data=false) which can be set to TRUE to cause the call to getForeignData() to be skipped.
- updated std.table.class.inc so that the getFieldArray() method includes an argument ($first_row_only=false) which can be set to TRUE to cause it return the first row as an associative array instead of all available rows in an indexed array.
- updated std.table.class.inc so that the getForeigndata() method can correctly handle the situation where an entry in $parent_relations contains a value for 'alias'.
- updated std.table.class.inc to comment out redundant code in the getNodeData() method.
- updated std.table.class.inc to include the getCollapsed() method for use in the tree1 and tree2 patterns.
- updated std.table.class.inc so that the initialise() method will ignore any values in the $_SESSION['search'] array which are not strings.
- updated std.table.class.inc so that the insertRecord() method will not supply the $old_data argument on the call to the _cm_commonValidation() method.
- updated std.table.class.inc so that the setFieldarray() method includes an extra argument ($reset_numrows=true) which can be set to FALSE so that the value in $this->numrows is not reset.
- updated std.table.class.inc so that the updateFieldArray() method includes an extra argument ($perform_validation=true) which can be set to FALSE so that the call to _cm_commValidation() will be skipped.
- updated std.table.class.inc so that the updateMultiple() method will ignore fields which do not exist in $this->fieldspec when copying data from the POST array to the object's $fieldarray.
- updated std.table.class.inc so that the _dml_getData() and _dml_getData_serial() methods can pass the data for Common Table Expressions to the database object.
- updated std.table.class.inc by adding the findDBVersion() method. This is to allow the use of MySQL version 8 to be detected so that an SQL query which is a Common Table Expression (CTE) can be used to traverse hierarchical structures.
- updated dml.mysql/sqlsrv/pgsql/oracle.class.inc to allow a Common Table Expressions (CTE) to be used in hierarchical structures which are displayed using std.tree_view1/2.inc. Note that this is not available for MySQL unless you are using version 8. 
- updated _cm_getNodeData() method in x_tree_structure(tree2).php (XAMPLE subsystem) to show how Common Table Expressions can be used.


2018-03-01, version 2.09.0
Database changes:
- run script menu\sql\mysql\menu.menu_export(2017-11-10).sql to update the contents of the MENU database

Other changes:
- fixed bug in mnu_saved_selection.class.inc and output4_header.class.inc by renaming method updateSelection() to updateSavedSelection() so that it does not conflict with standard method inside std.table.class.inc
- updated all dml.???.class.inc files and error.inc to cater for the $errcontext argument of the error handler being deprecated in PHP 7.2
- updated _cm_getNodeData() in 'std.table.class.inc' to include a 4th argument called $collapsed.
- updated 'std.tree_view1.inc' and 'std.tree_view2.inc' to maintain the contents of $collapsed.
- updated return_bytes() function to split off the trailing alpha character before performing any multiplications.
- updated the MENU database to include a new task called 'dates(all)' which will remove the 'dates(current/historic/future)' setting.
- updated 'include.library.inc' so that the currentOrHistoric() function can deal with the 'dates(all)' option.
- updated method '_cm_updateFieldarray()' method in 'std.table.class.inc' so that the 2nd argument is passed by reference. The contents of this array will automatically be merged with $fieldarray after the call so this provides the opportunity to remove values which are no longer wanted.
- added array variable $no_filter_where to 'std.table.class.inc' which prevents column names which do not exist in the current table from being filtered out of the where string. This can be set in the '_cm_initialise()' method. This provides an alternative to the '_cm_filterWhere()' method.
- updated 'include.xml.php5.inc' and 'std.data_field.xsl' to allow tooltips in custom buttons.
- updated 'std.search1.inc' so that it calls the $dbobject->post_search() method before it saves the search string in the $_SESSION array instead of after.
- updated 'std.filedownload.inc' so that you can provide the contents in memory instead of always having to read it from disk.
- updated 'std.table.class.inc' so that the getData_raw() method saves its results in $this->fieldarray.
- updated 'std.table.class.inc' so that the popupReturn() method will not call _cm_popupReturn() if the $selection argument is empty.
- updated 'std.table.class.inc' by adding a 2nd argument to the sqlSelectInit() method which will optionally allow $this->lookup_data to be initialised.
- updated 'include.session.inc' to improve the CSRF checks.
- updated 'std.validation.class.inc' to improve the validation of boolean fields.
- updated 'include.library.inc' so that the getForeignKeyValues() function can find the keys to either the parent or the child table in any parent-to-child relationship.

2017-11-01, version 2.08.0
Database changes:
- none

Other changes:
- fixed bug in logon.class.inc so that it escapes characters in user_id before doing a lookup on AUDIT_LOGON_ERRORS.
- fixed bug in getLanguageArray() which sometimes caused a 'file sys.language_array.inc is empty' error.
- updated dml.pgsql.class.inc for PostgreSQL version 10 which now uses GENERATED AS IDENTITY to indicate an auto-increment column.
- updated mnu_file.class.inc so that when files are deleted on the FilePicker screen it shows the correct count.
- fixed bug in menu\sql\mysql\mnu-user.sql which referenced a column which no longer exists.
- updated std.output1/2/3/4/5/6.inc so that they remove task details from the $_SESSION array after the file has been sent to the browser. This was to fix a problem with the CSRF token.
- fixed bug in std.multi5.inc and std.multi6.inc which sometimes made the RETRIEVE button ineffective.
- fixed bug in std.help.inc where the browser language indicated a language code which is not actually supported.
- fixed bug in std.library.inc where the browser language indicated a language code which is not actually supported.
- updated std.table.class.inc so that if _cm_pre_deleteData() returns an empty $fieldarray then the calls to validateDelete(), deleteRelations() and _dml_deleteRecord() are skipped.
- fixed bug in std.validation.class.inc which dropped fields from the data array if the 'novalidate' or 'nondb' option was set in the $fieldspec array.
- updated dml.pgsql.class.inc to deal with 'FOR UPDATE cannot be applied to the nullable side of an outer join' error.
- updated file 'includes/browser_detection.inc' to version 5.8.0

2017-10-05, version 2.07.0
Database changes:
- run script audit\sql\mysql\alter_table(2017-09-18).sql in order to change the structure of the AUDIT database

Other changes:
- increased size of session_id on php_session table to allow for change implemented in PHP 7.1.0
- updated logon screen to add 'Strict-Transport-Security: max-age=31536000; includeSubDomains' to HTTP header when HTTPS is available to turn on HTTP Strict Transport Security (HSTS).
- updated all links in menu bar, breadcrumbs and submit buttons to include a token to prevent CSRF attacks.

2017-09-01, version 2.06.0
Database changes:
- none

Other changes:
- removed the ampersand from all '$dbobject =& RDCsingleton::getInstance()' calls as it now generates a warning that only variables can be passed by reference.
- updated std.batch.inc so that it looks for ini fles in the sequence batch.ini, htaccess and user.ini, and will only process the first one that it finds.
- updated std.table.class.inc so that validateUpdate() method can be limited to primary or secondary validation only instead of both.
- updated std.update1.inc and std.output4.inc to call validateUpdate() with the correct switch.
- updated std.table.class.inc so that the _sqlProcessJoin(), validateDelete(), deleteRelations(), eraseRelations() and getForeignData() methods will use singletons for any child objects.
- updated std.table.class.inc so that the getFieldSpec_original() method will store its data in a static variable so that further calls will use this static variable instead of reading the file from disk again.
- fixed std.add1.inc, std.add2.inc, std.multi1.inc, std.update1.inc and std.update3.inc where '$dbobject' was mis-spelt as '$dbobect'.
- updated include.library.inc so that the getLanguageArray() and getLanguageText() functions will store any data in static variables which are keyed by language code and subsystem to prevent the same file being read from disk more than once.
- updated include.library.inc so that the pasteData() function will call the getForeignData() method to retrieve data from parent tables.
- updated include.xml.php.inc and std.data_field.xsl so that if the 'button' control is set to an array then the 'subtype' value (which can be 'submit' or 'button') will be used for each entry in that array.
- updated include.xml.php5.inc so that the XSLTransform() method will provide the contents of the XML document in the error log should the transform fail for any reason.

2017-08-03, version 2.05.0
Database changes:
- run script menu\sql\mysql\alter_table(2017-07-20).sql in order to change the structure of the MENU database
- run script menu\sql\mysql\menu.menu_export(2017-07-20).sql in order to change the contents of the MENU database.

Other changes:
- updated MNU_USER_ROLE table to include start_date and end_date so that roles can be activated or deactivated on certain dates.
- updated OUTPUT4 task so that the screen now shows a sequence number and a label for each column which can be exported to the CSV file. ***** NOTE THAT YOU WILL HAVE TO REBUILD EACH OUTPUT4 SCREEN STRUCTURE FILE USING THE TEMPLATE SCRIPT IN DEFAULT/SCREENS/EN/OUTPUT4.SCREEN.INC, NOT FORGETTING TO REPLACE '#tablename#' WITH THE ACTUAL TABLE NAME. *****
- fixed bug which prevented 'where dt between curdate() and curdate() + interval 365 day' from working.
- fixed bug in 'std.add4.inc' where the call to getInitialDataMultiple() was using $where_array instead of the $where string.
- updated 'std.validation.class.inc' to reject any value for a primary or candidate keys which contains whitespace characters.
- fixed bug in 'getLanguageArray()' and 'getLanguageText()' so that they do not read in the the message file more times than is necessary.

2017-07-01, version 2.04.2
Database changes:
- None

Other changes:
- fixed bug in mnu_user.class.inc which caused the user_password field to be hidden in the 'Add User' task. This is not a good idea as it is a required field.
- modified std.update1.inc so that after the call to $dbobject->getData() the result in $fieldarray is converted from an indexed array to an associative array.
- modified std.singleton.php5.class.inc so that if the input argument contains more than one '/' it will be treated as a complete path name and will not be subject to any adjustments.
- fixed bug in std.search1.inc which failed to deal properly with leaving a popup screen without having made a selection.
- modified include.session.inc to pass $where, $selection and $search strings as arguments on the exec($command_line) call to get around the problem which caused these values to be not retrieved from the $_SESSION array.
- modified std.table.class.inc so that after a call to $dbobject->getData() from anything other than a page controller a call to ->getForeignData() will be made automatically to include any missing data from foreign tables. This will prevent the need to perform this operation manually.
- fixed bug in _dml_ReadBeforeUpdate() method of std.table.class.inc so that the select string is not adjusted if it contains either '*' or '<tablename>.*'.

2017-06-14, version 2.04.1
Database changes:
- None

Other changes:
- fixed problem in filepicker screens by renaming 'file', 'size' and 'date' fields to 'file_name', 'file_size' and 'file_date'. This to to resolve confusion between 'size' being used as an attribute as well as a name. I also changed the name 'icon' to 'image' as a an image may or may not be an icon.
- fixed bug in a batch process started from a navigation button which caused it to lose the current selection criteria.
- fixed bug in 'List Database' screen which caused it not to show the subsystem name.

2017-06-01, version 2.04.0
Database changes:
- run script dict\sql\mysql\alter_table(2017-05-01).sql in order to change the structure of the DICT database
- run script menu\sql\mysql\alter_table(2017-05-01).sql in order to change the structure of the MENU database
- run script dict\sql\mysql\dict.menu_export(2017-05-01).sql in order to update the contents of the MENU database

You are advised to re-export all your application database details after this update.
You are advised to re-export all your application subsystem details after this update.

Other changes:
- updated all XSL stylesheets to output web pages with DOCTYPE for HTML5 instead of XHTML.
- modified std.table.class.inc so that if the getExtraData() method is given an associative array it will return an associative array. If it is given an indexed array it will return an indexed array.
- modified include.library.inc so that the array_update_indexed() function wil reset $fieldarray to ensure that the pointer starts at the first entry.
- modified include.library.inc so that the formatNumber() function will exit if the input argument is not numeric.
- modified std.validation.class.inc so that the validateNumber() will round any values for minvalue and $maxvalue to remove any unwanted decimal places.
- updated std.multi2.inc so that the sort order used in the parent form is used for the inner entity.
- updated std.multi3.inc to fix 'undefined variable' when returning from a child form.
- modified dict_database_s02.class.inc so that child relationships are not exported unless the child table is in the same database as the parent.
- updated std.datevalidation.class.inc so that it throws exceptions instead of populating $this->errors.
- updated include.xml.php5.inc so that if a pageis displayed using HTTPS then the hyperlink for the 'help' page will also use HTTPS.
- modified the logon screen so that when switching between HTTP and HTTPS it passes the session_id via a cookie instead of in the URL.
- updated tables in the DICT database to create consistent names for XX_NAME and XX_DESC columns:
-- the DICT_COLUMN.COLUMN_DESC column is renamed to COLUMN_NAME varchar(80)
-- the DICT_COLUMN.COL_COMMENT column is renamed to COLUMN_DESC text
-- the DICT_DATABASE.DATABASE_DESC column is renamed to DATABASE_NAME varchar(80)
-- the DICT_DATABASE.DB_COMMENT column is renamed to DATABASE_DESC text
-- the DICT_RELATIONSHIP.RELATION_DESC column is renamed to RELATION_NAME varchar(80)
-- the DICT_RELATIONSHIP.REL_COMMENT column is renamed to RELATION_DESC text
-- the DICT_RELATIONSHIP.REL_TYPE column is renamed to RELATION_TYPE char(3)
-- the DICT_TABLE.TABLE_DESC column is renamed to TABLE_NAME varchar(80)
-- the DICT_TABLE.TBL_COMMENT column is renamed to TABLE_DESC text
- updated tables in the MENU database to create consistent names for XX_NAME and XX_DESC columns:
-- the MNU_ACCOUNT.ACCOUNT_DESC column is added
-- the MNU_FAVOURITE.TASK_DESC column is renamed to TASK_NAME
-- the MNU_PATTERN.PATTERN_DESC column is renamed to PATTERN_NAME
-- the MNU_PATTERN.PATTERN_DESC column is added
-- the MNU_ROLE.ROLE_DESC column is renamed to ROLE_NAME
-- the MNU_ROLE.ROLE_DESC columnis added
-- the MNU_SAVED_SELECTION.SELECTION_DESC column is renamed to SELECTION_NAME
-- the MNU_SUBSYSTEM.SUBSYS_DESC column is renamed to SUBSYSY_NAME
-- the MNU_SUBSYSTEM.SUBSYS_DESC column is added
-- the MNU_TASK.TASK_DESC column is renamed to TASK_NAME
-- the MNU_TASK.TASK_DESC column is added
-- the MNU_TASK_ALT.TASK_DESC column is renamed to TASK_NAME
-- the MNU_TASK_ALT.TASK_DESC column is added
-- the MNU_TODO.ITEM_DESC column is renamed to ITEM_NAME
-- the MNU_TODO.ITEM_NOTES column is renamed to ITEM_DESC
- updated the MNU_USER table to replace the pswd_chg_date and pswd_chg_time columns with a single pswd_change_datetime
- updated the MNU_USER table to replace the logon_date and logon_time columns with a single logon_datetime


2017-04-02, version 2.03.0
Database changes:
- run script menu\sql\mysql\alter_table(2017-02-12).sql in order to change the structure of the MENU database

Other changes:
- fixed bug in where2indexedArray() so that it deals with '(SELECT COUNT(*) FROM .....) = 0' properly.
- modified processing of $this->no_foreign_data so that it will still process _cm_getForeignData() but skip processing of $this->parent_relations array.
- added column FORCE_PSWD_CHG to table MNU_USER which will force the user to change his password at the next logon regardless of any policy on days or logons. This flag will be set to 'Y' whenever a user's password is reset, but only if the corresponding 'Force Change?' value on the Menu Control record is set to 'Y'.
- modified processing of WHERE string to allow both of the following:
-- lower(product_name) LIKE '%hello%'
-- product_name ILIKE '%hello%'
- added the ability to filter records from the display in the _cm_post_getData() method.

2017-02-01, version 2.02.0
Database changes:
- run script workflow\sql\workflow.menu_export(2016-11-02).sql in order to update the contents of the MENU database

Other changes:
- found and fixed a number of 'Undefined index' and 'Undefined variable' notices.
- fixed a bug in the logon class which failed to include the user_id when writing to the AUDIT_LOGON_ERRORS table.
- added new tasks to the Workflow subsystem to allow a case status to be changed in the following ways (a) from OPEN to SUSPENDED, (b) from OPEN to CANCELLED, (c) from SUSPENDED to OPEN, and (d) from SUSPENDED to CANCELLED. You will need to run script workflow\sql\workflow.menu_export(2016-11-02).sql in order to update the contents of the MENU database.
- modified 'std.table.class.inc' so that the insertMultiple() method can perform updates and deletes as well as inserts.
- modified 'std.table.class.inc' so that the updateMultiple() method can perform inserts and deletes as well as updates.
- modified 'include.session.inc' so that the initSession() function will strip all single and double quotes from the $_GET array before it is processed.

2016-11-01, version 2.01.0
Database changes:
- none

Other changes:
- updated 'include.xml.php5.inc' so that when a LIST pattern is executed it will not read the MNU_TASK data for popup tasks in order to obtain the text for the tooltip.
- tidied up batch processing by copying file 'std.batch.inc' from each subsystem directory and renaming it as 'include.batch.inc' in the parent directory. Updated each 'std.batch.inc' so that it refers to '../include.batch.inc'. Also copied 'batch.ini.default' and 'batch.ini' from each susbsystem directory into the parent directory. This means that I can update the code in '../include.batch.inc' in just one place instead of multiple directories, and that each installation needs only one copy of 'batch.ini'.
- included file 'custom_javascript.class.inc' which will allow javascript to be specified globally for all forms and/or all fields.
- created 'javascript' directory to contain scripts 'jquery-3.1.1.min.js' and 'jquery.cookie.min.js' which will disable a submit button when it is pressed and overlay it with a spinning red circle. This will prevent the problems caused by a user who presses a submit button more than once, thus sending multiple requests to the server.
- modified 'include.xml.php5.inc' so that call to form_level_js() in 'custom_javascript.class.inc' is only performed once for each form.
- updated Workflow system to allow more than two arcs on an implicit-OR-split, and removed restriction that one of the transitions must be triggered via a TIMER.
- fixed bug which prevented putting all Radicore schemas into a single database.
- modified 'database(output2).php' so that the PDF output shows the count of tables and relationships in each subsystem.


2016-10-01, version 2.00.0
Database changes:
- run script menu\sql\mysql\alter_table(2016-08-30).sql to alter the structure of the MENU database.

Other changes:
- dropped support for PHP4 and opened support for PHP7. This is because the PHP4 class constructors, which worked in both PHP4 and PHP5, will no longer work in PHP7. I have updated all classes to use the PHP5 constructors which will work in PHP5 and PHP7, but not in PHP4.
- changed MNU_TODO table by adding a column called 'object_id'. This is an optional field which is not used by the framework but by an application which was built using the framework.
- fixed bug in getCount() method where the SQL statement starts with whitespace.
- modified the logging of sql queries so that they are now written to the '<subsystem>/sql/logs' directory instead of the '<subsystem>/sql' directory, and to include timings down to the millisecond. See <a href='http://www.radicore.org/viewarticle.php?article_id=23#faq51'>FAQ51</a> for details.
- added function dateDiff_YYMM() to get the difference between two dates in years and months.
- updated 'include.session.inc' and 'std.update4.inc' so that when a task of the UPDATE4 pattern is activated through a navigation button without any individial rows being selected then any search criteria currently being used in the parent task will be passed down to the child task.
- updated all page controllers to remove the calls to START_TRANSACTION and COMMIT/ROLLBACK around the processing of custom buttons as they serve no purpose.
- updated 'include.session.inc' so that if scriptNext() is used when processing a custom button then it is treated just like a popup in that when the form containing the custom button is reactivated it will not re-read the database and therefore lose any data in the form which has not yet been saved.
- updated 'dml.sqlsrv.class.inc' to use 'SELECT SCOPE_IDENTITY()' instead of 'SELECT @@identity' to fix the bug reported in <a href='http://radicore.org/fud/index.php?t=msg&th=2288'>http://radicore.org/fud/index.php?t=msg&th=2288</a>.
- updated setJavaScript() in include.xml.php5.inc so that the contents of $javascript['foot'][]['code'] is processed correctly.

2016-08-01, version 1.97.0
Database changes:
- none

Other changes:
- added function generateGUID() to incude.library.inc
- updated std.add1/2/5.inc to include call to $object->quitButton() when CANCEL button is pressed.
- added the generateGUID() function to include.library.inc
- updated SQL Server processing to avoid the error 'New transaction is not allowed because there are other threads running in the session'. Calls to $dbobject->getDataSerial() and $dbobject->fetchRow() are now done using a separate instance of the database driver. This means that if any database updates are performed after a call to ->fetchRow() the call to ->startTransaction() will no longer fail.
- updated 'std.validation.class.inc' to disallow a '%' character from being used in a primary or unique key as this is used as the 'wildcard' character in database searches.
- updated 'std.filepicker.list1.xsl' to allow video files as well as still images.
- updated 'std.table.class.inc' so that when a task is initiated via append2ScriptSequence() with 'action' = 'OK' (meaning that the QUIT button is invalid and the task should only be terminated with a SUBMIT button) then the QUIT/CANCEL button is removed so that it cannot be pressed.


2016-07-01, version 1.96.0
Database changes:
- none

Other changes:
- fixed bug in 'logon.class.inc' and mnu_user.class.inc' which failed to deal with passwords which had not been encrypted before being stored in the database.
- fixed bug in 'mnu_user.class.inc' which which only deal with users with the same value for rdcaccount_id as the logon user when toggling between encrypted and unencrypted passwords.
- fixed bug in 'std.validation.class.inc' which rejected a field's subtype of 'video'.
- fixed bug in 'dml.pgsql.class.inc' regarding the error 'FOR UPDATE cannot be applied to the nullable side of an outer join'.
- fixed bug in 'dml.sqlsrv.class.inc' where referencing an alias name which is the product of a previous expression has to be replaced by the original expression.
- modified 'include.xml.php5.inc' and 'include.session.inc' to deal with popup buttons which can appear in different entities in the same multi-entity transaction pattern. The button's value will now be in the format 'task#<zone>#<task_id>' where '<zone>' can be either 'dbouter', 'dbmiddle' or 'dbinner'. When returning from the popup this makes it easier to pass the popup result to the correct table object.
- fixed bugs in 'mnu_initial_value_role(multi3)a/b.php', 'mnu_initial_value_user(multi3)a/b.php' and 'mnu_role_taskfield(multi3)a/b.php' where the query produced the wrong result in certain circumstances.
- modified all 'dml.???.class.inc' files so that when looking for a change in a unique key during an update it will use strcasecomp() to perform a case-insensitive comparison.
- modified 'std.pdf.class.inc' so that the 'ignore_if_empty' option will now work in 'Body contents (detail view - additional data)'.
- modified 'include.xml.php.inc', 'std.buttons.xsl' and 'std.data_field.xsl' so that tooltips are now displayed for action buttons amd popup buttons.
- fixed bug which prevented creation of new records on MNU_ACCOUNT table.
- fixed bug when a user with a NULL rdcaccount_id used Copy+Paste on a user record which had rdcaccount_id > 1. The new record must use the same rdcaccount_id as the copied record whereas the bug caused it t be set to 1 (the shared account). 

2016-06-01, version 1.95.0
Database changes:
- run script menu\sql\mysql\alter_table(2016-05-18).sql to alter the structure of the MENU database.
- run script menu\sql\mysql\menu.menu_export(2016-05-18).sql to alter the contents of the MENU database.

Other changes:
- modified handling of custom buttons in page controllers ADD5, LINK1, MULTI2/3/4/5/6. By default the customButton() method will only be called on the object in which the button was actually defined, but this can be overridden by setting $this->allow_all_zones=TRUE in other objects.
- fixed bug in 'mnu_initial_value_role_s01.class.inc' by excluding 'start_task_id' from the WHERE clause which was introduced in version 1.94.0.
- fixed bug which caused role_id on 'Search User' screen to be mandatory instead of optional.
- fixed bugs with 'Search Workitem' and 'Search Token' screens in WORKFLOW subsystem.
- fixed bug in 'Generate PHP Script (b)' when it tried to create an entry on MNU_MENU with a value for button_text which was too long. It now uses the table identity instead of the table description.
- added $rownum as a second argument to the _cm_getForeignData() method to identify the row number for the $fieldarray argument.
- added column 'is_documentation_only' to the 'mnu_task_field' table. This defaults to 'N', but can be set to 'Y' when the entry should not be used as a prompt when adusting the contents of the MNU_INITIAL_VALUE_USER or MNU_INITIAL_VALUE_ROLE tables.
- added tables MNU_TASK_QUICKSEARCH and MNU_TASK_QUICKSEARCH_ALT so that populating the QuickSearch area on the screen can be done by adding entries to the MENU database instead of adding code to the table class.
- amended the data dictionary to add the 'mustvalidate' option to the $fieldspec array.
- amended the data dictionary to add 'video' to the list of subtypes.
- amended 'std.table.class.inc' so that the member variable called $this->reuse_previous_select has a default value of TRUE instead of FALSE as TRUE is the most common value that is required.

2016-04-01, version 1.94.0
Database changes:
- none

Other changes:
- modified 'dict_column.class.inc' so that when inporting column definitions it does not nullify existing values for 'align_hv' or 'align_lr'.
- fixed bug in 'mnu_subsystem_s01.class.inc' (Export Subsystem) which escaped the ' (double quote) character which caused such strings as '<a href='...'>' to be corrupted when reloaded.
- fixed bug in 'mnu_subsystem_s01.class.inc' (Export Subsystem) which caused data for mnu_user_role to be labelled for the mnu_initial_value_user table.
- updated the 'fileupload1' pattern to include a call to getExtraData() so that the messages can be customised.
- modified the use of rdcaccount_id so that access to a table's data depends on the value in the user's MNU_USER record:
  - if NULL then the user can read data for any account but can only add/update/delete records for rdcaccount_id=1 (the shared account)
  - if = 1 then the user can only read/add/update/delete data for the shared account
  - if > 1 then the user can read data for that account and the shared account, but can only add/update/delete records for that non-shared account
- modified 'std.validation.class.inc' to use the filter_var() function for email addresses and numbers.

2016-01-30, version 1.93.0
Database changes:
- none

Other changes:
- Added 'u' modifier to all preg_replace calls to fix the problem reported in http://radicore.org/fud/index.php?t=msg&th=1896&goto=5293&#msg_5293
- Changed 'mnu_subsystem_s01.class.inc' so that when exporting a subsystem it includes MNU_TASK entries with TASK_TYPE = 'MENU' as well as 'PROC'.
- Changed 'mnu_subsystem_s01.class.inc' so that when exporting a subsystem it includes MNU_ROLE entries for each role that has one of the subsystem's tasks on the MNU_ROLE_TASK table.
- Changed 'std.list2.inc' and 'std.list3.inc' to use function 'getForeignKeyValues()' to help build the WHERE string to access the child table.
- Modified the Workflow process so that if a transition is a batch task, the next transition can have an 'AUTO' trigger provided that it is also a batch task. It is possible for an online task to be followed by a batch task with an 'AUTO' trigger which is then run immediately in the same session, but it is not possible for a batch task to be followed by an online task with an 'AUTO' trigger. A transition which is a batch task can be followed by an online task with a 'USER' trigger as this does not actually run the online task - it only updates the database to enable the workitem for that online task which then prompts the user for action during an online session.
- Modified the Dictionary Export process so that any column with the column_desc field set to 'DEPRECATED' will be excluded from the $fieldspec array. This will allow a deprecated column to remain in the physical database, but the table class will act as if it is not there.
- Modified the way that batch (command line) tasks are activated on Windows so that if the PHP.EXE program is not correctly defined on the PATH environment variable it can be overridden by the PATH_TO_PHP_EXECUTABLE constant in the config.inc file.

2015-12-12, version 1.92.0
Database changes:
- run script 'audit\sql\mysql\alter_table(2015-10-15).sql' to alter the structure of the AUDIT database.
- run script 'menu\sql\mysql\alter_table(2015-11-19).sql' to alter the structure of the MENU database.
- run script 'menu\sql\menu.menu_export(2015-11-20).sql' to alter the contents of the MENU database.

Other changes:
- modified tables 'audit_ssn' and 'audit_trn' in the AUDIT database to replace separate 'date' and 'time' columns with a single 'datetime' column. This will allow more accurate selections between different dates.
- modified the 'Menu Control' screen to allow the 'Audit Delete' values to specify a time period in days, weeks, months or years instead of just years.
- modified 'std.csv.class.inc' to include the 'appendToCSV()' method to allow additional data to be appended to the CSV output following the calls to 'getData_serial()' and 'fetchRow()'.
- fixed bug in workflow engine caused by a case being started by a user whose rdcaccount_id is set to '1'.
- updated 'std.output4.inc' to allow the use of popup buttons, custom buttons and javascript.
- fixed bug in 'std.fileupload1.inc' caused by wrong arguments being passed to SplFileInfo object.
- amended the MENU database by adding tables MNU_SAVED_SELECTION and MNU_SAVED_SELECTION_DATA for use in transations which use the OUTPUT4 pattern.
- fixed bug in 'dml.oracle.php.class.inc' when performing getData_serial() with $rows_per_page > 0.
- fixed bug in 'dict_table_s02.class.inc' when exporting dictionary data as reported in http://radicore.org/fud/index.php?t=msg&goto=5177
- updated 'std.table.class.inc' to add the $offset argument to the _cm_popupCall() method so that if this is used in an area with multiple rows it will show the HTML row number (which starts from 1 not zero).
- updated '_cm_pre_getData)' method in 'std.table.class.inc' to rename 3rd argument from $fieldarray to $parent_data.
- updated 'dict_table_s04.class.inc' so when generating the scripts for a LINK1 pattern it will allow the INNER table to be in a different database.
- updated 'std.table.class.inc' to rename '_validateInsert()' and '_validateUpdate()' methods to '_validateInsertPrimary()' and '_validateUpdatePrimary()' in order to avoid confusion with other validation methods with similar names.


2015-10-01, version 1.91.0
Database changes:
- run script 'menu\sql\<dbms>\alter_table(2015-09-20).sql' to rename 'mnu_user.language_code' to 'mnu_user.language_id'.

Other changes:
- fixed bug in std.update1.inc which erroneously called the getInitialData() method after the PASTE button was pressed.
- modified 'std.treenode.xsl' to allow additional names in 'css_class' to be added to the node description.
- fixed bug in 'std.multi5.inc' which caused the call to $dbinner->setParentData() to initialise $inner_data.
- updated 'std.search1.inc' to set $dbobject->no_foreign_data = FALSE instead of TRUE. This is because I have found it necessary to change it to FALSE more often than to leave it as TRUE, so the default setting should be the one that is most commonly used.
- updated 'std.filepicker1.inc' so that it automatically includes the quicksearch area for file or directory names. This removes the need for a separate 'Search' button on the navigation bar.
- updated 'include.xml.php5.inc' and 'std.head.xsl' to allow javascript to be added at the end of the <BODY> element.
- updated 'include.xml.php5.inc' and 'std.data_field.xsl' to allow custom buttons to be specifed by either the <input> or <button> controls. If you currently use any 'button' controls these may have to be changed to 'input' due to the way that the button text is displayed in the screen.
- fixed bug in 'std.multi2/3/4/5.inc' which caused a popup in the inner entity to return its result to the wrong row.
- updated 'include.xml.php5.inc' to allow 'rdc_fieldspecs' to be an alias of 'rdc_fieldspec', and to allow either to be used in the '_cm_formatData)' method as well as the '_cm_post_getData()' method.
- fixed bug in 'std.multi4.inc' which caused scrolling for the outer entity to fail.
- renamed column 'language_code' to 'language_id' in the MNU_USER table to be consistent with the MNU_LANGUAGE table.
- fixed bug in 'mnu_subsystem_s01.class.inc' which caused an invalid query to be generated when trying to export from the 'mnu_user_role' table.
- updated TCPDF library to version 6.2.12
- updated TINYMCE library to version 4.2.6

2015-07-01, version 1.90.0
Database changes:
- run script 'menu\sql\menu.menu_export(2015-06-23).sql' to add the 'directory(up)' task to the MENU database.

Other changes:
- fixed bug in 'validateDelete()' method within 'std.table.class.inc' which caused $errors array to be cleared out by calling '_examineWorkflowInstance()' method.
- updated 'where2array' and 'array2where' functions within 'include.library.inc' to cater for bitwise operations on columns such as 'WHERE col1 & 1 = 0'.
- fixed bug in 'dict_column.class.inc' which failed to show the size of columns of type 'bit'.
- fixed bug in 'php_session.class.inc' where the values for 'date_created' and 'last_updated' were set using PHP dates while the date comparison in the GC method (garbage collection) used 'now()' which is the current date as known to the database server. 'date_created' and 'last_updated' are now updated using 'now()'.
- updated all the relevant 'dml.???.class.inc' classes to convert 'now()' to the equivalent function in that DBMS.
- fixed bug in 'std.tree1.inc' and 'std.tree2.inc' which prevented selected rows from staying selected after returning from a child task with the 'locked' option set.
- modified 'std.filepicker1.inc' so that it will list directories instead of file if the $this->picker_filetypes property is set to the string 'directory' instead of an array of file extensions. This can be used in a task which can be added as a navigation button to a standard filepicker task to switch to a subdirectory within the current directory. See <a href='http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq162'>FAQ162</a> for details.
- added a new task called 'directory(up)' to the 'Miscellaneous' subsystem which can be added as a navigation button on a filepicker task to go up a directory level instead of down to a selected subdirectory.
- updated 'std.fileupload1.inc' so that when it is started from a navigation button in a filepicker task it will set its directory to the current directory in that filepicker task.
- modified the screen layout used by 'std.fileupload1.inc' so that it shows the directory into which the file will be uploaded.

2015-05-05, version 1.89.0
Database changes:
- run script 'audit\sql\mysql\alter_table(2015-03-29).sql' to alter the 'session_data' column from TEXT to BLOB.
- run script 'workflow\sql\mysql\alter_table(2015-05-01).sql' to update the structure of the WF_ARC table in the WORKFLOW database.
- run script 'menu\sql\mysql\alter_table(2015-05-01).sql' to update the structure of the MNU_USER table in the MENU database.

Other changes:
- updated the 'getExtraData()' method within 'std.table.class.inc' so that the call to '_cm_getExtraData()' comes after the call to '_cm_changeConfig()' instead of before. This allows any extra data to be fetched after the object's configuration has been changed.
- updated 'dml.sqlsrv.class.inc' to deal with conversion of CONCAT, CONCAT_WS and GROUP_CONCAT functions.
- fixed bug in 'mnu_task(upd1).php' which caused the 'Run at End' and 'Run at Cancel' popups to show only the current task instead of everything but the current task.
- updated the 'php_session' table in the AUDIT database from a TEXT to a BLOB datatype so that it can handle unusual characters. This became evident in the SQLSRV driver, but may also affect the MYSQL driver.
- updated 'php_session.class.inc' so that the 'session_data' column for the SQLSRV database is converted from TEXT to BINARY using the CONVERT(varbinary(max), ...) function.
- updated 'std.table.class.inc' to include the $allow_zero_rows property. This is for use in the LIST3 pattern.
- updated 'std.list3.inc' so that if no rows are read in the 'middle' entity, but it has the $allow_zero_rows property set, it will continue to the 'inner' entity without displaying an error. This will effectively make the 'middle' entity optional.
- updated 'std.table.class.inc' to include the 'validateChooseButton()' and '_cm_validateChooseButton()' methods.
- updated 'include.session.inc' so that when the 'chooseButton()' function is called it will pass the selection to the object's 'validateChooseButton()' method. This will allow further processing to take place after the selection has been made and before it returns control to the calling script.
- updated 'std.table.class.inc' to include the 'getParentClass()' and 'getChildClass()' methods which will return the names of those classes, if they exist in the current Transaction Pattern.
- updated 'std.validation.class.inc' to convert a boolean value from TRUE/FALSE to the equivalent 'true' or 'false' value provided in the $fieldspec array.
- updated the WF_ARC table in the WORKFLOW database to replace the 'pre_condition' field with three separate fields to remove the need to use the 'eval()' function which could possibly be used to inject malicious code.
- updated the MNU_USER table in the MENU database to increase the size of the 'user_password' column. This is to allow a future change to the password hashing/encryption algorithm.

2015-03-01, version 1.88.0
Database changes:
- none

Other changes:
- modified 'std.csv.class.inc' so that the call to ini_set('auto_detect_line_endings', true) comes before the call to fopen(), not after. This is a result of https://bugs.php.net/bug.php?id=63341
- modified 'getChanges()' function in 'include.library.inc' so that the test uses '==' instead of '===' as this was saying that the value '6' (string) was different from the value 6 (long).
- modified 'getCount()' method in several 'dml.???.class.inc' files so that it can deal correctly with a $where string that spans multiple lines.
- fixed bug within 'ddl_showTableKeys()' method in file 'dml.sqlsrv.class.inc' to include 'constraint_name' in the list of selected fields.
- modified 'dict_table_key.class.inc' so that the key name 'PRIMARY' is in uppercase and all other keys are in lowercase.
- modified 'dict_column_s01.class.inc' so that the call to '$keyobj->getInitialDataMultiple($this->where)' is not executed if there are any errors produced by a previous call.
- fixed bug in 'std.update1.inc' which lost scrolling area after pressing 'SUBMIT' button.
- fixed bug in 'logon.php' which failed to update AUDIT_LOGON_ERRORS and MNU_USER table if the logon failed and the database engine was transactional. Previously it followed the convention where any errors would cause a rollback, but in this case it must always perform a commit in order to log the error.
- fixed bug in 'std.datevalidation.class.inc' which allowed a date such as '1970-01-001' to be accepted as valid.
- fixed bug in 'std.datevalidation.class.inc' which failed to strip off the microseconds from timestamps HH:MM:SS<.microseconds>
- updated 'std.fileupload1.inc' so that if $this->allow_multiple = TRUE then a SUBMIT+stay button will be shown to prevent the task from quitting after the file has been uploaded, thus allowing another file to be uploaded.
- updated 'std.fileupload1.inc' so that it will populate a $files array for each uploaded file. This will contain the following:
	$file['url'] = fully-qualified file name
    $file['filename_orig'] = 'example.pdf'
    $file['filename'] = 'example'
    $file['extension'] = 'pdf'
    $file['size'] = 23400
- amended 'std.table.class.inc' so that after returning from a fileupload task the contents of the $files array will be made available in an additional argument called $return_files in the _cm_reset(), _cm_popupReturn() and _cm_post_popupReturn() methods.

2014-12-01, version 1.87.0
Database changes:
- none

Other changes:
- fixed bug in 'std.pdf.class.inc' so that can it can trap and discard any Byte Order Marks which are written to the output stream when a file which is encoded in UTF-8 is included, such as when the getLanguageText() function is called.
- fixed bug in 'std.multi1.inc' so that if a call to getData($where) returns an empty row it will be filled with the contents of the $where string so that a new record can be created.
- fixed bug in 'std.table.class.inc' so that the formatData() method will not call the getInternalDate() method on an empty date otherwise it will generate an error.
- updated 'std.filepicker1.inc' so that it will use the 'Order By' value in the task screen for its default sort sequence.
- fixed bug in 'mnu_menu.class.inc' which, in some circumstances, did not remove menu buttons which were not accessible by the user.
- fixed bug in the data dictionary which failed to show the choice of unique keys when maintaining the relationship between two tables.
- fixed bug with where2array() function in 'include.library.inc' which could not deal with tabs and newlines in the input string.
- fixed bug with executeQuery() method in 'std.table.class.inc' so that when splitting a string of queries into an array using ';' as a delimiter it now ignores ';' characters inside quoted strings. This fixes bug http://radicore.org/fud/index.php?t=msg&th=1410
- fixed bug in isPkeyComplete() function in 'include.library.inc' which failed to deal with a compound unique key where an optional column was not provided. This should only cause an error when a NOT NULL column is not provided.
- fixed bug with 'Generate PHP scripts (b) - Enter Details' which failed to show the outer database name and showed an empty dropdown list for the outer table name in the DEL4 pattern. This fixes bug http://radicore.org/fud/index.php?t=msg&th=1414
- updated PDF processing to allow 'padding' values to be set between the cell boundary and the cell contents.
- updated PDF processing to allow the 'y' coordinate of one cell to be saved so that it can be used to position another cell.

2014-09-01, version 1.86.0
Database changes:
- none

Other changes:
- modified processing of datetime fields so that when the input contains only a date portion a time portion will be appended, and this will be taken from the default value. For start_date fields this will normally be '00:00:00' while for end_date fields this would be '23:59:59'.
- modified 'std.tree_view2.inc' to set $GLOBALS['mode'] to 'tree' instead of 'read', and to call the 'getExtraData()' method on the outer entity.
- fixed bug in 'std.multi1.inc' which removed all data except the primary key for a new record after returning from a popup screen.
- fixed bug in 'std.buttons.xsl' and 'include.xml.php4/5.inc' to make the word 'Selections:' (in the navigation bar) translatable instead of hard-coded.
- fixed bug in validateSortItem() function so that if the object's table name is at the start of the FROM string it will not look for any alias names for that table.
- fixed bug in 'std.list2.inc' and 'std.list3.inc' so that when the RESET button is used it will not lose the ORDERBY sequence for the outer entity.
- added the ability to specify that a particular field in a particular row in a multi-row update area, such as in a MULTI2 pattern, should be set to 'noedit'. This can be achieved by adding the pseudo-column 'rdc_fieldspec['fieldname']' with the value 'array('noedit' => 'y')' to the row in question.
- modified the workflow system to enable a task to set the user_id of a workitem record to a particular value. See <a href='http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq161'>FAQ161</a> for details.
- fixed bug in 'logon.class.inc' which generated an invalid SQL query when trying to set 'is_disabled' to TRUE after the number of failed logon attempts went over the limit.
- amended 'std.table.class.inc' so that for the 'insertRecord()' and 'updateRecord()' methods the call to $this->convertTimeZone is now done after the call to '_cm_pre_insertRecord()' and '_cm_pre_updateRecord()' respectively. This is to allow any datetime validation to take place before the values are converted from the client timezone to the server timezone.

2014-07-01, version 1.85.0
Database changes:
- run script 'dict/sql/mysql/alter_table(2014-06-14).sql' to change the structure of the DICT database.
- run script 'menu/sql/menu.menu_export(2014-06-26).sql' to alter the contents of the MENU database

Other changes:
- fixed bug in 'dict_table_key.class.inc' which failed to update correctly after columns were either added to or removed from the primary key.
- fixed bug in 'dml.pgsql.class.inc' which failed to set the auto_increment attribute when importing a table's structure into the Data Dictionary.
- updated table 'dict_column' in the DICT database to increase size of 'col_default' column from 40 to 255 characters. This is to allow default values such as 'nextval('test_autoincrement_id_seq'::regclass)' which may appear in PostgreSQL databases.
- fixed bug in 'mnu_task.class.inc', 'mnu_menu.class.inc', 'mnu_nav_button.class.inc' and 'mnu_favourite_s04.class.inc' so that queries test for the value 'Y' instead of TRUE otherwise they will fail when using the PostgreSQL database.
- modified 'std.tree_view1.inc' and 'std.tree_view2.inc' to allow pagination, but this is for the entries which exist at level 1 only.
- added pattern 'OUTPUT6' to extract data from a Tree View and output it to a CSV file. 

2014-06-01, version 1.84.0
Database changes:
- run script 'menu/sql/mysql/alter_table(2014-05-07).sql' to change the structure of the MENU database.

Other changes:
- modified 'php_session.class.inc' so that it ignores $GLOBALS['server_timezone'] when setting the 'date_created' and 'last_updated' columns. This was causing problems with session garbage collection when the application timezone was different from the database timezone.
- modified 'dml.pgsql.class.inc' so that it sets the database timezone to be the same as date_default_timezone_get();
- fixed bug in 'dml.oracle.class.inc' which caused an incorrect conversion of 'DATE_SUB(field1 - INTERVAL $field2 unit)' to '($field1 - INTERVAL '$field2' $unit)'.
- fixed bug when attempting to use the 'recover password' option on the logon screen.
- modified the MNU_LANGUAGE table to increase the size of the date_format columns. This is to allow for Asian dates which contain symbols.
- modified 'std.filepicker1.inc' so that if the directory contains more than 2000 files the file names will be read once and stored in a cache instead of being read from disk each time. The cache will be per session, and if the RESTART button is pressed it will be rebuilt.
- added function 'replaceScreenLabels()' to work in DETAIL screens to complement 'replaceScreenHeadings()' which works in LIST screens.
- updated 'std.pdf.class.inc' to allow all fonts to be changed if the language changes. Please refer to http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq159 for details.
- modified the logon process to check the record counts on the 'mnu_task_ip_address', 'mnu_user_ip_address', 'mnu_time_limit_role' and 'mnu_time_limit_user' tables so that if they are empty no further lookups are performed on all subsequent web pages in the current session.
- updated 'std.imap.class.inc' to use imap_errors() if imap_open() returns false.

2014-05-01, version 1.83.0
Database changes:
- run script 'menu/sql/mysql/alter_table(2014-04-17).sql' to change the structure of the MENU database.
- run script 'menu/sql/menu.menu_export(2014-04-17).sql' to change the contents of the MENU database.

Other changes:
- updated the MNU_LANGUAGE table in the MENU database to add the 'input_date_format' and 'output_date_format' columns. This is to allow the ability to specify different input and output date formats for different languages instead of having a single output format for each installation. The input date format will restrict the user's input to that format instead of allowing it to be free-format and having the software guess what it is by using regular expressions (this does not work satisfactorily with certain unicode character sets).
- updated the MNU_FAVOURITE table in the MENU database to add a UNIQUE index on user_id+task_id to prevent duplicate records.
- updated the MENU database to remove the 'role_id' column from the MNU_USER table and move it to the new MNU_USER_ROLE table. This will allow a user to have more than one role. One role must be marked as 'primary' to identify the starting transaction. 
- updated the MENU database to include the MNU_USER_ALT table which allows users to have different names in different languages.
- fixed bug in 'dml.*.class.inc' which prevented a candidate key from being changed from something to NULL.
- updated 'std.csv.class.inc' so that when creating a CSV file it will by default set the BOM (byte order mark) to signify that the output is UTF8.
- updated login.php so that after a successful login the session_id is regenerated. This procedure was advised in https://wblinks.com/notes/secure-session-management-tips/
- updated htaccess.txt to include 'session.cookie_httponly 1'. This procedure was advised in http://simonholywell.com/post/2013/05/improve-php-session-cookie-security.html
- fixed bug in '_dml_updateSelection()' and '_dml_deleteSelection()' methods which used the current value in $this->rows_per_page to limit the number of rows affected. This prevented more than one record being processed if the current value of $this->rows_per_page was 1, such as in an UPDATE1 transaction. This value is now ignored, which means that the code will process all available records and not just the first one.
- modified the '__sleep()' method within 'std.table.class.inc' so that when the object is being serialised for storage in the session data the contents of $this->fieldarray will be modified to remove any fields which are not in the primary key. Note that the list of pkey fields can be temporarily adjusted by using the '_cm_getPkeyNames()' method. Note that this procedure is not performed if the current task has a pattern of ADD, UPD, MULTI or SRCH.
- fixed issue http://www.radicore.org/forum/index.php?t=msg&th=1089&goto=4133 which caused the audit trail to find zero records.

2014-03-07, version 1.82.0
Database changes:
- none

Other changes:
- modified 'std.table.class.inc' so that '_cm_getColumnNames()' method can be used to remove unwanted columns as well as set the initial value in the selection screen of the UPDATE4 task.
- modified 'std.search1.inc' so that it will accept a value for an ENUM field which is either a numeric index or a string representation.
- modified 'runInBackground()' function within 'include.session.inc' so that if being run on linux/unix it will run the command line version of PHP and pass the session id as an argument, otherwise it will continue to start a parallel apache thread via the curl extension.
- modified 'initSession()' function within 'include.session.inc' so that it the session id can be obtained either from $argv (command line) or $_GET. 
- modified 'std.batch.inc' so that it will display any input values which have been supplied in the $argv array.
- modified 'mnu_nav_button.class.inc' so that when it modifies the SELECT clause to extract values from a foreign language table it removes the previous entry from the default table. This is to fix a problem when using the SQL Server database as it does not like duplicate names in the SELECT clause.
- fixed bug in 'dml.sqlsrv.class.inc' where it failed to change 'dbname.tblname' to 'dbname.dbo.tblname' in the SELECT clause.
- updated 'getExternalDate()' and 'getInternalDate()' methods inside 'std.datevalidation.class.inc' to provide a second optional argument to specify the format of the input/output date if it is different from the value defined in $GLOBALS['date_format'].
- modified 'std.table.class.inc' to include '$this->executeQuery()' method to execute an arbitrary query, or several queries. You can also use '$this->multiQuery()' as a synonym for this method.
- added the 'findDBName()' function to identify the correct database name to be used in an SQL query containing a JOIN.
- fixed bug in 'std.pdf.class.inc' which caused a cell containing only '0' (zero) to be printed as blank.
- modified 'dict_table_s02.class.inc' so that when creating '<table>.dict.inc' files it will include the database name independent of the subsystem name. This is to allow more than one database to exist in the same subsystem.

2013-12-01, version 1.81.0
Database changes:
- run script menu/sql/menu.menu_export(2013-10-17).sql to change the contents of the MENU database.
- run script dict/sql/dict.menu_export(2013-10-26).sql to change the contents of the MENU database.
- run script dict/sql/mysql/alter_table(2013-10-26).sql to change the structure of the DICT database.

Other changes:
- updated 'radicore.simplexmlelement.inc' (which is used to convert a PHP array to XML) so that if the first element is an index number then it is output as '<index index='0'>' instead of '<0>' which is invalid XML.
- updated 'include.library.inc' so that the format_xml_document() function will abort if the $doc->loadXML() or $doc->load() functions find an error.
- updated 'std.table.class.inc' to include '$this->fields_not_for_trimming' property. This is an indexed array containing names of fields whose contents should not be trimmed when either the '_validateInsert()' or '_validateUpdate()' function is called. By default all string values are trimmed to remove leading and trailing spaces, but in rare cases these may be valid parts of the string.
- fixed bug in 'std.validation.class.inc' when dealing with very large floating point numbers.
- fixed bug in getTableAlias1/2/3() functions in 'include.library.inc' when the string contains newline characters. 
- updated database import functionality in the Data Dictionary so that if multiple servers are defined in the CONFIG.INC file then it will show all databases from all those servers which have yet to be imported. Previously this was limited to only that server which contained the DICT database itself.
- updated 'dml.mysqli.class.inc' so that after an insert it will retrieve the value of an auto_increment field even if it is not the primary key.
- added 'MULTI6' to the list of transaction patterns.
- renamed task 'dict_table(popup1)' to 'dict_table(popup2)' as it actually uses the 'popup2' pattern.
- updated list of relationship types in the Data Dictionary to include 'IGNORE' which will cause no action to be taken on the child table when the parent is deleted.
- updated the DICT_RELATIONSHIP table to include a 'key_name' column to identify which key in the parent/senior table is to be used in the relationship. This will default to the PRIMARY key, but may be changed to one of the other UNIQUE keys.
- updated all page controllers to rename the 'submit' button to 'submitBtn' so that it does not clash with the javascript 'submit()' function.
- added the $object->updateFieldArray() and $this->_cm_updateFieldArray() methods to 'std.table.class.inc' so that if a form is submitted by the javascript 'submit()' function and not a SUBMIT button all changes can be made available to the application objects. All relevant page controllers have been updated to call this method.
- removed the '_cm_setParentData()' method as it is now redundant. Please refer to the getParentData() and setParentData() methods below.
- Where a transaction uses more than one object in a parent-child or parent-child-grandchild relationship the page controller will automatically populate the $parent_object and $child_object properties in each relevant object. The contents of $fieldarray in these objects can be obtained using either $this->getParentData() or $this->getChildData(). This data can also be updated using the $this->setParentData() or $this->setChildData() methods.
- modified 'dml.mysqli.class.inc' to that it will automtically sync MySQL's timezone with PHP's timezone in order to avoid the problem reported in http://www.radicore.org/forum/index.php?t=msg&th=688&goto=3870#msg_3870. It is therefore *IMPERATIVE* that you have the correct timezone specified in your php.ini file.
- created script fix_audit_tbl(batch).php to update the 'pkey' column in the 'audit_tbl' table to remove any errant spaces between the field name and the '=' sign. This prevents records from being retrieved when using the 'Audit Trail' button on the navigation bar.

2013-09-03, version 1.80.0
Database changes:
- none
Other changes:
- added '$this->no_foreign_data' flag to 'std.table.class.inc' to prevent 'getForeignData()' method from being called automatically.
- amended 'std.search1.inc' and 'std.multi5.inc' to set $this->no_foreign_data to TRUE.
- fixed bug in 'std.xml.php4/5.inc' when displaying error messages which are not associated with a field on the screen.
- fixed bug in 'xml2array' function inside 'radicore.xmlreader.inc' when an element contains a child element of the same name.
- amended 'std.batch.inc' and 'error.inc' to properly report errors with 'require()' function in batch jobs.
- removed the getBrowserLanguage(), matchBrowserLanguage() and saveLocaleFormat() functions from 'include.library.inc' and placed them inside 'language_detection.inc' so that they can be used without referencing 'include.library.inc'.
- updated the '_cm_getValRep()' method within 'mnu_user.class.inc' so that the $where argument is used in the call to getData(). This will allow the list of users to be filtered by the contents of the $where string.
- fixed bug in 'std.validation.class.inc' where a non-numeric value in a numeric field was not being reported correctly in the error message.
- updated 'dml.mysqli.class.inc' to output any MySQL warnings, such as silent data truncation, into the message area.
- updated 'mnu_subsystem_s01.class.inc' (subsystem export) to deal with MNU_TIME_LIMIT_ROLE and MNU_TIME_LIMIT_USER tables.
- updated all 'dml.*.class.inc' to include the '__toString()' method which can be used when the error handler is invoked.
- created 'error_logs' directory to hold the 'errorlog.html' file which is appended to by the error handler in 'error.inc'.
- upgraded TCPDF library to version 6.0.024.

2013-06-22, version 1.79.0
Database changes:
- added tables MNU_TIME_LIMIT_ROLE and MNU_TIME_LIMIT_USER to the menu database. Please run the following scripts:
-- radicore\menu\sql\mysql\alter_table(2013-04-21).sql - to amend the structure of the MENU database
-- radicore\menu\sql\menu.menu_export(2013-04-21).sql - to add task details to the MENU database.
Other changes:
- updated list of valid IP addresses in SOAP and XMLRPC folders to include '::1' (the IPv6 equivalent of '127.0.0.1').
- updated 'std.validation.class.inc' to replace CRLF in any multiline strings to just LF as CRLF is sometimes interpretted as two line feeds.
- updated 'std.filepicker1.inc' and 'std.filepicker2.inc' to move the processing of the RESET button.
- updated 'std.filepicker2.inc' to include the server name in the 'current directory' message.
- updated TCPDF to version 6.0.010 for PHP5. The PHP4 version is no longer updated.
- added tables MNU_TIME_LIMIT_ROLE and MNU_TIME_LIMIT_USER to the menu database which can be used to restrict user access to particular times of day and/or particular days. The maintenance screens are available via navigation buttons on the 'List Roles' and 'List Users' screens.
- fixed bug in 'dml.oracle.php5.class.inc' when retrieving times from a CHAR(8) column instead of a DATE column.
- modified 'std.help.inc' to obtain task description from the mnu_task table. 
- modified 'std.multi4.inc' to include processing for custom buttons in the data area (FAQ137).
- modified 'std.help.inc' to look for 'help-header.txt' and 'help-footer.txt' in the 'text/<language>/' directory before falling back to the subsystem root directory. This will enable the header and footer text to be available in different languages.
- modified 'std.help.inc' to allow the value '[copy: <task_id>]' to automatically copy the help text from another task.
- updated 'std.data_field.xsl' to allow fields with 'control=hidden' to occur in multi-row screens.
- updated list of relationship types in the Data Dictionary so that 'CASCADE' becomes 'CASCADE (framework)' and 'NULLIFY' becomes 'NULLIFY (framework)', and added 'CASCADE (FK constraint)' and 'NULLIFY (FK constraint)'. This is to separate actions which need to be taken by the framework from those that will be done by foreign key constraints in the database.
- added 'MULTI5' to the list of transaction patterns. The update to the MENU database is included in the radicore\menu\sql\menu.menu_export(2013-04-21).sql script.

2013-03-02, version 1.78.0
Database changes:
- none
Other changes:
- updated Import Columns function in Data Dictionary so that any existing comment is not overwritten with what has been defined in the dictionary database.
- updated XSL stylesheets to remove various errors reported by http://validator.w3.org/.
- updated XSL stylesheets to put 'title' attribute on images and navigation buttons so that they show up as tooltips in HTML pages.
- fixed problem in 'Generate PHP Scripts (a)+(b)' which failed to enclose $dbprefix in double quotes when constructing the sql query.
- updated 'std.pdf.class.inc' to allow an image to be used in 'detail view - multiple'.
- updated 'std.data_field.xsl' so that when a checkbox with a label appears in a search screen as a radiogroup, the label is shown in front of the group.
- fixed bug in 'std.filepicker1.inc' which failed to toggle sorting on the 'date' column.
- modified 'std.datevalidation.class.inc' to include $GLOBALS['date_format'] = 'yyyy-mm-dd' in the config file so that it can display dates in the format '2001-06-21'.

2013-01-01, version 1.77.0
Database changes:
- updated the structure of the MENU database to include the 'HELP_TEXT_ALT' and 'MNU_TASK_ALT' tables for text in alternative languages. You will need to run the following scripts:
-- radicore\menu\sql\mysql\alter_table(2012-11-17).sql - to amend the structure of the MENU database
-- radicore\menu\sql\menu.menu_export(2012-11-17).sql - to add task details to the MENU database.
Other changes:
- fixed bug in 'std.table.class.inc' where the scriptNext() and scriptPrevious() methods referred to $this->commit and $this->rollback instead of $this->commit() and $this->rollback().
- updated 'include.library.inc' to include removeBOM() function. This removes the Byte Order Mark from UTF8 strings.
- updated processing of $this->sql_search to allow line breaks in search expressions such as 'EXISTS(SELECT 1 FROM ... WHERE ...)'.
- fixed bug in 'getTableAlias1()' and 'getTableAlias2()' where it had 'trim($regs[0])' instead of 'array_map('trim', $regs[0])'.
- fixed bug in 'validateSortItem()' where it failed to use alias name if $this->sql_from contained 'tablename AS alias'.
- modified all the DML classes to pass the connection details via the constructor instead of global variables.
- fixed bug in 'dml.oracle.class.inc' which prevented the details for FLOAT(126) columns from being imported into the data dictionary.
- changed std.help.inc so that it reads help text from the database instead of from disk files. This means that the 'help' directory is now redundant.
- updated 'std.filepicker.list1.xsl' to accept 'no_hyperlink' in the 'params' element to display the file name as plain text.
- updated Data Dictionary to allow an integer column of any size, not just TINYINT(1), to be treated as a boolean.
- updated navigation buttons to include the task description as a tool-tip ('title' attribute on an input control).
- replaced the button label in the Quick Search area to read 'Quick Search' instead of 'Search' to avoid confusion with the other search button.

2012-10-14, version 1.76.0
- fixed bug in 'std.csv.class.inc' which prevented column headings being written out to a comma delimited file.
- updated MNU_USER table in the MENU database to increase the size of the 'ip_address' column from 16 to 40 characters. You will need to run script 'alter_table(2012-06-06).sql' to implement this change.
- updated AUDIT_LOGON_ERRORS table in the AUDIT database to increase the size of the 'ip_address' column from 16 to 40 characters. You will need to run script 'alter_table(2012-06-08).sql' to implement this change.
- modified the send_mail() function within 'include.library.inc' so that when sending an HTML message it puts the plain text version before the HTML version. This is because some email clients which cannot display HTML messages don't like it if the HTML version is first.
- fixed bug when dealing with numbers in locales which have different values for decimal point and thousands separator. Numbers are formatted in the user's locale before being displayed, and reformatted to internal representation (decimal point is '.', thousands separator is NULL) before being validated and written to the database. If a formatted number is included in the screen as 'noedit' then it is not passed back in the $_POST array, and when the $_POST array is merged with the original data the unformatted value is used. When this unformatted value is processed by the 'number_unformat()' function the result is a corrupted. The 'array_update_associative()' function has been modified to ensure that any number in the POST array is correctly unformatted before it is passed to the table object.
- updated the data dictionary to include screens to view relationship details from the child to its parents as well as from the parent to its children. You will need to run script 'dict.menu_export(2012-06-23).sql' in order to update the contents of your menu database.
- updated 'mnu_subsystem.class.inc' to make the 'erase' function faster.
- updated 'std.validation.class.inc' to deal with timestamp fields which are required but empty with a default of CURRENT_TIMESTAMP.
- updated 'dml.mysqli.class.inc' to change 'ddl_showColumns()' method to use INFORMATION_SCHEMA instead of 'SHOW COLUMNS'.
- updated 'dml.mysqli.class.inc' to deal with default of CURRENT_TIMESTAMP in timestamp fields.
- updated TCPDF library to version 5.9.178.
- fixed bug in 'include.xml.php4/5.inc' which sometimes caused the wrong value for 'orderby_seq' to be loaded into the screen, thus causing the wrong up-arrow/down-arrow image to be displayed next to the sort column.
- fixed bug in 'std.filepicker1.inc' which caused the sort sequence to toggle between 'ascending' and 'descending' each time the page was automatically refreshed.
- modified result of clicking on a column heading in a list screen to change the sort sequence so that clicking on a different column will always start at ASCENDING sequence, and will only toggle between ASCENDING and DESCENDING when repeatedly clicking on the same column name.
- fixed bug in getTimeStamp() when $GLOBALS['server_timezone'] in the config file is set to a different value than the server's timezone.
- fixed bug when clicking on a hyperlink in the breadcrumbs area to go back to a previous task.
- updated the $servers directive in the config file to include an entry called 'switch_dbnames'. This can be used when the database name used when importing into the data dictionary and creating the class files is completely different (not just a change in prefix) when deployed on a different server.
- fixed bug in 'dml.oracle.php5.class.inc' when using $dbprefix to alter database names.
- fixed bug when using Oracle 11g which stopped with 'ORA-01002 Fetch Out of Sequence' error. 

2012-06-03, version 1.75.0
- fixed bug in 'std.pdf.class.inc' when dealing with a barcode in the multi1-multi9 area.
- moved methods 'outputPDF_DetailView()', 'outputPDF_LabelView()' and 'outputPDF_ListView()' from 'std.table.class.inc' to 'std.pdf.class.inc' as they are methods for PDF documents and not database tables.
- moved method 'outputCSV()' from 'std.table.class.inc' to a new file called 'std.csv.class.inc'.
- updated TCPDF library to version 5.9.157.
- fixed bug in 'dict_column.class.inc' which set a boolean value of '0' to 'N'.
- fixed bug in 'include.library.inc' which dealt incorrectly with a boolean value of '0'.
- updated 'std.xml.php4.inc' and 'std.xml.php5.inc' to have all the functions inside a class called 'radicore_view'.
- fixed bug in runInBackground() function so that it can detect and report errors such as '401 Authorization Required'.
- updated 'send_email()' function inside 'include.library.inc' so that it will send an HTML email if the message starts with '<' and ends with '>'.

2012-04-14, version 1.74.0
- created 'isDirectoryValid()' function to test that a directory is within the 'open_basedir' list before using the 'is_dir()' or 'file_exists()' function.
- updated 'audit_trn.class.inc' and 'audit_tbl.class.inc' to automatically increment the sequence number if a duplicate is detected during an insert.
- fixed bug which prevented 'updateSelection()' from working with an update string = 'field1=field1+1, field2=field2+1'.
- modified 'updateRecord()' in 'dml.mysql.class.inc' to allow a value of 'function(...)' to be added to the SQL query string as 'field1=FUNCTION(...)' instead of 'field1='FUNCTION(...)''. This can be turned on by by adding the field name to $this->allow_db_function as in '$this->allow_db_function[] = 'field1';'.
- modified 'std.pdf.class.inc' so that the 'multi1'-'multi9' zones will not stop with the first empty result, and will be processed in the order defined within the structure file (which could be multi1, multi4, multi3, multi2, multi6) instead of sequentially as in multi1, multi2, multi3, multi4, multi5, multi6.
- updated 'std.multi2.inc' to allow $search value to be input to outer entity via the '_cm_restart()' method.

2012-02-08, version 1.73.0
- fixed bug in 'dml.pgsql.class.inc' so that the arguments in the DATE_SUB() function are cast to the expected data types.
- modified LDAP and RADIUS classes (in /menu/classes/) to check that the extension is actually available when the class is instantiated, and abort if not.
- modified 'error.inc', 'dml.sqlserv.class.inc' and 'dml.oracle.class.inc' to deal with database errors in a more consistent manner.
- modified code which handles the switching between HTTP and HTTPS protocols.
- updated XAMPLE prototype to version 2.4.0 to include an example of the TinyMCE javascript library v3.4.7 as well as updating the FCKeditor library to version 2.6.6.
- modified 'add database' function in Data Dictionary to exclude databases from the server if they have the current dbprefix but exist in the dictionary without the prefix.
- updated 'std.data_field.xsl' so that a field with properties 'control=multi-line' and 'xml=CDATA' will be displayed as ordinary text without escaping any HTML entities.
- updated 'std.update4.inc' so that it validates any sort field passed down by the parent script.
- add new task 'audit_ssn(batch)delete' which will delete entries from the AUDIT database older than 'N' years, where 'N' can be set on the 'Maintain Menu Controls' screen. A navigation button for this task is also available on this screen, but you can also set up a cron job to run this automatically. You will need to run script 'audit.menu_export(2012-01-24).sql' in order to add this task to your system. 
- fixed bug in 'std.filepicker1.inc' which preventeed it from showing an error message henerated by a child form (usually std.fileupload1.inc).
- fixed bug in 'dml.sqlsrv.class.inc' when encountering SUBSTR() inside a CONCAT() function.
- updated 'std.table.class.inc' and 'dml.*.class.inc' to allow the '_cm_deleteSelection()' method to specify FROM and USING arguments to enable a multi-table delete in the format 'DELETE FROM $from USING $using WHERE $selection'.

2011-12-10, version 1.72.0
- updated 'include.library.inc' so that the 'removeDuplicateFromSelect()' function will not insert a duplicate field reference at the position of the first reference, otherwise it may result in an invalid SQL statement.
- updated 'dml.pgsql.class.inc' for PostgreSQL version 9.1 where string literals containing the backslash character must now be defined using the escape string syntax (E'...') otherwise an error will be generated.
- updated 'std.imap.class.inc' to get around problems when converting encoding into UTF-8.
- updated 'std.validation.class.inc' so that the the validateEmail() function can deal with multiple addresses in a single field, and to deal with addresses in the format 'name <user@hostname.domain>'.
- updated 'include.session.inc' to call quicksearch code from a separate function.
- fixed bug in 'std.table.class.inc' which cause the 'deleteRecord()' function to lose the contents of $this->numrows after calling validateDelete().
- updated 'std.table.class.inc' so that the insertOrUpdate() function will check $this->no_display_count before generating a message.
- updated 'std.fileupload1.inc' to include a 'submitstay' button so that it does not exit after uploading a file.
- fixed bug in 'dml.*.class.inc' so that the getData_serial() method uses !is_null() on $rdc_limit and $rdc_offset instead of !empty() as the value zero returns TRUE with empty().

2011-09-02, version 1.71.0
- fix bug in 'std.pdf.class.inc' when a report line has both text and a barcode, and the height of the barcode is not an exact multiple of the line height of the text. 
- updated 'std.pdf.class.inc' to include the following:
-- allow margin and padding options to be supplied either with or without an underscore making 'marginleft' and 'margin_left' both valid.
-- restrict the 'border' option on barcodes to the containing cell and 'image_border' for the barcode itself (when the barcode is smaller than its cell).
-- removed the 'position' option on barcodes as this positions the cell within the page, not the barcode within the cell.
-- added the 'cellfitalign' option to barcodes to position the barcode within its cell.
-- added the ability to handle 2D barcodes (QRCODE and PDF417).
-- added the 'margin_top' and 'margin_bottom' options to the page definitions.
-- added the 'image_offset' option for pictures and barcodes to provide a space between the image border and the cell border.
-- added the 'body_gap' option to specify a gap between the header and the body. The default is 1mm.
-- allow width of '*' to be used on more than 1 column, in which case the remaining space will be apportioned equally.

2011-08-25, version 1.70.0
- merge 'align','valign' and 'class' attribute values into a single 'class' entry when adding the screen structure details to the XML document.
- created script 'radicore/menu/sql/mnu_role_task.sql' to add missing standard tasks to existing roles. This is not necessary for new roles as they are added automatically when they are created.
- updated 'table(generate)b.php' so that when it creates the '<table>.report.inc' file for an OUTPUT2 task it will set the default column widths to a percentage so that the whole line is filled.
- updated TCPDF library to version 5.9.112.
- updated MENU database to include the OUTPUT5 pattern. You will have to run script 'radicore\menu\sql\menu.menu_export(2011-08-24).sql' to apply this change to your database.
- added file 'std.output5.inc' as the controller for the OUTPUT5 pattern.
- updated 'table(generate)a.php' and 'table(generate)b.php' to include OUTPUT5 pattern for address labels.
- updated 'std.pdf.class.inc' to deal with the OUTPUT5 pattern (address labels).
- updated 'default/pdf.styles.inc' so that 'noborder' style sets the border width to zero instead of the border colour to white.
- updated 'std.pdf.class.inc' to allow the 'min_lines' option on $structure['body']['fields'] elements in the report structure file so that a cell with fewer lines will be padded with empty lines.
- updated 'std.pdf.class.inc' to allow 'padding_left/right/top/bottom' and 'margin_bottom' to be specified in the 'pdf.styles.inc' file for use with the OUTPUT5 pattern (address labels).

2011-08-01, version 1.69.0
- added ability to pre-select a field name in the QuickSearch dropdown.
- added option to include a QuickSearch area on LIST2 screens.
- fixed bug which failed to display multiple error messages on the logon screen.
- modified 'include.xml.php5.inc' to replace '<br></br>' with '<br />' in HTML output to get around a bug in the libxslt library.
- added 'SUBMIT+stay' and 'SUBMIT+next' buttons to LINK1 pattern.
- modified XML output so that if a field's value is an array it will be output as '<array key='0' value='value1' />' instead of '<array id='value1' />' so that associative arrays can be shown properly.
- added ability to specify the 'nosort' option in the $structure['<zone>']['columns'] array as well as the $structure['<zone>']['fields'] array.
- as the <COL ALIGN='...'> and <COL VALIGN='...'> attributes are poorly supported in most browsers (and removed from HTML5) I have changed the code in 'include.xml.php4/5.inc' to convert them to 'class' attributes instead. The 'class' attribute within <COL> is also poorly supported, so I have changed 'std.column_hdg.xsl' and 'std.data_field.xsl' so it will now be added to every cell within that column instead. This has been tested in IE8, Firefox 5.0, Opera 11.5 and Safari 5.0.5. See http://www.tonymarston.net/php-mysql/model-view-controller.html#xsl-structure for details.
- modified all XSL stylesheets to include 'indent=yes' so that HTML output is easier to read.
- change the handling of error messages so that errors generated within internal objects can be shown as having come from that object. See http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq14 for details.

2011-06-01, version 1.68.0
- fixed a bug in the 'outputCSV()' method within 'std.table.class.inc' to ensure that only those fields which have been specifically selected will be output.
- modified '_dml_updateSelection()' method within 'std.table.class.inc' so that it will stop on the first error.
- modified 'updateRecord()' method within 'dml.*.class.inc' so that if it is called with a $where string, and the primary key has changed, it will still check for a duplicate value.
- modified 'send_email()' function within 'include.library.inc' so that it puts the 'from' address into the 5th argument of PHP's mail() function to force a valid 'Return-Path' value in the mail header otherwise the sendmail program may use a value which causes the recipient's mail server to treat the email as spam. If a fixed value for Return-Path is required you can set the MAIL_RETURN_PATH constant in the CONFIG.INC file.
- added option to include browser-specific CSS files.
- added option to include a QuickSearch area on LIST1 screens.
- upgraded TCPDF library to version 5.9.084

2011-01-01, version 1.67.0
- fixed bug which allowed tasks which had been disabled to appear in the 'favourites' area of the menu/home page.
- changed 'include.general.inc' so that it will look for a file called 'config.local.inc' if 'config.inc' does not exist in the include path. This is for use on development machines.
- fixed bug in XML processing when dealing with errors in a multi-row screen.
- fixed bug in getExtraData() method in std.table.class.inc which caused it to empty $this->fieldarray.
- updated XSL processing to use the disable-output-escaping template instead of the disable-output-escaping option. This is to get around a bug in Firefox.
- updated TCPDF library to version 5.9.029.
- fixed bug in 'dml.pgsql.class.inc' which had the wrong arguments in the call to $auditobj->auditDelete().
- amended table 'mnu_favourite' in the 'menu' database to include the 'breadcrumbs' column. This will allow the menu buttons and the breadcrumbs area to be rebuilt to what they had been when the task was originally added to a user's favourites. You will have to run script radicore\menu\sql\mysql\alter_table(2010-12-29).sql in order to change the database schema.
- added 'dml.sqlsrv.class.inc' so that RADICORE can now work with an SQL Server database.

2010-12-01, version 1.66.0
- updated 'std.imap.class.inc' to include method html2text() which will convert an HTML document into plain text.
- updated 'std.imap.class.inc' so that it will provide the content-id of any attachments which are included in the HTML email. This will allow the 'cid' entry to be replaced with a URL that will obtain the attachment from its new location.
- added the 'fullwidth' property to each 'style_custom.css' file so that the 'textarea' control can be made to fit the full width of the cell instead of being restricted to the specified number of columns.
- amended XML/XSL processing so that if you add $this->fieldspec['fieldname']['xml'] = 'CDATA' to a field's specifications it will be added to the XHTML document in a <pre> element with disable-output-escaping='yes'. This will prevent characters such as '<', '>' and '&' from being converted to '&lt;', '&gt;' and '&amp;'. Note that the 'disable-output-escaping' option does not work in client-side transformations with Firefox (see bug #98168).
- updated 'dml.pgsql.class.inc' so that it can deal with the 'retry_on_duplicate_key' property.
- updated 'dml.oracle.php5.class.inc' so that it can deal with the DATE_SUB() and DATE_ADD() functions.
- updated 'std.update2.inc' so that it will combine the result of the call to $dbobject->updateSelection() with any other messages generated within the object.
- updated 'error.inc' so that the error log is emailed using 'charset=UTF-8' so that non-ascii characters are displayed correctly.
- updated 'errorlogdel.php' so that after creating an empty 'errorlog.html' file it inserts a 'charset=utf-8' header so that utf-8 characters can be displayed correctly.
- amended 'std.data_field.xsl' so that if additional CSS class names are supplied in the screen structure file and/or the XML document then they will be merged into a single 'class' attribute.

2010-11-01, version 1.65.0
- ensure that search screens allow 'IS NULL' and 'IS NOT NULL' as search criteria in any field.
- amended 'std.imap.class.inc' so that if the plain text version of the message is empty (which it should never be if the email client follows the correct protocols) it will use the HTML version.
- modified 'std.fileupload1.inc' and 'std.table.class.inc' so that filesize is made available in the _cm_post_fileUpload() method.
- modified 'include.session.inc' so that a 'run_at_end' task is not added to the processing sequence if the current task terminates with errors.
- fixed bug with breadcrumbs area when switching between different tasks which use the same script.
- updated 'std.list1/2/3.inc', 'std.multi2/3/4.inc' so that any search criteria supplied in either selection_fixed or selection_temp on MNU_TASK table is saved so that it becomes visible in the associated search screen.
- updated 'std.table.class.inc' to include methods 'restart()' and '_cm_restart()'. These will be called from all page controllers when they are restarted after returning from a child form. This will allow action to be taken after returning from a particular child task.
- modified 'include.library.inc' to improve the use of regular expressions when processing the WHERE string.

2010-10-02, version 1.64.0
- fixed bug in 'stripOperators()' function in file 'include.library.inc', which is used in 'where2array()', so that if the value is enclosed in single or double quotes it will also call stripslashes() in case it contains any escaped characters.
- fixed some anomalies when using column hyperlinks to change the sort sequence in LIST forms.
- updated 'audit_fld.class.inc' so that it will truncate any string larger than 65535 characters.
- updated the config.inc file to include the constant ERROR_LOG_MAILTO. This can contain one or more email addresses. If this is defined then the error_log will be emailed to this address.
- modified 'dml.*.class.inc' files so that when inserting a record with a compound primary key, part of which is empty, it will set the field to '' (empty string) instead of NULL.

2010-09-01, version 1.63.0
- updated std.help.inc so that the script id and script description are on separate lines.
- fixed bug in 'std.add3.inc' which caused it to return the wrong count when inserting more than one record.
- updated 'std.data_field.xsl' to copy across any 'class' attribute found with any <option> in the <lookup> area for dropdown lists.
- modified 'include.xml.php4/5.inc' so that the reference to file 'style_custom.css' will be excluded from the HTML output if it does not exist.
- when converting a selection string to or from an array ensure that the difference between a field value of '' (empty string) and NULL is maintained.
- updated TCPDF library to version 5.8.013
- fixed bug which caused the creation of a PDF file which could not be read. This was caused by running the initialisation code a second time after detecting a change in language, and this re-initialisation caused a corruption.

2010-08-01, version 1.62.0
- fixed bug in unFormatNumber() where it processed an empty field.
- fixed bug in getWhere() where it returned multiple selections when the current task only displayed one.
- fixed bug in 'append2ScriptSequence()' which caused the 'prepend' option to fail if the $_SESSION['script_sequence'] array did not currently exist.
- created some extra popups for 'Choose Task'. You will need to run the following script:
-- radicore\menu\sql\menu.menu_export(2010-07-18).sql in order to update the contents of your MENU database.
- updated the MNU_TASK table in the MENU database to include columns for 'task_id_run_at_end' and 'task_id_run_at_cancel'. You will need to run the following script:
-- radicore\menu\sql\mysql\alter_table(2010-07-18).sql in order to update the structure of your MENU database.
- added the MNU_FAVOURITE table to the MENU database. This stores a user's favourite tasks so that they can be displayed in the 'Favourites' area of the Menu/Home Page screen. They are displayed as buttons on the Menu/Home Page screen which can be pressed to activate the task. You will need to run the following scripts:
-- radicore\menu\sql\mysql\alter_table(2010-07-20).sql in order to update the structure of your MENU database.
-- radicore\menu\sql\menu.menu_export(2010-07-20).sql in order to update the contents of your MENU database.
- added navigation buttons to the 'List To-Do' screens to set the selection criteria to either COMPLETE or INCOMPLETE. You will need to run the following script:
-- radicore\menu\sql\menu.menu_export(2010-07-24).sql in order to update the contents of your MENU database.
- added task 'Delete Logon Errors' to AUDIT subsystem. You must run the folowing script:
-- radicore\audit\sql\audit.menu_export(2010-07-31).sql in order to update the contents of your MENU database.

2010-07-01, version 1.61.0
- modified 'std.validation.class.inc' and 'logon.class.inc' to deal with situation where $_SESSION['rdcaccount_id'] is not present.
- modified 'error.inc' to skip logoff function if $logon_user_id is 'INTERNET' or 'BATCH'.
- amended XMLRPC functions to obtain the value for $GLOBALS['dbprefix'] before the database is accessed.
- modified 'dml.mysqli.class.inc' so that if an errno of 2006 (MySQL server has gone away) is returned it will attempt to reconnect.
- modified 'config.xmlrpc.inc.default' to change the server encoding from 'utf8' to 'iso-8895-1'. This is because the client has already changed any utf8 characters into numeric entities, and to decode them using 'utf8' again would produce the wrong results.
- modified 'getLanguageFile()' within 'include.library.inc' so that if it cannot find a file beginning with 'sys' then it uses a literal error message instead of one supplied by 'getLanguageText()' as this would also fail with 'file not found'. 
- modified 'std.table.class.inc' so that 'getForeignData()' will not clear out any key fields if a lookup failed while within a search screen as the key may only contain a partial value.
- modified 'std.table.class.inc' so that 'unFormatData()' will not insert '9999-12-31' into a field which has 'infinityisnull' set while within a search screen.
- fixed bug in convertTZdate() and convertTZtime() which failed to ensure that date is converted to internal format (ccyy-mm-dd) before being converted.

2010-06-01, version 1.60.0
- modified 'config.inc' file to include optional 'port' and 'socket' parameters for MySQL database connections. See 'config.inc.default' for details.
- modified 'std.batch.inc' and 'dml.???.class.inc' so that if a batch job fails on a duplicate candidate key during an insert or an update then the error log will contain the key value.
- modified XML/XSL processing to allow a field's HTML control to be set to 'button'. See FAQ137 for details.
- modified 'std.add1.inc', 'std.add2.inc', 'std.add5.inc' and 'std.update1.inc' to deal with 'button' controls.
- fixed bug with cascadeDelete() when called from deleteRelations() method which failed to pass down the identity of the parent table.
- modified processing of MNU_INITIAL_VALUE_ROLE and MNU_INITIAL_VALUE_USER so that both will be read and combined, with USER values taking precedence over ROLE values.
- fixed bug in 'std.validation.class.inc' involving a MySQL field type of 'SET' which uses a screen control of MULTI CHECKBOX. This bug resulted in unselected values being represented as '0' in the sql query, thus causing an error. This does not happen if the control is MULTI DROPDOWN. See http://www.radicore.org/forum/index.php?t=msg&goto=2543 for details.

2010-05-01, version 1.59.0
- fixed bug when writing to the AUDIT database when it has a dbprefix which is different from that of the table being audited.
- updated TCPDF library to version 4.9.007.
- added the ability to execute a task between the logon screen and the display of the first menu. This task can be specified as the 'initial passthru' on the 'menu' (Home Page) task. See FAQ132 for details.
- fixed bug in wf_workitem.class.inc and workflow_engine.class.inc where rdcaccount_id was not included in the SELECT list. See http://www.radicore.org/forum/index.php?t=msg&th=554 for details.
- amended function 'append2ScriptSequence()' to include an optional second argument, which, if set to TRUE, will cause the task details to be prepended to the $_SESSION['script_sequence'] array instead of being appended. This is to force any AUTO tasks generated by the workflow system to go to the head of the queue in front of any non-workflow tasks. See http://www.radicore.org/forum/index.php?t=msg&th=556 for details.
- amended 'workitem(timeout).php' so that it will process records for all values of rdcaccount_id.
- updated 'wf_transition' table in 'workflow' database so that the time_limit can be specified in minutes instead of hours. You will need to run script radicore\workflow\sql\mysql\alter_table(2010-04-07).sql in order to implement this change.
- fixed bug in 'std.multi4.inc' which prevented it from changing the rows-per-page setting.
- fixed bug with the regular expression within the 'unFormatNumber()' method in 'std.table.class.inc'.
- fixed bug which prevented a task of pattern 'batch' to be run from a menu button.
- amended the 'auditWrite()' method inside 'audit_tbl.class.inc' so that it ignores BLOB fields. This is to prevent an error when attempting to write to a string field which contains invalid characters.
- updated the data dictionary to allow a column to have a control of 'image'. This is similar to the 'control=filepicker' with 'subtype=image', but without the filepicker option.
- updated XML/XSL processing to allow the specification of 'alt' text for an image field. See FAQ133 for details.
- updated XML/XSL processing to allow a hyperlink field to have separate parts for 'label' and 'url'. See FAQ133 for details.
- updated XML/XSL processing to allow a hyperlink field to be specified as an array so that multiple entries can be displayed. See FAQ133 for details.

2010-04-01, version 1.58.0
- updated PDF processing to allow the page footer to contain an image.
- updated PDF processing to allow the page margins to be changed from the defaults.
- updated PDF processing to allow 'ignore_if_empty' to be set for an entire style. This saves having to specify it for every line that uses that style.
- updated PDF processing to allow title elements to be printed once per database row (not on overflow pages). This facility uses the 'print_only_once' option.
- fixed database export and table export functions within the data dictionary so that when they link to the MENU database to find the subsystem's directory name they use the correct dbprefix from the config.inc file.
- change 'singleton' class to 'RDCsingleton' so that it wll not clash with a class/interface with the same name when being integrated with other software. YOU WILL NEED TO CHANGE ALL REFERENCES TO THIS CLASS IN YOUR CODE.

2010-03-01, version 1.57.0
- modified the workflow system to allow more than 2 Explicit OR-Splits to come out of a transition. Any number can be specified, but they must all have a pre-condition that can be tested for TRUE except for the last one. This will be used as the default when none of the pre-conditions evaluates to TRUE.
- allow the text on the menu/home page for pending workflow items to be customised. For details see FAQ130.
- added 'soap' directory to assist in the development of web services. Point your browser to 'radicore/soap/index.html' to see some working examples.

2010-02-01, version 1.56.0
- fixed bug in startTransaction() method within 'std.table.class.inc' so that, when setting up the lock array, if the multiple database server option is employed it will use a separate dbprefix for each server rather than a single dbprefix for all servers.
- modified the '_cm_ListView_print_after()' method within 'std.table.class.inc' so that it includes $next_row as the second argument. This will allow a comparison to be made with the current row before printing any extra lines.
- fixed bug in processing of MULTI4 pattern which failed to associate error messages with the correct rows of the inner entity.
- modified screen structure files to allow the 'align' and 'valign' attributes to be specified for cells in the vertical view.
- modified 'std.multi1.inc' so that it calls the 'validateDelete()' method before the 'deleteRecord()' method.
- modified 'update column' in the data dictionary to allow a new control called 'image hyperlink'. The field value should be the path to an image, and this will be displayed as a thumbnail image which will also be a hyperlink to the full-sized image.

2010-01-01, version 1.55.0
- updated 'std.validation.class.inc' to allow a numeric field to contain text such as 'field+1' so that it can be incremented from its current value instead of just being set to a new value.
- updated 'std.delete1.inc' to display a message after a record has been deleted.

2009-12-01, version 1.54.0
- fixed bug in setDefaultOrderBy() function which set the default sequence to 'asc', only to have it switched to 'desc' in the setOrderBy() function.
- fixed bug in 'dict_table_key.class.inc' which failed to include the value of $dbprefix when accessing the database schema.
- fixed bug in 'std.update4.inc' to change '$dbobject->getErrors' to '$dbobject->getErrors()'.
- fixed bug in the 'import tables' function in the data dictionary which added $dbprefix twice to $dbname, thereby creating an invalid database name.
- added 'xmlrpc' directory to assist in the development of web services. Point your browser to 'radicore/xmlrpc/index.html' to see some working examples.
- replaced all POSIX functions which have been deprecated in PHP 5.3.0 with their PCRE equivalents.
- updated the MENU database to include tables MNU_TASK_IP_ADDRESS and MNU_USER_IP_ADDRESS. This can be used to restrict access to machines with specified IP addresses. You will need to run the following scripts
-- radicore\menu\sql\mysql\alter_table(2009-11-15).sql to alter the structure of your MENU database.
-- radicore\menu\sql\menu.menu_export(2009-11-15).sql to update the contents of your MENU database.

2009-11-01, version 1.53.0
- modified error handler so that it only displays verbose error messages when the server is 'localhost'. Verbose messages will still be sent to file 'errorlog.html' and emailed to the system administrator.
- fixed bug in 'runInBackground()' function which failed to pass back any error message to the calling function.
- fixed bug in 'std.filepicker1.inc' which failed to process the 'selectall/unselectall' options.
- fixed bug in 'initialise()' function within 'std.table.class.inc' which incorrectly replaced $where with $selection.
- modified search screen so that a dropdown list or radio group can be temporarily converted to a MULTIDROP. This will allow multiple options to be selected instead of just one, and will result in SQL similar to the following being inserted in the WHERE string: 'field IN ('option1','option2','option3',...)'.

2009-10-04, version 1.52.0
- upgraded TCPDF to version 4.8.005
- updated 'include.general.inc' to add functions 'convertTZdate()' and 'convertTZtime()'. These will allow timezone conversions on fields of type 'date' and 'time' instead of 'datetime'.
- updated footer processing in PDF output so that 'date' and 'time' values are converted into the user's timezone.
- updated 'std.table.class.inc' to replace the '_cm_ListView_pre_print()' method with the '_cm_ListView_print_before()' and '_cm_ListView_print_after()' methods.
- updated 'std.pdf.class.inc' to include the 'getLinesRemaining()' method.
- fixed bug in login screen where the email address was entered in mixed/upper case instead of lower case, causing the error message 'A record already exists with this key' to be displayed.
- updated 'std.validation.class.inc' to change all 'str*()' functions to 'mb_str*()' (if the mbstring extension has been loaded) as the func_overload option is no longer supported in htaccess files as of PHP version 5.2.7
- fixed bug in 'std.update5.inc' which failed if $where was empty, ignoring the fact that $selection was not empty.
- updated AUDIT database to add 'email_addr' field to 'audit_logon_errors' table. This is to fix bug when a login fails when using an email address instead of a user id. You will need to run script 'radicore\audit\sql\mysql\alter_table(2009-09-29).sql' in order to update your database schema.

2009-09-01, version 1.51.0
- fixed bug in 'std.search1.inc' which caused changes to $this-fieldspec in '_cm_validateSearch()' to be ignored.
- changed 'std.data_field.xsl' to remove the need for the 'id' attribute when defining labels for options in radio groups and checkboxes. The 'id' attribute always used a value which was the same as the 'value' attribute for the control, which caused duplicate id's if more than one field had the same value. This in turn caused only the last label entry with that id to have any effect.
- fixed bug in 'std.list2/3.inc', 'std.multi2/3/4.inc' where the RESET button caused action to be taken on the outer/parent entity when it should not.
- fixed bug in 'childForm()' function which passed $search as a separate string to child forms of type 'list' instead of merging in the $where string.
- fixed bug in 'childForm()' function which failed to include $script_vars in its arguments on the call to the runInBackground() function.
- fixed bug in 'std.table.class.inc' which failed to set up the value for rdcaccount_id when the getData_serial() method was called.
- fixed bug in '__sqlProcessJoin()' where $select (the current SELECT list) contained a field with an alias name and the contents of $parent_field contained more than one new field name.
- fixed bug in 'dict_database_s01.class.inc' which referred to task 'dict_table(list)2' instead of 'dict_table(list2)'.
- removed 'header('content-length: ...')' from XSLclient() function as this caused problems when the XML document contained multibyte characters.
- changed HELP text for DICT subsystem to reflect the latest task id's.
- added custom method '_cm_reset()' which is called whenever the RESET button is pressed.
- changed the processing of _cm_initialise() so that the 2nd argument, $selection, will be available for all tasks, not just those of pattern ADD2.
- changed '_cm_pre_output()' method so that the $filename argument is available for CSV output. This will allow the filename to be changed in OUTPUT1 tasks.
- changed 'std.pdf.class.inc' to allow the 'ignore_if_empty' attribute for a cell in the title area.
- fixed bug in 'recover password' function which failed to decrypt the user's password before it was emailed.

2009-08-01, version 1.50.0
- fixed bug in 'include.xml.php4/5.inc' which mis-spelled a call to getLanguageText().
- modified the _sqlSelectAlternateLanguage() method inside 'std.table.class.inc' so that it allows more options.
- modified 'dml.pgsql.class.inc' to include the adjustGroupBy() and adjustHaving() functions which are used for the Oracle database.
- added function replaceScreenColumns() which will replace a column id in a screen structure file with a different column id (and label) at runtime. This is similar to replaceScreenHeadings() which will only replace the column label.
- updated 'mnu_subsystem_s01.class.inc' (subsystem export) so that it includes the MNU_ACCOUNT and MNU_MOTD tables when exporting the MENU subsystem.
- updated various 'std.*.inc' files to use $object->getErrors() instead of $object->errors.
- updated Virtual Private Database processing so that users whose rdcaccount_id is greater than 1 cannot modify or delete any shared records (where rdcaccount_id = 1).
- allow the selection/choice made in popup screens to be locked for the next activation.
- updated 'std.output1/2/3/4.inc' so that $search is available as a 3rd argument to _cm_initialise() in case it was called from a search screen. 

2009-07-01, version 1.49.0
- added field 'user_timezone' to MNU_USER table. You will need to run script radicore\menu\sql\mysql\alter_table(2009-06-01).sql in order to amend the database schema.
- added the ability to convert datetime fields between the timezone of the server and the timezone of the client. This is only available if your PHP version is 5.2 or greater.
- updated 'std.pdf.class.inc' to use $this->getAliasNbPages() instead of the deprecated $this->AliasNbPages (used to insert 'page n of n' in page footers).
- modified ListView in PDF processing so that each line can have a border top and bottom instead of alternate lines having a different background colour. Also allow 'border=P' to put a border around the page instead of each cell.
- modified all page controllers to use '$dbobject->getMessages()' instead of '$dbobject->messages' which will allow $dbobject->messages to be either a string or an array.
- modified 'dml.oracle.php4.class.inc' and 'dml.oracle.php5.class.inc' in order to manipulate the GROUP BY and HAVING clauses as what is acceptable to MySQL will not work in Oracle.
- added method 'post_search()' and '_cm_post_search()' to 'std.table.class.inc'.
- modified 'std.search1.inc' to call the new 'post_search()' method in order to perform any final processing before the entered values are passed back to the calling form. This may be because the search form is being used to enter selection details before firing off a batch process.
- all tasks and scripts in the DICT subsystem have been renamed to conform to the current Radicore naming conventions. You will need to run script radicore\dict\sql\dict.menu_export(2009-06-25).sql to update your MENU database.
- modified search screens so that required fields will be indicated as such. The 'required' property is removed from every entry in $this->fieldspec by default, but can be reinstated in '_cm_changeConfig()'.
- fix bug in 'dict_table_s02.class.inc' (export table) which failed to error when a related table was in a different subsystem but with no value for SUBSYS_DIR.

2009-06-01, version 1.48.0
- updated 'std.buttons.xsl' to include the total row count after 'show 25 | ... | show 100'.
- added table 'mnu_motd' to the MENU database to deal with Message Of The Day.
  You will need to run the following scripts:
  - radicore\menu\sql\mysql\alter_table(2009-05-05).sql to update the structure of the MENU database. This will also add 'mnu_motd(show)' to the mnu_role_task table for each role_id so that it is accessible to all users.
  - radicore\menu\sql\menu.menu_export(2009-05-05).sql to add the new tasks to the MENU database.
- modified the logon process so that a 'Show Message of the Day' screen will appear immediately after passing through the LOGON screen. It will show the latest unexpired message, with the ability to scroll through earlier unexpired messages.
- fixed bug in 'mnu_user(add1)' which failed to encrypt the password field.
- updated the dictionary import scripts to take account of $dbprefix when reading the target database. Database names in the dictionary do not have this prefix.
- modified the method of looking up language files, screen and report structure files. It will now look for the specified file individually in one of the possible language directories instead of assuming that if the language directory exists then the file must exist in that directory.
- renamed script 'mnu_pattern_enq.php' to 'mnu_pattern(enq1).php' and 'mnu_role_search.php' to 'mnu_role(search).php' to conform to current naming standards. You will need to run script radicore\menu\sql\menu.menu_export(2009-05-14).sql in order to update your copy of the MENU database.
- fixed bug which caused the BACK button from a help page to go back to the wrong page.
- changed the MULTI1 pattern to remove the RETRIEVE button and replace the CLEAR button with RESET as it resets the screen to its previous values which may not mean clearing it to an empty state.
- upgraded TCPDF library to version 4.6.011.
- fixed bug in 'std.validation.class.inc' which failed to validate a string's length against the column size in the data dictionary.

2009-05-01, version 1.47.0
- updated 'include.session.inc' to include getPreviousPattern() function.
- updated 'std.table.class.inc' to include $this->scriptPrevious() method which will call $this->commit() if there is a database transaction which is open.
- updated 'std.table.class.inc' to include $this->no_duplicate_error which, if set to TRUE, will prevent an error message when inserting a record which already exists. Instead it will set $this->numrows to zero to signify 'no insert', and the '_cm_post_insertRecord()' method will not be called. If the new record is not a duplicate then $this->numrows will be set to 1 to signify 'record inserted'.
- updated 'batch_log(filepicker)' task so that by default each file hyperlink will open up in the browser window. If 'download=TRUE' is entered into the task's 'settings' field then each hyperlink will be processed by the 'batch_log(filedownload)' task.
- updated 'std.table.class.inc' to include 'post_fileUpload()' and '_cm_post_fileUpload()' methods.
- updated 'std.fileupload1.inc' to call the 'post_fileUpload()' method so that the file may be processed after it has been uploaded.
- updated the 'selections' area of the navigation bar so that a selection can be locked, which will enable the same records to be automatically reselected when returning to the screen.
- modified the processing of the 'rdcaccount_id' field so that it is qualified with the table name when included in any SQL statement that is generated by the framework.

2009-04-01, version 1.46.0
- fixed bug in php_session.class.inc which accepted a session_id greater than 32 chars when the request string had '/.../...' appended to it.
- updated 'deleteRelations()' method in 'std.table.class.inc' so that when deleting or nullifying child relations the value of $this->audit_logging for the parent table is passed down to the child table.
- updated the 'dict_table' table in the DICT database to include columns 'nameof_start_date' an 'nameof_end_date' when the table has fields which represent 'start_date' and/or 'end_date', but with different names. You must run script radicore\dict\sql\mysql\alter_table(2009-03-08).sql in order to update your database schema.
- updated PDF processing to allow '<imagename>' to be expressed as '%%name' instead of the hard-coded path to an image file so that the path name can be provided from data which is obtained at runtime.
- fixed bug in 'mnu_user.class.inc' which tried to validate the password when attempting to update a different field, such as the role_id. As the password is not present on the screen the validation always failed.
- fixed bug in 'std.pdf.class.inc' where variables in the title were not being shown correctly if the printing of _cm_ListView_total() caused a new page to be started.
- updated 'std.table.class.inc' to include $this->scriptNext() method which will call $this->commit() if there is a database transaction which is open.

2009-03-01, version 1.45.0
- fixed bug in lookup of language directories which used format 'xx-XX' instead of 'xx_xx' (all lower-case characters, with '_' (underscore) instead of '-' (hyphen)).
- fixed bug in conversion of WHERE string into array to allow operator of NOT LIKE as well as LIKE.
- updated TCPDF library to version 4.5.018

2009-02-01, version 1.44.0
- ensure that if a screen is refreshed after a database update it is done via GET instead of POST.  
- fixed bug in 'std.detail1.xsl' which prevented a field's 'size' attribute in the screen structure file from being used to override the default size.
- fixed bug in 'getData_raw()' when $this->sql_orderby contains a field which does not exist in either $this->sql_select or $this->fieldspec, thus causing an error.
- fixed bug in 'mnu_user.class.inc' which corrupted the password when the COPY button is pressed while running 'mnu_user(add1)'.
- fixed bug in 'std.encryption.class.inc' regarding multibyte characters.
- fixed bug in 'include.xml.php4/5.inc' which tried to output a numeric field name as an element id. These are invalid in XML, so are ignored.
- fixed bug in 'std.filedownload1.inc' to allow spaces in the file name.
- fixed bug in 'std.head.xsl' which failed to append the session name to the meta refresh line.

2009-01-01, version 1.43.0
- added variable '$this->sql_no_foreign_db' (default value is FALSE) to 'std.table.class.inc'. If this is set to TRUE then when $this->_sqlForeignJoin() is executed it will ignore any tables which exist in other databases. This is to deal with the situation where an application contains several databases which are spit across more than one server, in which case cross-database JOINs would fail.
- replaced 'getColumnHeadings()' and 'setColumnHeadings()' functions with 'replaceScreenHeadings()'.
- added 'replaceReportHeadings()' function for PDF output.
- updated PDF report structure files to allow column widths to be expressed as a percentage as well as a number.
- upgraded TCPF library to version 4.4.006.

2008-12-02, version 1.42.0
- made it possible to connect to a remote MySQL database using SSL encryption. This is only possible when using the 'improved' mysqli extension for version 4.1 and above. Refer to FAQ115.
- fixed bug in 'std.pdf.class.inc' in order to allow an image to appear in the 'multi*' area.
- modified 'insertOrUpdate() method within 'std.table.class.inc' so that the input array is checked to see if the full primary key has been specified. If it has not then a lookup cannot be performed and the record will be inserted. This is to deal with auto_increment columns.
- modified the 'getColumnNames()' method within 'std.table.class.inc' so that it calls custom method '_cm_getColumNames()'. This will allow both the list of column names (defined within $this->fieldpsec) and their initial values to be customised.
- fixed bug in 'logon.class.inc' which caused the wrong error message to be displayed if the login is via email address and the address does not exist in the MNU_USER table.
- updated the processing of radio groups to allow individual entries to be given their own CSS style. Refer to FAQ117.
- updated 'std.batch.inc' so that it will use the INCLUDE_PATH from the local {.}htaccess{.txt} file instead of the 'batch.ini' file. You will need to copy the updated version from the 'radicore/default' directory.
- modified list of patterns to include 'BATCH' for tasks which are to be run in the background. Refer to FAQ119. You will need to run script 'radicore\menu\sql\menu.menu_export(2008-11-21).sql' in order to update your copy of the MENU database.
- updated directory structure to include 'radicore/logs' for the output from background tasks. You will need to create this directory and change its permissions so that it can be written to by the application.
- created task 'batch_log(filepicker)' to read the contents of the 'radicore/logs' directory. Clicking on a file name will download/display its contents.
- updated 'std.filepicker1.inc' to include a call to the 'filePickerSelect()' method after a selection has been made in case some further processing is necessary.
- updated 'std.filedownload1.inc' to include a call to the 'initialise()' method to perform any processing before the 'initialiseFileDownload()' method is called.
- added task 'file(search)' to be used as the search function for the 'filepicker' pattern.
- added task 'file(delete)' as a navigation button in 'batch_log(filepicker)', to allow selected entries to be deleted.
- updated 'std.filepicker1.inc' to include optional 'size' and 'date' column, and to allow sorting on these columns.

2008-11-01, version 1.41.0
- fixed bug in 'initSession()' function within file 'include.session.inc' which lost the value of a task's pattern_id in the session data.
- updated 'std.add2.inc' so that if 'getExtraData()' produces an error it will return immediately to the previous task.
- fixed bug in 'std.validation.class.inc' which failed to pick up a custom validation class in the subsystem's 'classes' directory.
- fixed bug in 'std.datevalidation.class.inc' which failed to deal correctly with dates which were input in the format 'dd/mm/yyyy'.
- added option on Menu Control Data to allow login via email address instead of user_id.
- upgraded TCPDF library to version 4.0.029 (after overcoming some new bugs in TCPDF which the author won't recognise as bugs).
- modified the pagination and scrolling functionality to allow 'google style' which shows (Page 1 2 3 4 5 6 7 8 9 10 of 99) instead of (Page 5 of 99). My thanks to Ian Katz for contributing this code.
- modified the 'help' template inside 'std.buttons.xsl' so that all help screens use the same session name as the application screens. This will ensure that the user's language will be taken into account when finding text to be displayed.
- modified 'std.pdf.class.inc' to accept 'notext' => 'y' on images so that the image will be displayed on its own without the file name.
- fixed bug in 'radicore/default/screens/en/output4.screen.inc' which had 'party' as the table name instead of '#tablename#'.

2008-10-01, version 1.40.0
- fixed bug in 'qualifySelect()' of 'std.table.class.inc' so that it will not try to qualify any element in the select list which starts with 'function(SELECT ...)' as well as '(SELECT ...)'.
- added 'sqlSelectDefault()' method to 'std.table.class.inc' so that the components of an object's sql SELECT statement can be set to their default values before being modified.
- modified 'std.datevalidation.class.inc' and 'config.inc' to allow dates to be displayed in the format 'dd.mm.yyyy' and 'dd/mm/yy'.
- modified 'Generate SQL' function in AUDIT system to replace chr(10) with '\n' and chr(13) with '\r' in field values.
- modified the 'filepicker' pattern so that if a 'fileupload' task is activated then the uploaded file will automatically be passed back to the user as the selected file without any further action.
- modified 'std.help.inc' so that it includes both the taskid and description in the screen title.
- added the ability to authenticate the logon screen via an LDAP server, in addition to the existing RADIUS server.
- updated MNU_TASK table to include a new column to hold max_execution_time, to allow a script to run for longer than the limit defined in the PHP.INI file. You will need to run script radicore\menu\sql\mysql\alter_table(2008-09-19).sql to update the structure of the MENU database.
- made it possible to force a page break in a PDF report with the code '$this->pdf->AddPage();'
- fixed bug in 'getForeignData()' which dealt incorrectly with a field list containing multiple fields, some of which were aliased.

2008-09-01, version 1.39.0
- modified 'std.table.class.inc' so that if the 'getData()' or 'getData_serial()' methods need to check that the primary key has been supplied they will also accept a candidate key.
- fixed bug in 'dml.*.class.inc' which caused the value zero in an integer field to be treated as empty, thus causing an error if a field had the 'required' property set. The test has been changed from 'if (empty($value)) to 'if (strlen($value) > 0)'.
- modified 'std.table.class.inc' so that the 'initialise()' method saves the contents of $where in $this->where. This will allow $where in an ADD1 pattern to be passed to a popup form.
- fixed bug in 'isPkeyComplete()' where the primary key was not supplied but because the table had additional unique keys no error was raised even though none of these keys was supplied.
- modified 'std.table.class.inc' so that the '_cm_initialiseFilePicker()' method accepts an argument which is the $where string converted into an associative array.

2008-08-01, version 1.38.0
- modified 'setColumnAttributes()' and 'std.data_field.xsl' so that the 'nodisplay' attribute can be set for fields which occur in multi-field rows for a single occurrence (eg: the 'outer' entity in a 'list2' pattern). 
- modified 'std.add1.inc' so that $selection will be made available as a second argument for the '_cm_initialise()' method if it is required.
- modified 'icon' template within 'std.data_field.xsl' so that width and height are only output when they are non-zero.
- fixed bug in 'dict_table_s02.class.inc' which failed to deal correctly with multiple candidate keys.
- modified the 'actbar' template within 'std.buttons.xsl' so that the script time is not included in the HTML output if it is not included in the XML document. This can be achieved by adding the line '$GLOBALS['no_script_time'] = true;' in the subsystem's 'include.subsystem.inc' file.
- upgraded TCPDF library to version 4.0.008.
- modified popup processing so that _cm_popupCall() can set $this->errors and change the value in $popupname.

2008-07-01, version 1.37.0
- modified template 'scripting_events' within 'std.data_field.xsl' to include the 'id' attribute.
- modified 'validateField()' method within 'std.validation.class.inc' so that if a field's size (obtained using strlen()) is greater than $fieldspec['size'] then it will test for multi-byte characters using mb_strlen() before failing.
- fixed bug in 'audit_tbl_s02.class.inc' which incorrectly determined that a database change where all the previous values were NULL was an insert. However, if the list of field names does not include all the primary key fields it is in fact an update.
- fixed bug in 'filterWhere1Where2()' of 'include.general.inc' which caused a WHERE clause of 'EXISTS (SELECT ...)' to be accidentally filtered out in some circumstances.
- fixed bug in 'splitNameOperatorValue()' which failed to recognise a 'MATCH(...) AGAINST(...)' condition which contained the 'IN BOOLEAN MODE' option.
- modified 'std.fileupload1.inc' so that it sets the file permissions to 664 after it has been uploaded instead of relying on the default permissions which are sometimes random and unpredictable.
- modified 'table_export.php' in DICT subsystem to set the file permissions to 664 after creating the '*.class.inc' and '*.dict.inc' files.
- added function 'rangeFromTo()' which combines '<whatever>_from' and '<whatever>_to' values into the '<whatever>' field as 'BETWEEN '<whatever>_from' AND '<whatever>_to''.
- added function 'unqualifyFieldArray()' which removes table names from field names in the input array.
- fixed bug in 'extractTableNames()' of 'include.general.inc' which failed to deal correctly with the first tablename in the FROM string being prefixed with a database name.
- modified 'filterWhere1Where2()' so that if field name exists in both $where1 and $where2 is not removed from $where2 unless it has the same operator.
- fixed bug in 'initial_value_user_s01.class.inc' and 'initial_value_role_s01.class.inc' which failed to deal with empty input.
- modified 'mnu_task' screen to make 'initial_passthru' a popup instead of a text box.
- fixed bug in 'dict_related_column_multi2.php' which allowed the alias names for the two tables to be more than one word.
- fixed bug in 'std.data_field.xsl' which prevented multiple selections from appearing in the $_POST array.
- modified 'std.multi3.inc' so that it now has a 'submit+next' button.
- added new transaction pattern 'OUTPUT4' which will allow columns to be selected before they are output to the CSV file.
- modified 'std.search1.inc' so that if a value is input with an operator such as '<', '<=', '>' and '>=' then the operator will be preserved when returning to the search screen.
- updated the MENU database so that the 'initial_value' field on the 'mnu_initial_value_role' and 'mnu_initial_value_user' tables is increased from 40 to 255 characters. You will need to run script radicore\menu\sql\mysql\alter_table(2008-06-24).sql in order to implement this change.
- modified 'dict.column.class.inc' so that when a column is changed from CHAR(1) to BOOLEAN then 'boolean_true' is set to 'Y' and 'boolean_false' is set to 'N'. These are initial values which may be changed later.

2008-05-01, version 1.36.0
- switched license from GPL (GNU General Public License) to AGPL (GNU Affero General Public License) to include 'remote network interaction' in the definition of 'sharing' (ie: non-private usage).
- modified 'std.data_field.xsl' so that the select box will not be shown for any row that has the 'noselect' attribute set. This can be achieved by adding the pseudo-column 'rdc_rowspecs' with the value 'array('noselect' => 'y')' to the row in question.
- modified 'std.table.class.inc' so that it deals with 'allow_empty_where=true' passed down in the 'settings' field from the 'Update Task' screen.
- modified 'std.table.class.inc' so that if an object's 'allow_empty_where' property is set it will also ignore the 'checkPrimaryKey' property.
- modified 'logon.class.inc' so that if radius authentication is turned on the user is not prompted to change his menu password.
- modified 'std.list1.inc' so that 'getExtraData()' method is called after 'getData()' instead of 'initialise()'.
- fixed bug in 'validateSortItem()' which failed to remove trailing 'asc' or 'desc' from field name before testing it against the field list of the current object.
- fixed bug in 'getFieldAlias3()' function within 'include.general.inc' so that if an expression contains more than one '.. AS ..' it deals with the last one, not the first.
- modified 'std.data_field.xsl' so that when processing a MULTI2, MULTI3 or MULTI4 pattern it is possible to set the 'outer' or 'inner' zones to 'noedit' with the statements '$this-xsl_params['outer_noedit'] = 'y'' and '$this-xsl_params['inner_noedit'] = 'y''. This can be reversed using the 'unset()' statement.
- added '_cm_getWhere()' method to 'std.table.class.inc' to allow $where string to be modified before it is passed to the next task.
- modified 'std.update1.inc' so that if $dbobject->errors is set after the call to $dbobject->getData() then all the fields in the data area are set to 'noedit'.
- modified 'std.search1.inc' to allow date fields to be preceded by operators such as '<', '<=', '>' and '>='.
- the file 'std.multi3.xsl' is now redundant as it is a duplicate of 'std.list3.xsl'.

2008-04-01, version 1.35.0
- fixed bug in the 'validateField()' method inside 'std.validation.class.inc' which translated a field name using the contents of the 'language_text.inc' file, then used the translated name as the key to the $errors array insead of using it in the body of the message.
- fixed bug in the 'qualifySelect()' function within 'std.general.inc' so that fields within a 'function(...)' statement are also qualified, but fields within a subselect are not.
- modified the 'filterWhere()' method inside 'include.general.inc' so that all field names are converted to lowercase before being compared with the contents of the $fieldspec array.
- modified the 'getInitialData()' method inside 'std.table.class.inc' so that if a field is currently empty but it has a default value defined, then the default value will be used as the field's initial value (unless it has a datatype of date and/or time).
- modified the '_sqlProcessJoin()' method inside 'std.table.class.inc' so that if a field being added to the select string has an alias name which is already being used, that alias name will be appended with an 'x' to make it unique.
- modified LIST2, LIST3, MULTI2, MULTI3 and MULTI4 controllers so that the $where string passed to the 'initialise()' method of the inner objects is the original string, not the one filtered by the outer object. 
- fixed bug in ADD2 pattern which caused $selection to be used instead of $where. However, $selection will be made available as a second argument for the '_cm_initialise()' method if it is required.
- modified XSL files so that each <body> element in the HTML output will include a CSS class name which is based on the script name (but without the '.php' extension, and with parentheses changed to underscores). This will allow custom CSS styles to be set for individual scripts.
- added pattern ADD5 which will allow multiple database rows to be created from a single input screen. You will need to import script radicore\menu\sql\menu.menu_export(2008-03-28).sql to update your copy of the MENU database.
- added '_cm_setParentData()' method to 'std.table.class.inc' to allow changes made in a parent object to be made available to the child object in the ADD5 pattern.
- added functions 'setColumnAttributes()' and 'unsetColumnAttributes()' to 'include.general.inc' to allow columns in a horizontal display to be hidden or unhidden.
- added functions 'getColumnHeadings()' and 'setColumnHeadings()' to 'include.general.inc' to allow column headings in a horizontal display to be modified.
- added the ability to specify that all the fields in a particular row in a multi-row update area, such as in a MULTI2 pattern, should be set to 'noedit'. This can be achieved by adding the pseudo-column 'rdc_rowspecs' with the value 'array('noedit' => 'y')' to the row in question.

2008-03-01, version 1.34.0
- made it possible to include '../menu/logon.php' from another script in order to allow additional logon screens for different purposes. Each logon can have its own footer.txt and CSS entries.
- modified LIST2, LIST3, MULTI2, MULTI3 and MULTI4 controllers so that the contents of 'Selection (fixed)' from the MNU_TASK table is made available in $this->sql_where for all middle and inner entities. This is because the value may get filtered out when the $where string is extracted from the previous entity.
- modified the '_sqlAssembleWhere()' method in 'std.table.class.inc' so that if the WHERE string contains a reference to a name which appears as an alias name in the select list (i.e: 'name AS alias') it will be moved to the HAVING string, thus avoiding an SQL error. This makes the solution in FAQ 85 obsolete.
- modified the mechanism by which primary keys are extracted from one object for passing to another object, either within the same task or a different (child) task. By default only the fields which are part of the primary key will be included in the $where string, but this list can be altered at runtime within the _cm_getPkeyNames() method.
- modified the mechanism by which the $where string which is passed down from the previous object, either within the same task or a different (parent) task, is filtered during the initialise() method. By default any field which does not exist in the $fieldspec array will be filtered out, but additional fields can be added to the list within the _cm_filterWhere() method.
- fixed bug in dict_database(import) which failed to deal correctly with a non-null value in $GLOBALS['dbprefix'].
- added the ability to change the hyperlinks above the menu bar from text to images. Refer to http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq99 for details.
- added 'Search' navigation buttons to the various 'mnu_initial_value_role/user' tasks. Please run script radicore\menu\sql\menu.menu_export(2008-02-07).sql to import these changes.
- modified structure of USER and TASK_FIELD tables in the MENU database. You will need to run script radicore\menu\sql\mysql\alter_table(2008-02-27).sql to modify your existing database.

2008-02-01, version 1.33.0
- modified MENU database to include a new LANGUAGE table which will help when providing application data in multiple languages. This is documented in http://www.tonymarston.net/php-mysql/internationalisation2.html. You will need to run the following scripts:
-- radicore\menu\sql\mysql\alter_table(2008-01-03).sql to modify the database structure.
-- radicore\menu\sql\menu.menu_export(2008-01-03).sql to modify the contents of the MENU database.
- modified DICT database to add new columns to DICT_TABLE table. You will need to run the following script:
-- radicore\dict\sql\mysql\alter_table(2008-01-04).sql
- updated 'dict_table_s02.class.inc' so that the dictionary export facility will include alternative language details in the '<table>.dict.inc' file.
- updated 'std.table.class.inc' to include 'getLanguageEntries()' which ensures that each alternative language table contains a default entry for each supported language.
- updated 'std.list2.inc' so that when the inner table is the same as the alternative language table of the outer table it will call 'getLanguageEntries()' automatically.
- updated 'std.table.class.inc' so that when 'insertRecord()' is used on a table which has an alternative language table it will automatically call 'getLanguageEntries()' to create default entries on the alternative language table for all the supported languages.
- modified the XAMPLE subsystem to demonstrate how the alternative language feature works. You will need to install that subsystem before you can view it.
- modified tables 'initial_value_role' and 'initial_value_user' in the MENU database to include a new 'is_noedit' column. If this is set to TRUE then the field will be set to NOEDIT so that the value cannot be changed.
- modified 'std.table.class.inc' so that the '_getDBMSengine()' method will allow connections to multiple database servers, as documented in http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq92.
- modified the logon process to include the option of additional authorisation via a RADIUS server. Please refer to http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq93 for details.
- modified PDF List View so that additional lines can be printed both before and after the current database record, as documented in http://www.tonymarston.net/php-mysql/output-to-pdf.html#example.list.view.line.breaks
- modified the logon screen to accept user_id and user_password via the URL, thus removing the need for dialog with the user.

2008-01-01, version 1.32.0
- modified 'std.data_field.xsl' to allow the option lists for dropdowns and radio groups to have a separate set of values for each row in a MULTI2 or MULTI3 form.
- modified 'std.data_field.xsl' so that if a text field contains a non-breaking space it will be output as a non-breaking space in the HTML output. This is because when '&nbsp;' is added to the XML document it becomes '&amp;nbsp;' which causes the HTML output to display '&nbsp;' instead of ' '. The string '&amp;nbsp;' is therefore replaced with '&#160' during the XSL transformation.
- fixed bug in 'extractQualifiedFieldNames()' - used in 'qualifyOrderby()' - which failed to deal with 'CASE ... END AS alias' correctly.
- fixed bug in 'resizeImage()' function to use forward slashes instead of back slashes in path names so that it will work on *nix systems.
- fixed bug in task 'wk_workflow(validate)' which caused the SQL query to fail by qualifying a column in the ORDER BY clause with the wrong table name. 
- fixed bug in 'include.sesson.inc', 'include.xml.php4.inc' and 'include.xml.php5.inc' which failed to deal with '$_SERVER['HTTPS']=off' when using IIS.

2007-12-02, version 1.31.0
- modified 'audit_tbl_s01.class.inc' to prevent it from using addslashes() twice with WHERE clauses containing 'name LIKE 'foobar%' as this is now handled differently within each DBMS object.
- fixed bug in 'dml.pgsql.class.inc' which failed to deal correctly with an empty field of type 'varray' when inserting or updating.
- fixed bug in 'dml.pgsql.class.inc' which failed to deal correctly with fields in a WHERE string which contain either a backslash or a single quote.
- fixed bug in 'dml.oracle.php4/5.inc' which failed to deal correctly with fields in a WHERE string which contain either a backslash or a single quote.
- modified 'geLanguageArray()' and 'getLanguageText()' functions to replace 'require_once' with 'require' as files may have to be reloaded.
- modified 'std.table.class.inc' so that all insert/update/delete methods can detect when they are being accessed from a script in a different subsystem in order to set $GLOBALS['classdir']. This is used to retrieve messages from the directory associated with the table class, and not the directory associated with the calling script.
- modified 'std.singleton.php4/5.inc' so that they call the 'initialise()' method after instantiating a new object.
- modified 'include.general.inc' so that 'array2where()' replaces [name=''] with [name IS NULL].
- fixed bug in 'std.data_field.xsl' concerning a multi-line text box in a MULTI2 pattern.
- modified 'include.general.inc' so that if the php.ini setting for 'precision' is less than 15 (the default is 14) it will be set to 15. This is to allow the Data Dictionary to deal properly with the minimum and maximum values for BIGINT columns.
- modified numerous 'std.???.inc' files so that $dbobject->initialise() is called before $dbobject->setOrderBy() so that the contents of $this->fieldspec can be modified before the sort string is validated.
- modified 'std.filepicker1.inc' to allow it to accept search criteria for 'filename' from a 'search' screen which can be activated from the navigation bar.

2007-11-01, version 1.30.0
- modified 'include.general.inc' to allow 'MATCH(...) AGAINST(...)' in query strings for the MySQL database. 
- modified 'getForeignData()' inside 'std.table.class.inc' so that if the lookup on the foreign table fails then the foreign key field(s) are only cleared if they do not form part of the primary key.
- modified 'std.table.class.inc' so that if the 'insertOrUpdate()' method is given an associative array (containing a single database row) it will return an associative array, and if it is given an indexed array (containing a number of database rows) it will return an indexed array.
- modified 'std.table.class.inc' so that the 'getInitialDataMultiple()' method can deal with a $where string that contains ') OR (' to indicate a selection of multiple rows. The input to the '_cm_getInitialDataMultiple()' method will now be a multi-dimensional array, indexed by row number.
- modified 'std.filepicker1.inc' to enable pagination. This currently has a fixed page size of 100 rows which will be displayed in 2 columns of 50 rows each.
- fixed bug in 'std.search1.inc' which treated '0' as empty instead of false for boolean fields.
- fixed bug in the 'setAction()' method within 'std.table.class.inc' which caused a ghost entry to be inserted into an otherwise empty array when either the 'selectall' or 'unselectall' hyperlinks were used in a Multi3, Multi2 and List2 screens.
- fixed bug in 'std.data_field.xsl' when, for a field with a control of 'popup', the field name is the same as the foreign field.
- fixed bug in 'setScreenStructure()' of 'include.xml.php4/5.inc' so that 'size=<string>' is treated as a field name and 'size=<numeric>' is treated as an field attribute. 
- fixed bug in ADD2 pattern which caused it to use $selection instead of $where.
- fixed bug in processing of Multi4 pattern which caused popup in outer table to be directed to the inner table instead.
- fixed bug in 'std.enquire1.inc' which caused it to process the previous selection when restarted with a new selection.
- fixed bug in logon processing which failed to use addslashes() when building the WHERE string from the user's input.
- modified 'dml.mysql.class.inc' and 'dml.mysqli.class.inc' to deal correctly with backslashes in the WHERE string. Values such as [name='value\\'] must be left alone while [name LIKE 'value\\'] must be changed to [name LIKE 'value\\\\'].
- modified 'std.validation.class.inc' so that an integer of size=3 will accept a maximum value of 999, not 127.
- added function 'resizeImage()' to 'include.general.inc'.
- modified 'std.fileupload1.inc' to call resizeImage() if $object->resize_array is not empty.

2007-10-01, version 1.29.0
- renamed MENU tasks in the MENU database so that they conform to the format 'table_name(pattern)suffix'. You will need to run script radicore\menu\sql\menu.menu_export(2007-09-10).sql in order to update any previous installations.
- fixed bug in 'dict_table(export)' when using a PostgreSQL database which failed to deal properly with column types of tinyint and mediumint.
- fixed bug in 'language_detection.inc' which failed to recognise France when the language array contained [fr] instead of [fr-fr].
- fixed bug in 'std.validation.class.inc' which failed to convert French decimal point ',' to '.' before testing for a numeric value.
- fixed bug in 'std.search.inc' which failed to convert French decimal point ',' to '.' before passing search string back to previous form.
- changed 'dict_column(import)' so that it reports the column name instead of the column number in any error messages.
- fixed bug in 'std.tree_view2.inc' which caused the saved version of $dbouter to be lost from the $_SESSION array.
- fixed bug in 'dml.mysql.class.inc' and 'dml.mysqli.class.inc' which did not deal properly with column names used in unique or non-unique keys which contained uppercase characters.
- added an option for Virtual Private Databases (VPD), also known as Row Level Security (RLS). This allows a database table to contain data for multiple accounts, but each user can only access the data for his/her account. This feature is documented in http://www.tonymarston.net/php-mysql/virtual-private-database.html. This will require the following scripts to be run:
-- radicore\menu\sql\mysql\alter_table(2007-09-14).sql - to update the structure of the MENU database
-- radicore\menu\sql\menu.menu_export(2007-09-14).sql - to update the contents of the MENU database
-- radicore\workflow\sql\mysql\alter_table(2007-09-17).sql - to update the structure of the WORKFLOW database
- Added function 'free_result()' to 'std.table.class.inc' to release the resource created by 'getData_serial()'.

2007-09-01, version 1.28.0
- fixed bug which caused message produced by 'Recover Password' task to be lost when returning to the logon page when it is displayed using the HTTPS protocol.
- fixed bug which allowed invalid characters in user passwords to be allowed if they were not encrypted. This caused a problem when using the Control screen to set all passwords from unencrypted to encrypted as this processing would fail if it hit a password which contained invalid characters.
- PDF library changed from http://www.fpdf.org/ to http://tcpdf.sourceforge.net/ as this includes support for UTF-8 unicode fonts and barcode generation.
- fixed bug in $where string processing (converting from string to array and back again) which caused problems when the leading characters of a string field contained relative operators such as '<', '>', '<=', '>=', etc.

2007-08-20, version 1.27.0
- fixed bug in dictionary import when dealing with unsigned FLOAT columns.
- created function 'append2ScriptSequence()' for adding entries to $_SESSION['script_sequence'] to include additional standard processing.
- updated 'std.add1/2.inc', 'std.update1/3.inc' and 'std.multi1/2/3.inc' to check for errors after calling the $dbobject->getExtraData() method.
- fixed bug in 'std.delete2.inc' which made it ignore the contents of $where in favour of $selection.
- updated workflow subsystem to add a new task to list expired workitems (timed items which have gone past their time limit) and a child task to trigger the expired item. This is for those users who do not use a cron job to trigger a selected expired item. Please use script radicore\workflow\sql\workflow.menu_export(2007-08-05).sql to update your menu database.
- fixed bug in getLanguageText() caused when obtaining text from a subsystem other than the current subsystem.
- added tasks 'mnu_menu(list2)a' and 'mnu_nav_button(list2)a' which will show the parents of the selected task instead of its children. You will have to import script 'radicore\menu\sql\menu.menu_export(2007-08-12).sql' to change your menu database.
- fixed bug in 'qualifyWhere()' function where $this->sql_search_table contained 'tablename AS alias'.
- fixed bug which caused 'recover password' function to fail.
- fixed bug which failed to show 'Reset User Password' screen when user is forced to change his password after 'n' days or 'n' logons.

2007-07-25, version 1.26.0
- changed the 'initialise()' method inside 'std.table.class.inc' so that values from 'mnu_initial_value_role' and 'mnu_initial_value_user' can be used as WHERE criteria on any LIST pattern, not just LIST1.
- changed 'std.fileupload1.inc' so that if any type of image can be uploaded then the $filetypes variable can be set to the string value 'image' instead an array of all possible image types.
- modified the MULTI4 pattern so that any editable field in the parent area which also exists in the $fieldspec array of the child will be added to the field data which is given to the child object.
- added '_cm_ListView_header()' method to 'std.table.class.inc' which will be called just before titles are printed at the top of each page. This is a more convenient place to define data values that can be inserted into title elements by means of field names with the '%%' prefix.
- modified 'std.pdf.class.inc' to allow 'type'=>'date/time/pageno' to be used in title elements as well as footer elements.
- corrected 'radicore\default\reports\en\output2.report.inc' which had 'type'=>'text','value'=>'<string>' instead of 'text'=>'<string>' in the title array. 
- modified 'getInitialData()' method inside 'std.table.class.inc' so that if $where contains any 'IS NULL' or 'IS NOT NULL' values then this will not cause those fields to become display-only.
- modified POPUP processing to allow a value to be entered before the POPUP form is called. Please refer to http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq81 for details.
- added the 'choose_single_row' setting for use in POPUP forms so that if only a single row is retrieved from the database then it will automatically be selected without waiting for the user to press the CHOOSE button.
- removed all references to 'javascript_footer' as I have been informed that the issue I was trying to solve was actually being caused by a certain brand of anti-virus software, and my solution was not a real solution after all.
- if any subsystem directory contains a file called 'include.subsystem.inc' then its contents will be included during the inclusion of 'include.general.inc'. This will allow changes at the subsystem level, such as modifying INCLUDE_PATH, defining additional global functions, et cetera.

2007-06-30, version 1.25.0
- changed all dml.*.class.inc' files so that if a value is supplied for an auto_increment column it will be used instead of generating a new one.
- changed 'insertRecord' in 'std.table.class.inc' to skip the insert if the data array is empty. This will allow the array to be cleared in the _cm_validateInsert() method so that the record can be updated manually in the _cm_post_insertRecord() method.
- updated 'std.data_field.xsl' so that it will accept a 'size' attribute on a field in a horizontal display in order to reduce the size of a large field.
- updated 'mnu_subystem(export)' so that the contents of the mnu_control table where record_id='<subsystem>' will be included in the export file. This will allow each subsystem to have its own data on the mnu_control table.
- changed the default behaviour for search screens so that if anything is entered for a string field without a wildcard character '%' then '%' will be appended to the string. This is to emulate the behaviour of other common software where text such as 'ABC' means 'beginning with ABC'.
- changed processing of popup1 screen so that if a navigation button is used to add a new record, upon returning to the popup screen the identity of the new record will automatically be passed back as the selection. This avoids the process of having to find the new record in the popup screen so that the CHOOSE button can be pressed.
- changed the fetchrow() method so that it calls _cm_post_fetchRow() to process a single occurrence instead of _cm_post_getData() which expects multiple occurrences.
- changed 'dml.mysql*.class.inc' so that if 'WITH ROLLUP' is encountered in the GROUP BY clause the ORDER BY string will be ignored. This fixes the problem reported in http://www.radicore.org/forum/index.php?t=msg&th=237
- removed method 'getData_batch()' as it does the same thing as 'getData_serial()'

- added table 'mnu_initial_value_role' and 'mnu_initial_value_user' to the 'menu' database in order to hold initial values for fields within tasks for either roles (groups of users) or individual users. The field names are taken from those entered in the 'List Task Field' screen. The way that this information is used depends on the task being run:
-- if it inserts new records then this data is added to $fieldarray (unless the field already has a non-empty value) just before the call to the '_cm_getInitialData()' method.
-- if it is pattern LIST1 and the $where string is empty it will be inserted into the $where string before any data is retrieved from the database.
The 'mnu_initial_value_role' table will only be read if nothing is found on 'mnu_initial_value_user'. You will need to import file 'radicore\menu\sql\mysql\alter_table(2007-05-26).sql' in order to make these changes to your database schema

- changed the Output2 and Output3 patterns so that the call to _cm_post_output() is surrounded by startTransaction() and commit()/rollback() to allow a database update to take place after the PDF document has been produced.
- created task 'audit_tbl(upd4)' and added it as a navigation button on 'audit_dtl(list)2' in order to generate an SQL query which will reproduce the database change that is currently being displayed. The query string will be appended to a file called 'audit_export.sql' which will be written to the 'radicore\audit\sql' directory. This can be useful when changes made in one database need to be replicated in another database. The details of this new task can be imported into your current MENU database by running script 'radicore\audit\sql\audit.menu_export(2007-06-23).sql' which was created using this facility.

2007-05-01, version 1.24.0
- changed 'std.session.inc' so that the argument 'csxslt=on' in the URL (which turns on client-side XSL transformations) will propagate itself via a cookie instead of being repeated in all subsequent URLs. This is because a session abort will cause this setting in the URL to be lost, which means that the session would restart without that setting in effect.
- amended 'std.table.class.inc' so that the _dml_ReadBeforeUpdate() method will use an additional argument called $this->reuse_previous_select. This is boolean and set to FALSE by default, but can be set to TRUE within the _cm_pre_updateRecord() method. This will allow _dml_ReadBeforeUpdate() to reuse the previous SELECT statement instead of the default 'SELECT * FROM $this->table WHERE pkey=X' in those cases where a field obtained from another table via a JOIN is retrieved and made available for update. Although this other field cannot be updated in the standard updateRecord() mechanism, a change in values can be detected in the _cm_post_updateRecord() method where code can be inserted to update the other table.
- modified 'dml.pgsql.class.inc' to allow columns of type BOOLEAN to be imported correctly into the data dictionary.
- modified 'std.add3.inc' so that error messages generated within the database object are appended to the array which is returned to the previous form instead of being replaced with a generic message.
- modified 'std.data_field.xsl' so that it will process a 'class' attribute on a field entry when constructing a vertical display. This will allow CSS properties to be applied to an individual field instead of all fields which occupy that column in the HTML table.
- modified 'dict_column.class.inc', 'include.xml.php4/5.inc' and 'std.data_field.xsl' to include a new 'multi-checkbox' control which can be used instead of a multi-dropdown when the user can make multiple choices.
- added new pattern 'Update 5' which will take an collection of records and perform either an INSERT or an UPDATE on each record depending on whether it currently exists or not.
- added custom method '_cm_getPkeyNames()' to 'std.table.class.inc' so that the list of primary key fields can be adjusted before the selection string is constructed and passed to a child form when a navigation button is pressed. 
- added custom method '_cm_validateSearch() to 'std.table.class.inc' which will be called before any input to a search screen is passed back to the previous form, thus allowing any custom validation (or other processing) to be performed.

2007-03-30, version 1.23.0
- fixed bug in 'std.list2.inc' and 'std.list3.inc' which failed to deal correctly with a selection returned from a popup form.
- fixed bug in 'dml.mysql.class.inc' and 'dml.mysqli.class.inc' which prevented the tables from a database with a name which is a reserved word (such as 'order') from being imported into the data dictionary.
- fixed bug with an sql SELECT statement containing HAVING, as reported in http://www.radicore.org/forum/index.php?t=msg&th=201
- fixed bug in 'dict_table(generate)b' when dealing with MULTI3 and MULTI4 patterns, as reported in http://www.radicore.org/forum/index.php?t=msg&th=204 
- updated 'std.search1.inc' so that it will automatically include fields from compound keys which are returned from a popup and which are not displayed on the current screen. Previously these fields had to be included in the screen with 'control' => 'hidden' in order to have their values added to the $where string which is returned to the previous form when the SUBMIT button is pressed.
- updated 'std.table.class.inc' to include a new '_cm_post_popupReturn()' method which is called after '_cm_popupReturn()' and 'getForeignData()'.
- updated database schemas to change task_id from varchar(40) to varchar(80), and subsys_id from varchar(8) to varchar(16). Please run the following scripts to update your databases:
-- radicore/audit/sql/mysql/alter_table(2007-03-06).sql
-- radicore/dict/sql/mysql/alter_table(2007-03-06).sql
-- radicore/menu/sql/mysql/alter_table(2007-03-06).sql
-- radicore/workflow/sql/mysql/alter_table(2007-03-06).sql

- updated 'dict/table_export.php' so that it will not export anything for a database table that has no columns.
- updated 'dict/table_popup.php' so that it will not show any tables which have no columns.
- updated '_cm_validateDelete()' method to include a new $parent_table argument. This will be empty for ordinary deletes, but for cascade deletes it will identify the table from which the delete is being initiated.
- modified all XSL stylesheets to improve performance using ideas identified in http://www.radicore.org/forum/index.php?t=msg&th=95&goto=701#msg_701
- updated 'std.validation.class.inc' so that it will retrieve translated field (column) names from the 'language_text.inc' file when constructing error messages. The task 'mnu_subsystem(export)' will include a list of column names when building file '<subsystem>.menu_export.txt'. This is in response to the request at http://www.radicore.org/forum/index.php?t=msg&th=203

2007-03-03, version 1.22.0
- fixed bug in 'dict_table_generate(b)' which failed to create a valid (sub)class file for a table alias. See http://www.radicore.org/forum/index.php?t=msg&th=179 for details.
- fixed bug in 'std.list2.inc' which combined values from $selection and $where, causing the resulting SELECT statement to find no records. See http://www.radicore.org/forum/index.php?t=msg&th=182 for details.
- fixed bug in the updateRecord() method within 'std.table.class.inc' which was reported in http://www.radicore.org/forum/index.php?t=msg&th=189
- fixed bug in 'getForeignData()' method of 'std.table.class.inc' which did not deal correctly with a list of several parent fields instead of the usual single field.
- fixed bug in '_cm_InitialiseFileupload()' method of 'std.table.class.inc' which failed to return $fieldarray, as reported in http://www.radicore.org/forum/index.php?t=msg&th=191
- updated 'mnu_task(pdf)' to include a record count.
- updated 'include.xml.php4.inc', 'include.xml.php5.inc' and 'std.data_field.xsl' to allow a field specification of 'control' => 'hidden' to allow a field value to be included in an HTML form without being visible. This is to allow  that value to be included in the $_POST array for search forms when dealing with compound keys which are returned from a popup, and where not all the fields are visible on the form.
- updated 'std.multi3.inc' so that the middle entity will accept additional selection criteria from a search screen, which can be activated from a navigation button.
- updated the 'updateRecord()' method in all 'dml.*.class.inc' files so that the values for numeric fields are not enclosed in quotes. This is to allow updates such as 'field=field+1' which would otherwise be constructed as 'field='field+1''. See http://www.radicore.org/forum/index.php?t=msg&th=183 for details.
- updated 'mnu_task' table on menu database so that the 'task_desc', 'button_text' and 'script_id' fields have their maximum sizes increased to 80 characters. Please import file radicore/menu/sql/mysql/alter_table(2007-02-12).sql to alter your database schema.
- updated 'dict_database(list)' to include a table count.
- updated 'dict_table_generate(b)' so that for the LIST2 pattern there is the option of selecting the outer entity from a different database to that of the inner entity.
- updated 'std.table.class.inc' so that if a search screen contains the 'curr_or_hist' field without a value it will have an initial value of 'C' (current).

2007-02-05, version 1.21.0
- fixed bug in 'include.session.inc' when using the COPY button on forms which contain dates. These have to be converted from 'dd Mmm YYYY' to 'yyyy-mm-dd' so that when the PASTE button is used they can be converted back to 'dd Mmm yyyy' correctly.
- fixed bug in 'std.link1.inc' which caused popups in 'inner' area not to function properly.
- fixed bug in 'std.validation.class.inc' which did not deal with a missing/invalid custom validation file correctly. See http://www.radicore.org/forum/index.php?t=msg&th=165 for details. 
- updated 'dict_database(import)' so that when table details are imported the 'table_desc' field has underscores removed and the first character of each word upshifted, thus turning 'table_desc' into 'Table Desc'.
- updated 'dict_table(generate)b' so that when entries are added to the 'mnu_task' table all descriptions use the 'table_desc' field and not the 'table_id' field.
- updated 'dict_table(generate)b' so that when generating tasks which require a popup the name of the popup form is requested, not the popup table. This is because the popup may require two tables.
- updated 'std.table.class.inc' to include new custom method '_cm_getOrderBy()'. This can be used when the column name in the orderby clause needs to be adjusted before it can be included in an SQL statement, then adjusted back again so the original column name in the screen can have the ascending/descending icon associated with it.
- updated 'include.general.inc' to automatically add 'menu', 'audit' and 'workflow' directories to include_path, thus removing the need to have them specified in the htaccess file.
- updated 'config.inc' to include $GLOBALS['use_https'] which, if set to TRUE, will cause all pages to use the secure HTTPS protocol instead of the default HTTP.
- updated 'std.table.class.inc' so that it can deal with subqueries of type 'EXISTS (SELECT...)' and 'NOT EXISTS (SELECT...)' in $this->sql_search. 

2007-01-15, version 1.20.0
- updated 'dml.*.class.inc' to avoid 'object to string' conversion errors.
- fixed bug http://www.radicore.org/forum/index.php?t=msg&th=143
- fixed bug in 'std.output2.inc' and 'std.output3.inc' which occasionally caused the pdf output to disappear.
- updated custom validation (http://www.tonymarston.net/php-mysql/custom-validation.html) to allow it to be specified for any type of field, not just strings, and without the need to set SUBTYPE=CUSTOM. This will bypass all validation performed by the framework except for (a) required fields cannot be empty, and (b) value cannot exceed maximum size. All other validation will be performed within the specified custom method.
- created 'dml.oracle.php4.class.inc' and 'dml.oracle.php5.class.inc' to allow connections to an Oracle database. Certain existing column names caused problems as they are reserved words in Oracle, so they have been renamed as follows:
-- database 'audit':
--- table 'audit_ssn', changed 'date' to 'ssn_date' and 'time' to 'ssn_time'.
--- table 'audit_trn', changed 'date' to 'trn_date' and 'time' to 'trn_time'.
--- table 'audit_logon_errors', changed 'timestamp' to 'err_timestamp'.
--- Please import radicore/audit/sql/mysql/alter_table(2006-12-12).sql to alter your database schema.
-- database 'dict':
--- table 'dict_column', changed 'comment' to 'col_comment', 'nosearch' to 'no_search', 'noaudit' to 'no_audit' and  'subtype' to 'col_subtype'. Changed 'user_size' and 'col_maxsize' from NOT NULL to NULL.
--- table 'dict_database', changed 'comment' to 'db_comment'.
--- table 'dict_relationsip', changed 'comment' to 'rel_comment'.
--- table 'dict_table', changed 'comment' to 'tbl_comment'.
--- Please import radicore/dict/sql/mysql/alter_table(2006-12-15).sql to alter your database schema.
-- database 'product':
--- table 'product', changed 'comment' to 'prod_comment'.
--- table 'inventory_item_variance', changed 'comment' to 'var_comment'.
--- table 'prod_cat_class', changed 'comment' to 'pcc_comment'.
--- Please import radicore/product/sql/mysql/alter_table(2006-12-16).sql to alter your database schema.
- update 'dict_column' table in 'dict' database to cater for differences in Oracle database:
-- changed 'col_type' from varchar(12) to varchar(20)
-- changed 'col_array_type' from varchar(12) to varchar(20)
-- added 'col_type_native' varchar(32)
- updated 'std.output2.inc' to allow the option of a totals line at the end of the report. Examples are provided in  'mnu_pattern(pdf).php' and 'mnu_subsystem(pdf).php'.
- updated '_cm_formatData()' method to include a new argument which will allow a custom CSS class (or PDF style) to be specified for selected fields. This will allow the display attributes of those selected fields to be modified at run time. This can be used in financial applications for example to show negative and positive values in different colours. Please see http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq73 for details.
- updated popup and filepicker screens to include a 'Choose Null' button which will cause the current selection to be nullified (cleared). This is different from the 'Cancel' button which will terminate the popup process without making a selection, thus leaving any current selection unchanged.
- added a new record to 'mnu_pattern' table in 'menu' database with pattern_id='OTHER', and updated several entries  on 'mnu_task' table to relate to this pattern_id. See file radicore/menu/sql/mysql/alter_table(2007-01-10).sql for details.
- changed the method of putting blank entries into lookup arrays (used by dropdown lists and radio groups) to solve the problem identfied in http://www.radicore.org/forum/index.php?t=msg&th=156
- updated 'error.inc' to include E_RECOVERABLE_ERROR (introduced in PHP 5.2) in its list of non-fatal error codes.

2006-12-05, version 1.19.0
- fixed bug in 'std.multi2.inc' which caused screen contents not to be refreshed when returning from a form which was not a popup.
- fixed all page controllers so that when the RESET button is pressed this will cause the initialise() method to be called on all objects. This is in case any one of these objects wishes to start at something other than the first record. This is to solve the problem identified in http://www.radicore.org/forum/index.php?t=msg&th=133
- updated 'dml.*.class.inc' to allow database names with '-' (hyphen) instead of '_' (underscore), otherwise they cannot be imported into the data dictionary. For MySQL this uses 'sql_mode='ANSI_QUOTES' so that database names can be enclosed in double quotes as well as backticks. If your version of MySQL is before 4.1 then you must go ino MySQL Administrator->Startup Variables->Advanced and ensure that 'Use ANSI SQL' is checked ON. If your version of MySQL is 4.1 or later this option will be set programatically.
- amended 'dict_column(upd)' to allow the AUTO-UPDATE setting for fields of type INTEGER. This can be used with a special field named 'rdcversion' (Radicore Version Number) to help prevent simultaneous updates of the same database record. See http://www.tonymarston.net/php-mysql/infrastructure-faq.html#faq70 for details.

2006-11-18, version 1.18.0
- added option for each subsystem to show its version number. If a file called 'version.txt' is found in a subsystem's subdirectory then its contents (up to 20 characters) will be displayed at the bottom of the screen.
- fixed bug in 'include.session.inc' which caused the 'Log SQL queries?' option in the 'Update Session data' screen not to be carried forward.
- fixed bug in 'std.update2.inc' which prevented it from calling the popup task.
- fixed bug in 'tree_nde_jnr.popup.php' which prevented it from displaying the correct entries.
- fixed bug in 'dict_table(generate)b' which did not replace '#popup_table#' in the component script with null if no value has been supplied.
- fixed bug in 'mnu_task_s02.class.inc' which caused 'mnu_task(rename)' to malfunction.
- fixed bug in 'std.multi4.inc' which failed to refresh screen after returning from a child form which was activated by a navigation button.
- fixed bug which caused 'std.multi4.inc' to retrieve primary key from the wrong entity when passing selection to a child form.
- fixed bug which caused 'std.output2.inc' and 'std.output3.inc' to return to the previous screen after writing the PDF output to disk instead of sending it the browser. 
- fixed bug in 'std.filepicker.list1.xsl' which prevented images from being displayed with the specified width and height.
- fixed bug in the logon screen when run with Microsoft IIS which caused it to use HTTPS even when an HTTPS server had not been specified.
- fixed bug with ENUM types as reported in http://www.radicore.org/forum/index.php?t=msg&th=123

- changed the way the FILEDOWLOAD pattern is implemented. Instead of having the options defined in the _cm_pre_getData() method of the table class they now go into the _cm_initialiseFileDownload() method. Please see  http://www.tonymarston.net/php-mysql/dialog-types.html#filedownload for details.
- changed the way the FILEPICKER pattern is implemented. Instead of having the options defined in the component script they now go into the _cm_initialiseFilePicker() method of the table class. Please see  http://www.tonymarston.net/php-mysql/dialog-types.html#filepicker for details.

- modified 'dict_table(generate)b' so that it will include alias names from relationships in the dropdown list of table names.
- modified 'mnu_task(rename)' to replace any embedded spaces with '_' (underscore) because when used in navigation buttons embedded spaces are automatically changed to '_' in the $_POST array, and this causes the lookup using that task_id to fail.
- modified the '_cm_pre_getData()' method so that it now includes the $fieldarray argument.
- modified XSL stylesheets so that they will accept the 'nosort' parameter to remove all sorting hyperlinks from the column headings. This feature can be turned on by inserting the line '$this->xsl_params['nosort'] = 'y';' in your table class.
- modified 'Export Subsystem' so that the file '<subsystem>/sql/<subsystem>.menu_export.sql' includes all MNU_ROLE entries which are found on the MNU_ROLE_TASK table for all tasks within the selected subsystem.
- modified 'Export Subsystem' so that the file '<subsystem>/text/en/<subsystem>.menu_export.txt' is created without the 4 character indent on each line.
- modified 'std.update1.inc' so that it can generate a 'paste' button if the ''copy' button is pressed (for use in 'dict_table(generate)b').
- made 'xsl/std.list2.xsl' the same as 'xsl/std.multi2.xsl', which means that 'std.multi2.xsl' is now redundant. This means that all screen structure scripts which refer to 'std.multi2.xsl' should be changed.
- modified 'std.multi4.inc' so that it generates the message 'N records have been updated on XXX' for both database tables.
- modified 'sample.validation.class.inc' and 'std.validation.class.inc' so that the $input parameter on the custom methods is passed by reference, thus allowing the value to be changed inside the method.
- modified 'dml.*.class.inc' so that if a table is read during a database transaction (i.e. between 'start transaction' and 'commit/rollback') then the SELECT statement is altered to include 'LOCK IN SHARE MODE' (MySQL) or 'FOR UPDATE' (PostgreSQL).

2006-10-18, version 1.17.0
- fixed bug which caused an invalid sql statement to be created when navigating from 'List To-Do by User' to 'List Audit Details'. This was caused by an inappropriate entry in $search not being filtered out as it specified a tablename which was not defined in the FROM clause.
- fixed bug in xample/sql/mysql/xample-schema.sql by adding in missing column 'fckeditor_test'.
- fixed bug in menu/classes/mnu_user.class.inc as reported in http://www.radicore.org/forum/index.php?t=msg&th=99.
- fixed bug in product_category.class.inc which caused non-database field 'rollup' to be qualified with a table name when selected as a sort item, thus causing an invalid SQL statement to be generated.
- fixed bug in include.xml.php5.inc where it was calling ->set_attribute() instead of ->setAttribute().
- removed global variable $popup_where as it is redundant,
- removed entries for 'POPUP', 'TREE1POPUP' and 'TREE2POPUP' from MNU_PATTERN table in MENU database. These have been replaced by 'POPUP1', 'POPUP2', 'POPUP3' and 'POPUP4'. Please import radicore/menu/sql/mysql/alter_table(2006-09-06).sql to delete the old entries and radicore/menu/sql/menu.menu_export.sql to insert the new entries.
- changed dict_column(import) so that the default value for column_desc is column_id, but with '_' (underscore) replaced with ' ' (space), then the first character of each word shifted to upper case.
- changed include.session.inc so that when navigating to 'audit_dtl(list)3' the selection criteria includes the current database_id, and when navigating to 'audit_dtl(list)3exact' the selection criteria includes the current database_id and table_id.
- added a series of 'xxx-wide' CSS files which set the screen width to 100% instead of 750px. This is for people with screen resolutions which are greater than 800x600.
- added function getPatternId() to file 'include.session.inc' to return the pattern_id of the selected script.
- added task 'mnu_subsystem(build)' which will build the directory structure for a new subsystem. You will need to import radicore/menu/sql/menu.menu_export.sql to see this task.
- added task 'dict_table(generate)a' and 'dict_table(generate)b' which will generate the component scripts and screen structure scripts for selected tables and transaction patterns. You will need to import radicore/dict/sql/dict.menu_export.sql to see these tasks.

2006-09-18, version 1.16.0
- updated popup processing to allow a MULTI4 pattern to have popup controls in both the single occurrence of the OUTER entity and the multiple occurrences of the INNER entity.
- found and fixed several E_NOTICE errors.

2006-09-11, version 1.15.0
- fixed bug in 'includes/std.table.class.inc' where '_examineWorkflow()' method failed to initialise $this->errors.
- fixed bug in 'includes/include.general.inc' which caused the 'fixTrueFalse()' method to corrupt values in some circumstances.
- fixed bug in 'includes/include.session.inc' which caused the 'childform()' method to load previous search criteria using $dbobject->tablename instead of $dbobject->sql_search_table.
- modified search screen to allow operators of '<=', '<', '>=', '>', '<>' and '!=' to be used on numeric fields.
- modified various components in order to allow any search criteria used in a task to be made available to a child task so that the same search criteria can be applied in the child.

- updated DICT schema to include a 'custom_validation' field on the DICT_COLUMNS table. You will need to import radicore/dict/sql/mysql/alter_table(2006-09-09).sql to make this change. You should also import radicore/dict/sql/dict.dict_export.sql to update the Data Dictionary.
- added 'CUSTOM' to the list of subtypes in the dict_column(upd) screen, as well as a 'custom_validation' field.
- modified 'x_person_addr' table in data dictionary to make use of the custom validation feature. You should import radicore/xample/sql/xample.dict_export.sql to update the Data Dictionary. This uses the contents of file 'sample.validation.class.inc'.

2006-08-28, version 1.14.0
- added pattern 'Output1' to the MENU database and created controller 'includes/std.output1.inc'. You will need to import /radicore/menu/sql/menu.menu_export.sql to see this change.
- added task 'x_person(csv)' to the Example Prototype which demonstrates how to use the output1 pattern to export data to a CSV file. You will need to import /radicore/xample/sql/xample.menu_export.sql to see this change.
- fixed a bug in 'includes/std.session.inc' which passed the contents of any search criteria down to all child forms instead of selected child forms, as reported in http://www.radicore.org/forum/index.php?t=msg&th=83&start=0
- fixed a bug in '/xample/screens/en/person_detail.screen.inc' which caused fields to be displayed out of alignment in the Add screen.
- fixed a bug in '/dict/classes/dict_related_column_s01.class.inc' which caused the wrong value to be written to the 'seq_in_index' column.
- fixed a bug in 'includes/std.table.class.inc' which caused data from a field of type SET (MySQL) or ARRAY (PostgreSQL) to be lost after navigating to another screen.
- added PDF library from www.fpdf.org which is extended by 'std.pdf.class.inc'
- added patterns 'output2' and 'output3' to the menu database and created controllers 'includes/std.output2.inc' and 'includes/std.output3.inc'. You will need to import /radicore/menu/sql/menu.menu_export.sql to see this change.
- added tasks 'x_person(pdf)', 'x_person(pdf)2' and 'x_person(pdf)3' to the Example Prototype which demonstrates how to use the output2/3 patterns to export data to a PDF file. You will need to import /radicore/xample/sql/xample.menu_export.sql to see these tasks.
- added several tasks to the DICT subsystem to create PDF output. You will need to import /radicore/dict/sql/dict.menu_export.sql to see these additional tasks.
- added several tasks to the MENU subsystem to create PDF output. You will need to import /radicore/menu/sql/menu.menu_export.sql to see these additional tasks.

2006-08-09, version 1.13.0
- added a multi-select dropdown list to the library of HTML controls supported by the framework.
- updated XAMPLE schema to include a new column called 'favourite_food' to demonstrate a multi-select dropdown list. This uses the MySQL column type of 'set' and the PostgreSQL type of 'array'. You will need to import radicore/xample/sql/mysql/alter_table(2006-08-01).sql to make this change. You should also import radicore/xample/sql/xample.dict_export.sql to update the Data Dictionary.
- updated DICT schema to include a new column called 'col_array_type' on the 'dict_column' table. This is for use on PostgreSQL databases where 'col_type' = 'array' and 'col_array_type' identifies the type of elements within the array, such as 'char', 'varchar', 'integer' or whatever. You will need to import /radicore/dict/sql/mysql/alter_table(2006-08-01).sql to make the change. You should also import radicore/dict/sql/dict.dict_export.sql to update the Data Dictionary.
- an example multi-select dropdown list is now included in the 'Update Person' screen in the 'Example System' prototype.

- added initial support for javascript into the framework. This will allow various pieces of javascript code and events to be defined inside table classes for inclusion in the XML document so that they can be built into the HTML document by the XSL transformation.
- added $GLOBALS['force_javascript_footer'] to file CONFIG.INC which writes the javascript footer manually in the HTML document as it is sometimes not written automatically (don't ask me why).
- added an extra screen to the 'Example System' prototype called 'Update Person (js)' which uses javascript to show a calendar control for the choosing of dates.
- added an extra screen to the 'Example System' prototype called 'Update Person (js2)' which uses javascript to show the FCKeditor control. This is available as a navigation button within 'Update Person (js)'. You will need to import /radicore/xample/sql/xample.menu_export.sql to see these new tasks on the navigation bars.

2006-07-28, version 1.12.0
- added TIMETABLE1 to the list of patterns in the menu database. You will need to import details from radicore/menu/sql/menu.menu_export.sql
- changed several tasks in the Classroom Scheduling prototype to use the TIMETABLE1 pattern. You will need to import details from radicore/classroom/sql/crss.menu_export.sql
- added FILEDOWNLOAD to the list of patterns in the menu database. You will need to import details from /radicore/menu/sql/menu.menu_export.sql
- added person_filedownoad.php to demonstrate the FILEDOWNLOAD pattern. This can be accessed from the 'Enquire Person' screen. You will need to import /radicore/xample/sql/xample.menu_export.sql to load the definition for the new transaction.
- fixed problem with the 'Choose Schedule' option in the Classroom Scheduling prototype.
- amended 'Search Audit detail' screen so that the use of the FROM date/time and TO date/time fields is more logical.
- changed std.add1/2/3.inc so that the contents of $messages is passed back to the previous script.
- changed std.multi3.inc so that it does not read INNER if MIDDLE is empty.
- changed std.treenode.xsl so that it encloses each icon with <span class='icon'>...</span> which allows it to be given its own style attributes in the CSS file.
- renamed column SURVEY_DESC to SURVEY_LONG_NAME on SURVEY.SURVEY_HDR table to be consistent, and changed column MIN_VALUE on SURVEY.NUMBER_OPTION to be required instead of optional.

  You will need to import radicore/survey/sql/mysql/alter_table(2006-07-16).sql
  You will need to import radicore/survey/sql/survey.dict_export.sql

- changed std.multi1.inc to return to calling script if the call to $object->getData() returns an error.
- amended 'Update Menu Control Data' screen to include an option to keep all user passwords hidden.
- changed column ARC_TYPE on WORKFLOW.WF_ARC so that default is 'SEQ' instead of 'NORMAL'.

  You will need to import radicore/workflow/sql/mysql/alter_table(2006-07-19).sql
  You will need to import radicore/workflow/sql/workflow.dict_export.sql

- amended include.session.inc, std.table.class.inc, std.list1/2.inc to allow search criteria used in a parent screen to be passed down to a child screen. For example, screen A shows a list of customers, but only those customers who have orders which satisfy certain selection criteria. Screen B will usually show all orders for a selected customer, but if it is called from screen A it must only show those orders which satisfy the search criteria that was used in screen A. This search criteria is automatically made available to all inner objects in the standard $where argument.
- fixed include.xml.php4/5.inc so that multiple attributes for the same column are grouped together.
- changed std.column_hdg.xsl so that it can deal with <col> attributes of align, valign, char and style (as well as width and class) in the screen structure file.
- changed all css files to remove all text-align and vertical-align specifications for table cells so as not to override what is specified in the screen structure file.
- updated the dictionary details for the MENU database. You can import these details from radicore/menu/sql/menu.dict_export.sql
- updated the dictionary details for the AUDIT database. You can import these details from radicore/audit/sql/audit.dict_export.sql
- updated the dictionary details for the WORKFLOW database. You can import these details from radicore/workflow/sql/workflow.dict_export.sql
- updated the dictionary details for the DICT database. You can import these details from radicore/dict/sql/dict.dict_export.sql
- amended include.general.inc to reference either std.singleton.php4.inc or std.singleton.php5.inc as different code is needed for the different PHP versions.

2006-07-10, version 1.11.0
- fixed problem in php_session.class.inc which was caused by trying to create a duplicate record.
- fixed problem in std.table.class.inc which caused method _sqlAssembleWhereLink() to remove 'A', 'N' or 'D' character from the end of column names.
- changed dml.*.class.inc so that auto_increment key values are enclosed in single quotes when appearing in the PKEY field of the AUDIT_TBL table. This is to make it consistent with all other values, numeric or not.
- changed the menu structure for the PRODUCT prototype to include a set of new inventory transactions.

  You will need to delete the existing data by logging on and running Menu System -> Subsystem, select 'product' then press the 'erase' button.
  Then import new details from radicore/product/sql/product.menu_export.sql

- fixed std.validation.class.inc so that if a required field is empty and (a) it has a default value defined and (b) it has an option list defined (for a dropdown or radio group) then the default value is only used if it also appears in the option list. This is for those situations where a numeric required field has a default value of '0' but the option list starts at '1'.
- fixed include.session.inc so that the 'Log SQL Query?' option in the 'Update Task' function works properly.
- changed include.general.inc to include an adjustDate() function.
- changed include.general.inc to include an isPrimaryObject() function.
- fixed xample/pers_opt_xref_del.php so that it refers to table 'x_pers_opt_xref' instead of 'pers_opt_xref'.
- fixed workflow/sql/mysql/workflow-data.sql so that it contains data for the WF_ARC table.
- changed wf_transition table in the workflow database so that role_id is now optional.

  You will need to import radicore/workflow/sql/mysql/alter_table(2006-07-09).sql
  You will need to import radicore/workflow/sql/workflow.dict_export.sql

- fixed workflow processing which failed to deal with a workitem whose context was not an exact match to the current object's primary key. 

2006-06-22, version 1.10.0
- fixed column sizes in audit database to be same as on menu and dict databases:
  audit_trn.task_id should be varchar(40) not (32)
  audit_tbl.base_name should be varchar(64) not (32)
  audit_tbl.table_name should be varchar(64) not (32)

  You will need to import radicore/audit/sql/mysql/alter_table(2006-06-20).sql
  You will need to import radicore/audit/sql/audit.dict_export.sql

- fixed task 'audit_dtl(list)3exact' so that 'pattern=exact' is in the 'settings' field instead of the 'Selection (fixed)' field.

  You will need to import radicore/audit/sql/audit.menu_export(2006-06-20).sql

- fixed 'import database' and 'import columns' functions in Data Dictionary to work on a shared server where a value is defined for $GLOBALS['dbprefix'].
- changed 'import database' so that it will allow the user to choose which database to import instead of automatically importing all available databases. It will also import the table names and then activate the 'list tables within database' function.

  You will need to import radicore/dict/sql/dict.menu_export(2006-06-22).sql

2006-06-19, version 1.9.0
- changed the PostgreSQL driver (dml.pgsql.class.inc) to use pg_escape_string() instead of addslashes() following the advice given with the release of version 8.1.4
- changed the MySQL drivers (dml.mysql.class.inc and dml.mysqli.class.inc) to use SQL_CALC_FOUND_ROWS and FOUND_ROWS() to obtain row count. This fixes a problem using SELECT count(*) with a GROUP BY clause.
- updated file include.xml.php5.inc to include the align_hv/align_lr specifications for radio groups and the align_lr specification for checkboxes.
- updated various xsl stylesheets and templates to use the variable 'zone' instead of 'table' to be consistent with the documentation.
- changed std.validation.class.inc to use the default value (if it has been defined) when no value has been supplied, even when the field is not marked as 'required'.
- changed std.datevalidation.class.inc to deal with a choice of 'dmy', 'mdy' and 'ymd' date formats. The choice can be set in $GLOBALS['date_format'] in the CONFIG.INC file. Will default to 'dmy' if not specified. 
- fixed bug in audit_dtl_list3.php which prevented the message 'No parent has been selected yet' from being displayed when no parent had been selected.
- created directory CSS to hold a series of css files (which makes 'radicore/style_default.css' redundant), and modified mnu_session_upd.php to allow the user to choose one. This choice will be stored in a cookie so that it persists beyond the current session.
- moved all individual 'radicore/<subsys>/images' subdirectories into a single 'radicore/images' directory.
- changed the images, css files and xsl files which deal with tree structures to improve the screen display.

2006-05-16, version 1.8.0
- added an extra parameter ($where_array) to _cm_fileUpload() method so that the contents of the $where string which was passed to initialiseFileUpload() are available for processing.
- changed audit_* tables from MyISAM to INNODB to incorporate transactional processing. See file radicore/audit/sql/mysql/alter_table(2006-05-11).sql for details.
- added control='hyperlink' to columns within data dictionary which causes a URL to be displayed as a clickable link.
- removed the call to addslashes() from the validateField() function as the escaped field could be echoed back to the user, which would be incorrect. It is now only done in array2where() when creating a WHERE string from an array, and in the DAO when constructing SQL query strings.

2006-04-30, version 1.7.0
- added 'recover password' link to logon screen which will allow a user to request an e-mail containing his password.
- amended table MNU_USER in MENU database to make EMAIL_ADDR a unique key.
- added column ALIGN_LR to DICT_COLUMN table in DICT database.
- added column CHECKBOX_LABEL to DICT_COLUMN able in DICT database.
- added CHECKBOX to list of available controls in DICT_COLUMN screen, with ability to put the optional label text on either the left or right.
- amended std.fileupload1.inc and std.table.class.inc to include new initialiseFileUpload() and fileUpload() methods to add more flexibility to the file upload function.

  You will need to import radicore/menu/sql/mysql/alter_table(2006-04-24).sql
  You will need to import radicore/menu/sql/menu.dict_export.sql
  You will need to import radicore/dict/sql/mysql/alter_table(2006-04-25).sql

2006-04-21, version 1.6.0
- amended files include.xml.php4/5.inc so that function setCSSfiles() uses $_SERVER['HTTP_HOST'] instead of $_SERVER['SERVER_NAME'] to fix problem http://www.radicore.org/forum/index.php?t=msg&th=5&start=0
- added a 'logout (all)' option to the menu bar
- updated Menu Control Data to include shutdown periods during which the system will be inaccessible.

2006-04-13, version 1.5.1
- fixed problem in file include.xml.php5.inc when attempting to perform XSL transformations on the client.
- fixed problem which prevented script help_text_multi.php from deleting entries.
- fixed problem with scripts mnu_role_taskfield_multi(a) and (b) where entries not yet defined on the database were not being displayed with default values.
- fixed problem in files dml.*.class.inc caused by SELECT count(*) containing a GROUP BY clause.

2006-04-10, version 1.5.0
- changed MENU database - see radicore/menu/sql/mysql/alter_table(2006-03-27).sql 
- added $GLOBALS['log_xml_document'] to CONFIG.INC.DEFAULT file to allow all XML files to be written to disk as a debugging aid.
- added task wf_workitem(upd) - load file /workflow/sql/workflow.menu_export.sql to add this to your menu database.
- added task mnu_session(upd) - load file /menu/sql/menu.menu_export.sql to add this to your menu database.
- removed $GLOBALS['use_HTTPS'] from CONFIG.INC.DEFAULT. This as been replaced by $GLOBALS['http_server'], $GLOBALS['https_server'] and $GLOBALS['https_server_suffix'] as it is possible to use a shared secured server which has a different host name.

2006-03-21, version 1.4.0
- created 5 sample workflows (see notes in /radicore/workflow/docs).
- created an audit_dtl(del) job to delete entries from the audit database, but this will not
  appear on any navigation button until you set 'disabled = FALSE' on the task details.
- changed MENU database - see radicore/menu/sql/mysql/alter_table(2006-03-15).sql

  You will need to import radicore/workflow/sql/mysql/workflow-data.sql
  You will need to import radicore/audit/sql/audit.menu_export.sql

2006-03-12, version 1.3.0
- changed AUDIT database - see radicore/audit/sql/mysql/alter_table(2006-03-07).sql
- changed MENU database - see radicore/menu/sql/mysql/alter_table(2006-03-06).sql
- changed WORKFLOW database - radicore/workflow/sql/mysql/alter_table(2006-02-13).sql

- updated file CONFIG.INC.DEFAULT to include a new setting $GLOBALS['use_HTTPS'] which by default is FALSE.
- changed the _cm_popupCall() method in radicore/includes/std.table.class.inc so that $settings is now an array instead of a string. So instead of 
    $settings = 'select_one = true';
  you will need 
    $settings['select_one'] = true;

  You will need to reload MENU data from radicore/menu/sql/mysql/dict-data.sql
  You will need to reload DICT data from radicore/dict/sql/mysql/dict-data.sql

2006-02-08, version 1.2.0
- changed MENU database - see radicore/menu/sql/mysql/alter_table(2006-02-03).sql
  This adds the ability to cause an automatic screen refresh. 

2006-01-20, version 1.1.0
- changed MENU database - see radicore/menu/sql/mysql/alter_table(2006-01-16).sql
  This adds the ability to write each sql query to a log file.

2006-01-10, version 1.0.0
- first release
