Source for file Validate.php
Documentation is available at Validate.php
// +----------------------------------------------------------------------+
// | PHP versions 4 and 5 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
// | Stig. S. Bakken, Lukas Smith |
// | All rights reserved. |
// +----------------------------------------------------------------------+
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
// | API as well as database abstraction for PHP applications. |
// | This LICENSE is in the BSD license style. |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution. |
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
// | Lukas Smith nor the names of his contributors may be used to endorse |
// | or promote products derived from this software without specific prior|
// | written permission. |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
// | POSSIBILITY OF SUCH DAMAGE. |
// +----------------------------------------------------------------------+
// | Author: Christian Dickmann <dickmann@php.net> |
// | Author: Igor Feghali <ifeghali@php.net> |
// +----------------------------------------------------------------------+
// $Id: Validate.php,v 1.31 2007/03/28 18:36:37 ifeghali Exp $
* Validates an XML schema file
* @author Igor Feghali <ifeghali@php.net>
function __construct($fail_on_invalid_names = true , $valid_types = array (), $force_defaults = true )
function MDB2_Schema_Validate($fail_on_invalid_names = true , $valid_types = array (), $force_defaults = true )
$this->__construct($fail_on_invalid_names, $valid_types, $force_defaults);
* Verifies if a given value can be considered boolean. If yes, set value
* to true or false according to its actual contents and return true. If
* not, keep its contents untouched and return false.
* @param mixed value to be checked
if ($value === 0 || $value === 1 || $value === '') {
* Checks whether the definition of a parsed table is valid. Modify table
* definition when necessary.
* @param array multi dimensional array that contains the
* tables of current database.
* @param array multi dimensional array that contains the
* structure and optional data of the table.
* @param string name of the parsed table
* @return bool|errorobject
/* Have we got a name? */
'a table has to have a name');
/* Table name duplicated? */
if (is_array($tables) && isset ($tables[$table_name])) {
'table "'. $table_name. '" already exists');
/* Table name reserved? */
if (in_array($name, $GLOBALS['_MDB2_Schema_Reserved'][$rdbms])) {
'table name "'. $table_name. '" is a reserved word in: '. $rdbms);
if (empty ($table['was'])) {
$table['was'] = $table_name;
/* Have we got fields? */
if (empty ($table['fields']) || !is_array($table['fields'])) {
'tables need one or more fields');
$autoinc = $primary = false;
foreach ($table['fields'] as $field_name => $field) {
if (!empty ($field['autoincrement'])) {
'there was already an autoincrement field in "'. $table_name. '" before "'. $field_name. '"');
$autoinc = $primary = true;
* this have to be done here as we can't
* guarantee that all table fields were already
* defined in the moment we are parssing indexes
if (!empty ($table['indexes']) && is_array($table['indexes'])) {
foreach ($table['indexes'] as $name => $index) {
if (!empty ($index['primary'])) {
* Lets see if we should skip this index since there is
* already an auto increment on this field this implying
if ($autoinc && count($index['fields']) == '1') {
'there was already an primary index or autoincrement field in "'. $table_name. '" before "'. $name. '"');
if (!$skip_index && is_array($index['fields'])) {
foreach ($index['fields'] as $field_name => $field) {
if (!isset ($table['fields'][$field_name])) {
'index field "'. $field_name. '" does not exist');
if (!empty ($index['primary'])
&& !$table['fields'][$field_name]['notnull']
'all primary key fields must be defined notnull in "'. $table_name. '"');
unset ($table['indexes'][$name]);
* Checks whether the definition of a parsed field is valid. Modify field
* definition when necessary.
* @param array multi dimensional array that contains the
* fields of current table.
* @param array multi dimensional array that contains the
* structure of the parsed field.
* @param string name of the parsed field
* @return bool|errorobject
/* Have we got a name? */
/* Field name duplicated? */
if (is_array($fields) && isset ($fields[$field_name])) {
'field "'. $field_name. '" already exists');
/* Field name reserverd? */
if (in_array($name, $GLOBALS['_MDB2_Schema_Reserved'][$rdbms])) {
'field name "'. $field_name. '" is a reserved word in: '. $rdbms);
if (empty ($field['type'])) {
'no field type specified');
'no valid field type ("'. $field['type']. '") specified');
'unsigned has to be a boolean value');
'fixed has to be a boolean value');
'length has to be an integer greater 0');
// if it's a DECIMAL datatype, check if a 'scale' value is provided:
// <length>8,4</length> should be translated to DECIMAL(8,4)
&& !empty ($field['length'])
&& strpos($field['length'], ',') !== false
list ($field['length'], $field['scale']) = explode(',', $field['length']);
if (empty ($field['was'])) {
$field['was'] = $field_name;
if (empty ($field['notnull'])) {
$field['notnull'] = false;
'field "notnull" has to be a boolean value');
&& $field['type'] != 'clob' && $field['type'] != 'blob'
$field['default'] = $this->valid_types[$field['type']];
if ($field['type'] == 'clob' || $field['type'] == 'blob') {
'"'. $field['type']. '"-fields are not allowed to have a default value');
if ($field['default'] === '' && !$field['notnull']) {
$field['default'] = null;
if (isset ($field['default'])
'default value of "'. $field_name. '" is incorrect: '. $result->getUserinfo ());
if (!empty ($field['autoincrement'])) {
if (!$field['notnull']) {
'all autoincrement fields must be defined notnull');
if (empty ($field['default'])) {
} elseif ($field['default'] !== '0' && $field['default'] !== 0 ) {
'all autoincrement fields must be defined default "0"');
* Checks whether a parsed index is valid. Modify index definition when
* @param array multi dimensional array that contains the
* indexes of current table.
* @param array multi dimensional array that contains the
* structure of the parsed index.
* @param string name of the parsed index
* @return bool|errorobject
'an index has to have a name');
if (is_array($table_indexes) && isset ($table_indexes[$index_name])) {
'index "'. $index_name. '" already exists');
'field "unique" has to be a boolean value');
'field "primary" has to be a boolean value');
if (empty ($index['was'])) {
$index['was'] = $index_name;
// {{{ validateIndexField()
* Checks whether a parsed index-field is valid. Modify its definition when
* @param array multi dimensional array that contains the
* fields of current index.
* @param array multi dimensional array that contains the
* structure of the parsed index-field.
* @param string name of the parsed index-field
* @return bool|errorobject
if (is_array($index_fields) && isset ($index_fields[$field_name])) {
'index field "'. $field_name. '" already exists');
'the index-field-name is required');
if (empty ($field['sorting'])) {
$field['sorting'] = 'ascending';
} elseif ($field['sorting'] !== 'ascending' && $field['sorting'] !== 'descending') {
// {{{ validateSequence()
* Checks whether the definition of a parsed sequence is valid. Modify
* sequence definition when necessary.
* @param array multi dimensional array that contains the
* sequences of current database.
* @param array multi dimensional array that contains the
* structure of the parsed sequence.
* @param string name of the parsed sequence
* @return bool|errorobject
'a sequence has to have a name');
if (is_array($sequences) && isset ($sequences[$sequence_name])) {
'sequence "'. $sequence_name. '" already exists');
if (in_array($name, $GLOBALS['_MDB2_Schema_Reserved'][$rdbms])) {
'sequence name "'. $sequence_name. '" is a reserved word in: '. $rdbms);
if (empty ($sequence['was'])) {
$sequence['was'] = $sequence_name;
if (!empty ($sequence['on'])
&& (empty ($sequence['on']['table']) || empty ($sequence['on']['field']))
'sequence "'. $sequence_name. '" on a table was not properly defined');
// {{{ validateDatabase()
* Checks whether a parsed database is valid. Modify its structure and
* @param array multi dimensional array that contains the
* structure and optional data of the database.
* @return bool|errorobject
/* Have we got a name? */
if (!is_array($database) || !isset ($database['name']) || !$database['name']) {
'a database has to have a name');
/* Database name reserved? */
if (in_array($name, $GLOBALS['_MDB2_Schema_Reserved'][$rdbms])) {
'database name "'. $database['name']. '" is a reserved word in: '. $rdbms);
if (isset ($database['create'])
'field "create" has to be a boolean value');
if (isset ($database['overwrite'])
&& $database['overwrite'] !== ''
'field "overwrite" has to be a boolean value');
* This have to be done here as we can't guarantee that all tables
* were already defined in the moment we are parsing indexes
if (isset ($database['sequences'])) {
foreach ($database['sequences'] as $seq_name => $seq) {
&& empty ($database['tables'][$seq['on']['table']]['fields'][$seq['on']['field']])
'sequence "'. $seq_name. '" was assigned on unexisting field/table');
// {{{ validateDataField()
* Checks whether a parsed DML-field is valid. Modify its structure when
* necessary. This is called when validating INSERT and
* @param array multi dimensional array that contains the
* definition for current table's fields.
* @param array multi dimensional array that contains the
* parsed fields of the current DML instruction.
* @param string array that contains the parsed instruction field
* @return bool|errorobject
'field-name has to be specified');
if (is_array($instruction_fields) && isset ($instruction_fields[$field['name']])) {
'field "'. $field['name']. '" already initialized');
if (is_array($table_fields) && !isset ($table_fields[$field['name']])) {
'"'. $field['name']. '" is not defined');
if (!isset ($field['group']['type'])) {
'"'. $field['name']. '" has no initial value');
if (isset ($field['group']['data'])
&& $field['group']['type'] == 'value'
&& $field['group']['data'] !== ''
&& PEAR ::isError ($result = $this->validateDataFieldValue($table_fields[$field['name']], $field['group']['data'], $field['name']))
'value of "'. $field['name']. '" is incorrect: '. $result->getUserinfo ());
// {{{ validateDataFieldValue()
* Checks whether a given value is compatible with a table field. This is
* done when parsing a field for a INSERT or UPDATE instruction.
* @param array multi dimensional array that contains the
* definition for current table's fields.
* @param string value to fill the parsed field
* @param string name of the parsed field
* @return bool|errorobject
* @see MDB2_Schema_Validate::validateInsertField()
switch ($field_def['type']) {
if (!empty ($field_def['length']) && strlen($field_value) > $field_def['length']) {
'"'. $field_value. '" is larger than "'. $field_def['length']. '"');
$field_value = pack('H*', $field_value);
if (!empty ($field_def['length']) && strlen($field_value) > $field_def['length']) {
'"'. $field_value. '" is larger than "'. $field_def['type']. '"');
if ($field_value != ((int) $field_value)) {
'"'. $field_value. '" is not of type "'. $field_def['type']. '"');
//$field_value = (int)$field_value;
if (!empty ($field_def['unsigned']) && $field_def['unsigned'] && $field_value < 0 ) {
'"'. $field_value. '" signed instead of unsigned');
'"'. $field_value. '" is not of type "'. $field_def['type']. '"');
if (!preg_match('/([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})/', $field_value)
&& $field_value !== 'CURRENT_DATE'
'"'. $field_value. '" is not of type "'. $field_def['type']. '"');
if (!preg_match('/([0-9]{4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/', $field_value)
&& $field_value !== 'CURRENT_TIMESTAMP'
'"'. $field_value. '" is not of type "'. $field_def['type']. '"');
if (!preg_match("/([0-9]{2}):([0-9]{2}):([0-9]{2})/", $field_value)
&& $field_value !== 'CURRENT_TIME'
'"'. $field_value. '" is not of type "'. $field_def['type']. '"');
if ($field_value != (double) $field_value) {
'"'. $field_value. '" is not of type "'. $field_def['type']. '"');
//$field_value = (double)$field_value;
Documentation generated on Mon, 11 Mar 2019 14:58:01 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|