<?php
/*
FormHandler v3
Revision: $Date: 2005/05/04 13:08:55 $
Look for more info at http://www.formhandler.net
*/
// make sure this file is not accessed directly
if(strtolower(basename($_SERVER['PHP_SELF'])) == strtolower(basename(__FILE__))) {
die("This file cannot be accessed directly! Include it in your script instead!");
}
/******* BUILD IN VALIDATOR FUNCTIONS ****/
define('FH_STRING', 'IsString', true); // any string that doesn't have control characters (ASCII 0 - 31) but spaces are allowed
define('FH_ALPHA', 'IsAlpha', true); // only letters a-z and A-Z
define('FH_DIGIT', 'IsDigit', true); // only numbers 0-9
define('FH_ALPHA_NUM', 'IsAlphaNum', true); // letters and numbers
define('FH_INTEGER', 'IsInteger', true); // only numbers 0-9 and an optional - (minus) sign (in the beginning only)
define('FH_FLOAT', 'IsFloat', true); // like FH_INTEGER, only with , (comma)
define('FH_FILENAME', 'IsFilename', true); // a valid file name (including dots but no slashes and other forbidden characters)
define('FH_BOOL', 'IsBool', true); // a boolean (TRUE is either a case-insensitive "true" or "1". Everything else is FALSE)
define('FH_VARIABLE', 'IsVariabele', true); // a valid variable name (letters, digits, underscore)
define('FH_PASSWORD', 'IsPassword', true); // a valid password (alphanumberic + some other characters but no spaces: ASCII 33 - 126)
define('FH_URL', 'IsURL', true); // a valid URL (http connection is used to check if url exists!)
define('FH_EMAIL', 'IsEmail', true); // a valid email address (only checks for valid format: xxx@xxx.xxx)
define('FH_EMAIL_HOST', 'IsEmailHost', true); // like FH_EMAIL only with host check
define('FH_TEXT', 'IsText', true); // like FH_STRING, but newline characters are allowed
define('FH_NOT_EMPTY', 'notEmpty', true); // check if the value is not empty
# for dutch people
define('FH_POSTCODE', 'IsPostcode', true); // valid dutch postcode (eg. 9999 AA)
define('FH_PHONE', 'IsPhone', true); // valid dutch phone-number(eg. 058-2134778)
# same as above, but with these the value is not required
define('_FH_STRING', '_IsString', true);
define('_FH_ALPHA', '_IsAlpha', true);
define('_FH_DIGIT', '_IsDigit', true);
define('_FH_ALPHA_NUM', '_IsAlphaNum', true);
define('_FH_INTEGER', '_IsInteger', true);
define('_FH_FLOAT', '_IsFloat', true);
define('_FH_FILENAME', '_IsFilename', true);
define('_FH_BOOL', '_IsBool', true);
define('_FH_VARIABLE', '_IsVariabele', true);
define('_FH_PASSWORD', '_IsPassword', true);
define('_FH_URL', '_IsURL', true);
define('_FH_EMAIL', '_IsEmail', true);
define('_FH_EMAIL_HOST', '_IsEmailHost', true);
define('_FH_TEXT', '_IsText', true);
define('_FH_POSTCODE', '_IsPostcode', true);
define('_FH_PHONE', '_IsPhone', true);
// make some variables global when the version < 4.1.0
if(IntVal( str_replace('.', '', phpversion()) ) < 410) {
define('_global', false);
$_GET =& $HTTP_GET_VARS;
$_POST =& $HTTP_POST_VARS;
$_FILES =& $HTTP_POST_FILES;
$_SERVER =& $HTTP_SERVER_VARS;
} else {
define('_global', true);
}
// Fields
define('FH_INCLUDE_DIR', dirname(__FILE__).'/');
require(FH_INCLUDE_DIR.'fields/class.Field.php');
require(FH_INCLUDE_DIR.'fields/class.TextField.php');
require(FH_INCLUDE_DIR.'fields/class.HiddenField.php');
require(FH_INCLUDE_DIR.'fields/class.TextArea.php');
require(FH_INCLUDE_DIR.'fields/class.PassField.php');
require(FH_INCLUDE_DIR.'fields/class.CheckBox.php');
require(FH_INCLUDE_DIR.'fields/class.RadioButton.php');
require(FH_INCLUDE_DIR.'fields/class.UploadField.php');
require(FH_INCLUDE_DIR.'fields/class.SelectField.php');
require(FH_INCLUDE_DIR.'fields/class.dbSelectField.php');
require(FH_INCLUDE_DIR.'fields/class.ListField.php');
require(FH_INCLUDE_DIR.'fields/class.Editor.php');
require(FH_INCLUDE_DIR.'fields/class.DateField.php');
require(FH_INCLUDE_DIR.'fields/class.TimeField.php');
// Buttons
require(FH_INCLUDE_DIR.'buttons/class.Button.php');
require(FH_INCLUDE_DIR.'buttons/class.SubmitButton.php');
require(FH_INCLUDE_DIR.'buttons/class.ImageButton.php');
require(FH_INCLUDE_DIR.'buttons/class.ResetButton.php');
// Includes
require(FH_INCLUDE_DIR.'includes/class.validator.php');
require(FH_INCLUDE_DIR.'includes/class.imageconverter.php');
require(FH_INCLUDE_DIR.'includes/class.fhMailer.php');
require(FH_INCLUDE_DIR.'includes/config.inc.php');
require(FH_INCLUDE_DIR.'includes/fckeditor.php');
require(FH_INCLUDE_DIR.'includes/error.inc.php');
require(FH_INCLUDE_DIR.'includes/mimeTypes.php');
// DB
require(FH_INCLUDE_DIR.'database/db.php');
require(FH_INCLUDE_DIR.'database/db.mysql.php');
require(FH_INCLUDE_DIR.'database/db.access.php');
require(FH_INCLUDE_DIR.'database/db.postgresql.php');
/**
* class FormHandler
*
* Create a new FormHandler object.
*
*/
class FormHandler
{
// private
var $_fields; // array: contains all the fields
var $_posted; // boolean: if the form is posted or not
var $_name; // string: the name of the form
var $_action; // string: the action of the form
var $_displayErrors; // boolean: if we have to display the errors in the form
var $_mask; // string: the mask which should be used
var $_upload; // array: contains the names of the uploadfields
var $_date; // array: contains the names of the datefields
var $_onCorrect; // string: the callback function when the form is correct
var $_onSaved; // string: the callback function when the form is saved
var $_add; // array: contains the data which was added by the user
var $_sql; // array: contains the names of the added values which are sql functions
var $_dontSave; // array: dont save these fields
var $_focus; // string: the field which should get the focus
var $_convert; // array: fields which should be converted (eg. resizeimage or mergeimage)
var $_gd; // boolean: check if gd is enabled!
var $_db; // object: contains the database object if the option is used
var $_id; // array: the id(s) which we are editing
var $_dbData; // array: the database data
var $_buffer; // array: buffer of set values (used when the field does not exists yet)
var $_eh; // string: the name of the original error handler
var $_text; // array: the language array we are using to display the messages etc
var $_lang; // string: the language used
var $_table; // boolean: set a html table arround the fields or has the user done that in the mask ?
var $_extra; // string: extra tag information for the <form> tag (like CSS or javascript)
var $_pageCounter; // int: how many pages has this form
var $_curPage; // int: current page
var $_mail; // array: contains the mailing data
var $_tabindexes; // array: tab indexes of the fields...
// public
var $insert; // boolean: if the form is an insert-form
var $edit; // boolean: if the form is an edit-form
/**
* FormHandler::FormHandler()
*
* Public constructor: create a new instance of FormHandler
*
* @param string $name: the name of the form
* @return FormHandler
*/
function FormHandler($name = null, $action = null, $extra = null) {
// make vars global if needed
if(!_global) global $_SERVER, $_POST, $_GET;
// try to disable caching from the browser if possible
if(!headers_sent()) {
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
}
// set all config values
fh_conf();
// set the name of the form
if(!empty($name)) {
$this->_name = $name;
} else {
// get a unique form name!
$i = null;
while(defined('FH_'.FH_DEFAULT_FORM_NAME.$i)) {
$i = (is_null($i)) ? 1 : ($i+1);
}
define('FH_'.FH_DEFAULT_FORM_NAME.$i, 1);
$this->_name = FH_DEFAULT_FORM_NAME.$i;
}
// set the action of the form if none is given
if( !empty($action) ) {
$this->_action = $action;
} else {
$this->_action = $_SERVER['PHP_SELF'];
if(!empty($_SERVER['QUERY_STRING'])) {
$this->_action .= '?'.$_SERVER['QUERY_STRING'];
}
}
// get the JS to put into the <form> tag
if( !empty( $extra ) ) {
$this->_extra = $extra;
}
// initialisation
$this->_fields = array();
$this->_date = array();
$this->_upload = array();
$this->_add = array();
$this->_sql = array();
$this->_dbData = array();
$this->_dontSave = array();
$this->_buffer = array();
$this->_convert = array();
$this->_mail = array();
$this->_tabindexes = array();
$this->_displayErrors = true;
$this->_table = true;
$this->_focus = null;
$this->_pageCounter = 1;
$this->insert = !isset($_GET[FH_EDIT_NAME]);
$this->edit = !$this->insert;
// get the ID if it's an edit form
if($this->edit) {
$this->_id = $_GET[FH_EDIT_NAME];
if( !is_array($this->_id) ) {
$this->_id = array( $this->_id );
}
}
// set our own error handler
if(FH_DISPLAY_ERRORS) {
error_reporting( E_ALL );
$this->_eh = set_error_handler('catchErrors');
}
// set the default mask
$this->setMask( FH_DEFAULT_ROW_MASK );
// check if the form is posted
$this->_posted = ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST[$this->_name.'_submit']));
// make a hidden field so we can identify the form
$this->hiddenField($this->_name.'_submit', '1');
// get the current page
$this->_curPage = isset($_POST[$this->_name.'_page']) ? $_POST[$this->_name.'_page'] : 1;
// check if gd is enabled
ob_start();
phpinfo( 8 );
$module_info = ob_get_contents();
ob_end_clean();
$matches = array();
if (preg_match("/\bgd\s+version\b[^\d\n\r]+?([\d\.]+)/i", $module_info,$matches)) {
$this->_gd = $matches[1];
} else {
$this->_gd = 0;
}
// set the language...
$this->setLanguage();
}
/******************/
/***** FIELDS *****/
/******************/
/**
* FormHandler::textField()
*
* Public: creates a textfield on the form
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param int $size: The size of the field
* @param int $maxlength: The allowed max input of the field
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function textField(
$title,
$name,
$validator = null,
$size = null,
$maxlength = null,
$extra = null)
{
// create the field
$fld =& new TextField($this, $name);
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($size)) $fld->setSize($size);
if(!is_null($maxlength)) $fld->setMaxlength($maxlength);
if(!is_null($extra)) $fld->setExtra($extra);
// add the field to the fields array
$this->_fields[$name] = array($title, &$fld);
}
/**
* FormHandler::passField()
*
* Public: Create a password field
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param int $size: The size of the field
* @param int $maxlength: The allowed max input of the field
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function passField(
$title,
$name,
$validator = null,
$size = null,
$maxlength = null,
$extra = null)
{
// create the field
$fld =& new PassField($this, $name);
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($size)) $fld->setSize($size);
if(!is_null($maxlength)) $fld->setMaxlength($maxlength);
if(!is_null($extra)) $fld->setExtra($extra);
// add the field to the fields array
$this->_fields[$name] = array($title, &$fld);
}
/**
* FormHandler::hiddenField()
*
* Public: create a hidden field
*
* @param string $name: The name of the field
* @param string $value: The value of the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function hiddenField(
$name,
$value = null,
$validator = null,
$extra = null)
{
// create new hidden field
$fld =& new HiddenField($this, $name);
if(!is_null($value) && !$this->isPosted() && !$this->edit)
$fld->setValue($value);
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($extra)) $fld->setExtra($extra);
// add the field to the fields array
$this->_fields[$name] = array('__HIDDEN__', &$fld);
}
/**
* FormHandler::textArea()
*
* Public: Create a textarea on the form
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param int $cols: How many cols (the width of the field)
* @param int $rows: How many rows (the height of the field)
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function textArea(
$title,
$name,
$validator = null,
$cols = null,
$rows = null,
$extra = null)
{
// create new textarea
$fld =& new TextArea($this, $name);
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($cols)) $fld->setCols($cols);
if(!is_null($rows)) $fld->setRows($rows);
if(!is_null($extra)) $fld->setExtra($extra);
// add the field to the fields array
$this->_fields[$name] = array($title, &$fld);
}
/**
* FormHandler::selectField()
*
* Public: Create a selectField on the form
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param array $options: The options used for the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param boolean $useArrayKeyAsValue: If the array key's are the values for the options in the field
* @param int $size: The size of the field (how many options are displayed)
* @param boolean $multiple: Should it be possible to select multiple options ? (Default: false)
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function selectField(
$title,
$name,
$options,
$validator = null,
$useArrayKeyAsValue = null,
$multiple = null,
$size = null,
$extra = null)
{
// options has to be an array
if(!is_array($options)) {
trigger_error(
"You have to give an array as value with the selectfield '$name'",
E_USER_WARNING
);
return;
}
// create new selectfield
$fld =& new SelectField( $this, $name );
$fld->setOptions($options);
if(!is_null($validator)) $fld->setValidator( $validator );
if(!is_null($useArrayKeyAsValue)) $fld->useArrayKeyAsValue( $useArrayKeyAsValue );
if(!is_null($extra)) $fld->setExtra( $extra );
if(!is_null($multiple)) $fld->setMultiple( $multiple );
if(!is_null($size)) {
$fld->setSize( $size );
// if no size is set and multiple is enabled, set the size default to 4
} else if( !is_null($multiple) ) {
$fld->setSize( 4 );
}
// add the field to the fields array
$this->_fields[$name] = array( $title, &$fld );
}
/**
* FormHandler::dbSelectField()
*
* Public: Create a selectField on the form with records loaded from a table
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param string $table: The table where the records are retrieved from
* @param mixed $fields: String or array with the field(s) which are retrieved from the table and put into the select field
* @param string $validator: The validator which should be used to validate the value of the field
* @param int $size: The size of the field (how many options are displayed)
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function dbSelectField(
$title,
$name,
$table,
$fields,
$validator = null,
$size = null,
$extra = null)
{
if( !is_object($this->_db) ) {
trigger_error(
'Error, you have to make use of the database option to make use of the field dbSelectField. '.
'Use selectField() instead!',
E_USER_WARNING
);
return;
}
// create new selectfield
$fld =& new dbSelectField( $this, $name, $this->_db, $table, $fields );
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($size)) $fld->setSize($size);
if(!is_null($extra)) $fld->setExtra($extra);
// add the field to the fields array
$this->_fields[$name] = array($title, &$fld);
}
/**
* FormHandler::checkBox()
*
* Public: Create a checkBox on the form
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param array|string $value: The option(s) used for the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param boolean $useArrayKeyAsValue: If the array key's are the values for the options in the field
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @param string $glue: if more the 1 options are given, glue the fields together with this
* @return void
*/
function checkBox(
$title,
$name,
$value = 'on',
$validator = null,
$useArrayKeyAsValue = null,
$extra = null,
$glue = null)
{
// create a new checkbox
$fld =& new CheckBox($this, $name, $value);
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($useArrayKeyAsValue)) $fld->useArrayKeyAsValue($useArrayKeyAsValue);
if(!is_null($extra)) $fld->setExtra($extra);
if(!is_null($glue)) $fld->setGlue($glue);
// add the field to the fields array
$this->_fields[$name] = array($title, &$fld);
}
/**
* FormHandler::radioButton()
*
* Public: Create a radioButton on the form
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param array $options: The options used for the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param boolean $useArrayKeyAsValue: If the array key's are the values for the options in the field
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @param string $glue: if more the 1 options are given, glue the fields together with this
* @return void
*/
function radioButton(
$title,
$name,
$options,
$validator = null,
$useArrayKeyAsValue = null,
$extra = null,
$glue = null)
{
// value has to be an array
if(!is_array($options)) {
trigger_error(
"You have to give an array as value with the radiobutton '$name'",
E_USER_WARNING
);
return;
}
// create a new checkbox
$fld =& new RadioButton($this, $name, $options);
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($useArrayKeyAsValue)) $fld->useArrayKeyAsValue($useArrayKeyAsValue);
if(!is_null($extra)) $fld->setExtra($extra);
if(!is_null($glue)) $fld->setGlue($glue);
// add the field to the fields array
$this->_fields[$name] = array($title, &$fld);
}
/**
* FormHandler::uploadField()
*
* Public: Create a uploadField on the form
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param array $config: The configuration used for the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @param string $alertOverwrite: Do we have to alert the user when he/she is going to overwrite a file?
* @return void
*/
function uploadField(
$title,
$name,
$config = array(),
$validator = null,
$extra = null,
$alertOverwrite = null)
{
$fld = new UploadField($this, $name, $config);
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($extra)) $fld->setExtra($extra);
if(!is_null($alertOverwrite)) $fld->setAlertOverwrite($alertOverwrite);
// add the uploadfield to the fields array
$this->_fields[$name] = array( $title, &$fld );
// set that this form is using uploadfields
$this->_upload[] = $name;
}
/**
* FormHandler::listField()
*
* Public: Create a listField on the form
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param array $options: The options used for the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param string $onTitle: The title used above the ON section of the field
* @param string $offTitle: The title used above the OFF section of the field
* @param boolean $useArrayKeyAsValue: If the array key's are the values for the options in the field
* @param int $size: The size of the field (how many options are displayed)
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function listField(
$title,
$name,
$options,
$validator = null,
$useArrayKeyAsValue = null,
$onTitle = null,
$offTitle = null,
$size = null,
$extra = null)
{
// options has to be an array
if(!is_array($options)) {
trigger_error(
"You have to give an array as value with the listfield '$name'",
E_USER_WARNING
);
return;
}
// create a listfield
$fld =& new ListField( $this, $name, $options );
if(!is_null($validator)) $fld->setValidator( $validator );
if(!is_null($useArrayKeyAsValue)) $fld->useArrayKeyAsValue( $useArrayKeyAsValue );
if(!empty($size)) $fld->setSize( $size );
if(!is_null($extra)) $fld->setExtra( $extra );
if(!empty($onTitle)) $fld->setOnTitle( $onTitle );
if(!empty($offTitle)) $fld->setOffTitle( $offTitle );
// add the listfield to the fields array
$this->_fields[$name] = array($title, &$fld);
}
/**
* FormHandler::editor()
*
* Public: Create a editor on the form
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param string $path: Path on the server where we have to upload the files
* @param string $toolbar: The toolbar we have to use
* @param string $skin: The skin to use
* @param int $width: The width of the field
* @param int $height: The height of the field
* @param boolean $useArrayKeyAsValue: If the array key's are the values for the options in the field
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function editor(
$title,
$name,
$validator = null,
$path = null,
$toolbar = null,
$skin = null,
$width = null,
$height = null,
$extra = null)
{
// create a new editor
$fld =& new Editor($this, $name);
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($path)) $fld->setServerPath($path);
if(!empty($toolbar)) $fld->setToolbar($toolbar);
if(!empty($skin)) $fld->setSkin($skin);
if(!is_null($width)) $fld->setWidth($width);
if(!is_null($height)) $fld->setHeight($height);
if(!is_null($extra)) $fld->setExtra($extra);
// add the editor to the fields array
$this->_fields[$name] = array($title, &$fld);
}
/**
* FormHandler::dateField()
*
* Public: Create a dateField on the form
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param boolean $required: If the field is required to fill in or can the user leave it blank
* @param string $display: How do we have to display the fields? These can be used: d, m and y.
* @param string $interval: The interval between the current year and the years to start/stop.Default the years are beginning at 90 yeas from the current. It is also possible to have years in the future. This is done like this: "90:10" (10 years in the future).
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function dateField(
$title,
$name,
$validator = null,
$required = null,
$display = null,
$interval = null,
$extra = null)
{
// create a new datefield
$fld =& new DateField($this, $name);
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($required)) $fld->setRequired($required);
if(!empty($display)) $fld->setDisplay($display);
if(!is_null($interval)) $fld->setInterval($interval);
if(!is_null($extra)) $fld->setExtra($extra);
// add the datefield to the fields array
$this->_fields[$name] = array($title, &$fld);
$this->_date[] = $name;
}
/**
* FormHandler::timeField()
*
* Public: Create a timeField on the form
*
* @param string $title: The title of the field
* @param string $name: The name of the field
* @param string $validator: The validator which should be used to validate the value of the field
* @param int $format: 12 or 24. Which should we use?
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function timeField(
$title,
$name,
$validator = null,
$required = null,
$format = null,
$extra = null)
{
// create a new timefield
$fld =& new TimeField($this, $name);
if(!is_null($validator)) $fld->setValidator($validator);
if(!is_null($required)) $fld->setRequired($required);
if(!is_null($format)) $fld->setHourFormat($format);
if(!is_null($extra)) $fld->setExtra($extra);
// add the timefield to the fields array
$this->_fields[$name] = array($title, &$fld);
}
/*****************/
/**** BUTTONS ****/
/*****************/
/**
* FormHandler::button()
*
* Public: Create a button on the form
*
* @param string $caption: The caption of the button
* @param string $name: The name of the button
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function button( $caption, $name = null, $extra = null) {
// get new button name if none is given
if(is_null($name)) {
$name = $this->_getNewButtonName();
}
// create new submitbutton
$btn =& new Button( $this, $name );
$btn->setCaption( $caption );
if(!is_null($extra)) $btn->setExtra($extra);
// add the button to the fields array
$this->_fields[$name] = array('__BUTTON__', &$btn);
}
/**
* FormHandler::submitButton()
*
* Public: Create a submitButton on the form
*
* @param string $caption: The caption of the button
* @param string $name: The name of the button
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function submitButton( $caption = null, $name = null, $extra = null, $disableOnSubmit = null) {
// get new button name if none is given
if(is_null($name)) {
$name = $this->_getNewButtonName();
}
// create new submitbutton
$btn =& new SubmitButton($this, $name);
if(!is_null($caption)) $btn->setCaption($caption);
if(!is_null($extra)) $btn->setExtra($extra);
if(!is_null($disableOnSubmit)) $btn->disableOnSubmit( $disableOnSubmit );
// add the button to the fields array
$this->_fields[$name] = array('__BUTTON__', &$btn);
}
/**
* FormHandler::imageButton()
*
* Public: Create a imageButton on the form
*
* @param string $image: The image URL which should be a button
* @param string $name: The name of the button
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function imageButton( $image, $name = null, $extra = null, $disableOnSubmit = null) {
// get new button name if none is given
if(is_null($name)) {
$name = $this->_getNewButtonName();
}
// create the image button
$btn =& new ImageButton( $this, $name, $image );
if(!is_null($extra)) $btn->setExtra( $extra );
if(!is_null($disableOnSubmit)) $btn->disableOnSubmit( $disableOnSubmit );
// add the button on the form
$this->_fields[$name] = array('__BUTTON__', &$btn);
}
/**
* FormHandler::resetButton()
*
* Public: Create a resetButton on the form
*
* @param string $caption: The caption of the button
* @param string $name: The name of the button
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function resetButton($caption = null, $name = null, $extra = null) {
// get new button name if none given
if(is_null($name)) {
$name = $this->_getNewButtonName();
}
// create new resetbutton
$btn =& new ResetButton($this, $name);
if(!is_null($caption)) $btn->setCaption($caption);
if(!is_null($extra)) $btn->setExtra($extra);
// add the button to the fields array
$this->_fields[$name] = array('__BUTTON__', &$btn);
}
/**
* FormHandler::cancelButton()
*
* Public: Create a cancelButton on the form
*
* @param string $caption: The caption of the button
* @param string $url: The URL to go to when the button is clicked
* @param string $name: The name of the button
* @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
* @return void
*/
function cancelButton($caption = null, $url = 'history.back(-1)', $name = null, $extra = null) {
// get new button name if none given
if(is_null($name)) {
$name = $this->_getNewButtonName();
}
// where to go when the button is clicked...
if(ereg('history', $url)) {
$extra .= ' onclick="'.$url.'"';
} else {
$extra .= ' onclick="document.location.href=\''.$url.'\'"';
}
// if no caption is given, get our own caption
if(is_null($caption)) {
$caption = $this->_text( 28 );
}
// create new button
$btn =& new Button($this, $name);
$btn->setCaption($caption);
if(!is_null($extra)) $btn->setExtra($extra);
// add the button to the fields array
$this->_fields[$name] = array('__BUTTON__', &$btn);
}
/*******************/
/****** STYLE ******/
/*******************/
/**
* FormHandler::addHTML()
*
* Public: Add some HTML to the form
*
* @param string $html: The HTML we have to add to the form
* @return void
*/
function addHTML( $html ) {
static $iCounter = 1;
$this->_fields['html'.$iCounter++] = array('__HTML__', $html);
}
/**
* FormHandler::addLine()
*
* Public: Add a new row to the form.
*
* @param string $data: Possible data to set into the row (line)
* @return void
*/
function addLine( $text = null ) {
static $iCounter = 1;
$this->_fields['line'.$iCounter++] = array('__LINE__',
sprintf( FH_LINE_MASK, $text )
);
}
/**
* FormHandler::borderStart()
*
* Public: Begin a new fieldset
*
* @param string $caption: The caption of the fieldset
* @param string $name: The name of the fieldset
* @return void
*/
function borderStart( $caption = null, $name = null ) {
static $i = 1;
if( is_null( $name ) ) {
$name = 'fieldset'.$i++;
}
$this->_fields[] = array('__FIELDSET__', array($name, $caption));
}
/**
* FormHandler::borderStop()
*
* Public: Stops a fieldset
*
* @return void
*/
function borderStop() {
$this->_fields[] = array('__FIELDSET-END__', true);
}
/**
* FormHandler::setMask()
*
* Public: Stops a fieldset
*
* @param string $mask: The mask we have to use
* @param int|bool $repeat: If we have to repeat the mask. When a integer is given, it will be countdown
* @return void
*/
function setMask( $mask = null, $repeat = true, $setTable = null ) {
if(is_null($mask)) {
$mask = FH_DEFAULT_ROW_MASK;
} else if(file_exists($mask)) {
if(is_readable($mask)) {
if( function_exists('file_get_contents')) {
$mask = file_get_contents( $mask );
} else {
$handle = fopen($mask, 'rb');
$mask = '';
while (!feof($handle)) {
$mask .= fread($handle, 4096);
}
fclose($handle);
}
} else {
trigger_error('Could not read from template '.$mask, E_USER_WARNING );
}
}
// do we have to set a table arround the fields?
if( !is_null( $setTable ) ) {
$this->_table = $setTable;
}
$this->_fields[] = array( '__MASK__', array( $mask, $repeat ) );
}
/****************************/
/**** DATA MANIPULATION *****/
/****************************/
/**
* FormHandler::value()
*
* Public: get the value of the requested field
*
* @param string $field: The field which value we have to return
* @return void
*/
function value( $field ) {
if(!_global) global $_POST;
// is it a field?
if( isset( $this->_fields[$field] ) ) {
return $this->_fields[$field][1]->getValue();
// is it a field of the database ?
} else if( array_key_exists($field, $this->_dbData) ) {
return $this->_dbData[$field];
// is it a added value ?
} else if( isset($this->_add[$field]) ) {
return $this->_add[$field];
// BELOW is beta!!
//} else if( isset( $_POST[$field] ) ) {
// return $_POST[$field];
} else {
//trigger_error("Try to get the value of an unknown field '$field'!");
return null;
}
}
/**
* FormHandler::setValue()
*
* Public: set the value of the spicified field
*
* @param string $field: The field which value we have to set
* @param string $value: The value we have to set
* @param boolean $overwriteCurrentValue: Do we have to overwrite the current value of the field (posted or db-loaded values)
* @return void
*/
function setValue($sField, $sValue, $bOverwriteCurrentValue = false) {
// save the data (we realy set the value in the method flush() )
$this->_buffer[$sField] = array($bOverwriteCurrentValue, $sValue);
}
/**
* FormHandler::addValue()
*
* Public: add a value to the data array which is going
* to be saved/used in the oncorrect & onsaved functions
*
* @param string $field: The field which value we have to set
* @param string $value: The value we have to set
* @param boolean $sqlFunction: Is the value an SQL function ?
* @return void
*/
function addValue($field, $value, $sqlFunction = false) {
$this->_add[$field] = $value;
// add to the sql list if the value is a sql function
if($sqlFunction) {
$this->_sql[] = $field;
}
}
/***********************/
/** DATABASE OPTIONS ***/
/***********************/
/**
* FormHandler::dbInfo()
*
* Public: set the DBInfo. You can give the primary key's after the table name, like this:
*
* dbInfo( 'DB', table', 'mysql', 'prKey1');
*
* or
*
* dbInfo( 'DB', table', 'mysql', 'prKey1', 'prKey2', 'etc...');
*
* When you dont specify a primary key, FormHandler will try to
* retrieve it automaticly. When this failes, it will trigger an error.
*
* @param string $db: the db which we are using
* @param string $table: the table where we have to save the data
* @param string $type: the type of db which is used
* @return
*/
function dbInfo( $db, $table, $type = null ) {
// if no db-type is given, set the default
if(is_null($type)) {
$type = FH_DEFAULT_DB_TYPE;
}
// get prKey(s) if given
$numArgs = func_num_args();
if($numArgs > 3) {
$keys = array();
for($i = 3; $i < $numArgs; $i ++ ) {
$keys[] = func_get_arg($i);
}
} else {
$keys = null;
}
$type = strtolower( $type );
if(class_exists( 'fh_'.$type)) {
// create a new database object
eval('$this->_db = new fh_'.$type.'( $db, $table, $keys );');
} else {
trigger_error(
"Error, could not find database handler for database type '".$type."'",
E_USER_WARNING
);
return;
}
// try to fetch the database data allready
if( $this->edit && $this->_db->isConnected() ) {
$this->_loadDbData();
}
}
/**
* FormHandler::dbConnect()
*
* Public: Connect to the database (only needed when there is no connection yet!)
*
* @param string $username: the username used to login
* @param string $password: the password used to login
* @return void
*/
function dbConnect($host = null, $username = '', $password = '') {
if(is_object($this->_db)) {
if(is_null($host)) {
$host = FH_DEFAULT_DB_HOST;
}
if(!$this->_db->connect( $host, $username, $password )) {
trigger_error( 'Error, connecting failed: '.$this->_db->getError(), E_USER_WARNING );
return;
}
} else {
trigger_error('No database object available! Make sure you call DBInfo() first!', E_USER_WARNING);
$this->_db = null;
return;
}
// load the database values only on a edit form...
if($this->edit && ( !is_array($this->_dbData) || sizeof($this->_dbData) == 0)) {
$this->_loadDbData();
}
}
/*******************/
/***** GENERAL *****/
/*******************/
/**
* FormHandler::getTitle()
*
* Public: return the title of the given field name
*
* @param string $sField: The fieldname where to retrieve the title from
* @return string
*/
function getTitle( $sField ) {
static $aTitleFields = array(
'textfield', 'listfield', 'selectfield',
'radiobutton', 'checkbox', 'editor',
'passfield', 'textarea', 'timefield',
'datefield', 'uploadfield'
);
if(isset($this->_fields[$sField]) && is_object( $this->_fields[$sField][1] ))
{
$sClass = strtolower( get_class( $this->_fields[$sField][1] ) );
if( in_array($sClass, $aTitleFields) ) {
return $this->_fields[$sField][0];
} else {
trigger_error(
'Error, cannot retrieve title of this kind of field: '.$sClass,
E_USER_WARNING
);
}
} else {
trigger_error(
'Could not find field "'.$sField.'"',
E_USER_WARNING
);
}
return null;
}
/**
* FormHandler::fieldExists()
*
* Public: check if the field exists in the form
*
* @param string $sField: The field to check if it exists in the form or not
* @return boolean
*/
function fieldExists( $sField ) {
return array_key_exists( $sField, $this->_fields);
}
/**
* FormHandler::getFormName()
*
* Public: return the name of the form
*
* @return string: the name of the form
*/
function getFormName() {
return $this->_name;
}
/**
* FormHandler::mailForm()
*
* Public: send the values of the form to the mail adress
*
* @param string $to: The e-mail adres to send the data to
* @param string $subject: The subject of the mail
* @param string $headers: The headers which should be used by sending the mail
* @return void
*/
function mailForm( $to, $subject = null, $headers = null ) {
if(is_null($subject)) {
$subject = "New form mailed to you by FormHandler";
}
if(is_null($headers)) {
$headers = "From: FormHandler <info@formhandler.nl>";
}
// add the mail items
$this->_mail[] = array( $to, $subject, $headers );
}
/**
* FormHandler::newPage()
*
* Public: Put the following fields on a seperate page
*
* @return void
*/
function newPage() {
$this->_fields[] = array( '__PAGE__', $this->_pageCounter++);
}
/**
* FormHandler::setTabIndex()
*
* Public: set the tab index for the fields
*
* @param mixed $mTabs: array of comma seperated string with the field names.
* When an array is given the array index will set as tabindex
* @return void
*/
function setTabIndex( $mTabs ) {
if(is_string( $mTabs ) ) {
$aTabs = explode(',', $mTabs);
array_unshift($aTabs, '');
} else if( is_array( $mTabs )) {
// is set element 0, then move all elements
// (0 is not a valid tabindex, it starts with 1)
if( isset( $mTabs[0])) {
ksort( $mTabs );
$aTabs = array();
foreach( $mTabs as $key => $value ) {
while( array_key_exists( $key, $aTabs) || $key <= 0) $key++;
$aTabs[$key] = $value;
}
} else {
$aTabs = $mTabs;
}
}
// array with tabs set ?
if( isset( $aTabs ) ) {
foreach($aTabs as $key => $value ) {
if(!empty($value)) {
$aTabs[$key] = trim($value);
} else {
unset($aTabs);
}
}
$this->_tabindexes = $this->_tabindexes + $aTabs ;
}
}
/**
* FormHandler::setLanguage()
*
* Public: Set the language we should use for error messages etc.
* If no language is given, try to get the language defined by the visitors browser.
*
* @param string $language: The language we should use
* @return void
*/
function setLanguage( $sLanguage = null ) {
if(!_global) global $_SERVER;
if(is_null($sLanguage)) {
// auto detect language ?
$bSet = false;
if( FH_AUTO_DETECT_LANGUAGE ) {
// get all accepted languages by the browser
$aLang = array();
if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
foreach(explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $sValue) {
if(strpos($sValue, ';') !== false) {
list($sValue, ) = split(';', $sValue);
}
if(strpos($sValue, '-') !== false) {
list($sValue, ) = split('-', $sValue);
}
$aLang[] = $sValue;
}
}
// set the language which we have too
while (list (, $l) = each ($aLang)) {
if(file_exists(FH_INCLUDE_DIR.'language/'.strtolower($l).'.php')) {
$this->setLanguage( $l );
$bSet = true;
break;
}
}
}
// no language is set yet.. set the default language
if(!$bSet) {
$this->setLanguage( FH_DEFAULT_LANGUAGE );
}
} else {
$this->_lang = strtolower($sLanguage);
if(file_exists(FH_INCLUDE_DIR.'language/'.$this->_lang.'.php')) {
include(FH_INCLUDE_DIR.'language/'.$this->_lang.'.php');
// load the array from the text file
$this->_text =& $fh_lang;
} else {
trigger_error('Unknown language: '.$this->_lang.'. Could not find file '.FH_INCLUDE_DIR.'language/'.$this->_lang.'.php!', E_USER_ERROR);
}
}
}
/**
* FormHandler::catchErrors()
*
* Public: get the errors occoured in the form
*
* @param boolean $display: If we still have to display the errors in the form (default this is disabled)
* @return array of errorsor an empty array if none occoured
*/
function catchErrors( $display = false ) {
// only return the errors when the form is posted!
if($this->isPosted()) {
$this->_displayErrors = $display;
$errors = array();
reset( $this->_fields );
while(list($field, $obj) = each($this->_fields)) {
if(method_exists($obj[1], 'getError') && method_exists($obj[1], 'isValid')) {
$obj[1]->isValid();
$err = strip_tags($obj[1]->getError());
if(strlen($err) > 0) {
$errors[$field] = $err;
}
}
}
return $errors;
}
return array();
}
/**
* FormHandler::resizeImage()
*
* Public: resize the image uploaded in the given field
*
* @param string $field: The field where the image is uploaded
* @param string $saveAs: How the image has to be saved (if not given, the original wil be overwritten)
* @param int $maxWidth: The maximum width of the resized image
* @param int $maxHeight: the maximum height of the resized image
* @param int $quality: the quality of the resized image
* @return void
*/
function resizeImage( $field, $saveAs = null, $maxWidth = null, $maxHeight = null, $quality = null ) {
// is gd enabled ?
if( ! $this->_gd ) {
trigger_error( 'Error! To use the function resizeImage you have to enable GD Libary!', E_USER_WARNING);
return;
}
if(is_null($maxWidth)) $maxWidth = FH_DEFAULT_RESIZE_WIDTH;
if(is_null($maxHeight)) $maxHeight = $maxWidth;
$this->_convert[$field]['resize'][] = array( $saveAs, $maxWidth, $maxHeight, $quality );
}
/**
* FormHandler::mergeImage()
*
* Public: merge a image uploaded in the given field with another image
*
* @param string $field: The field where the image is uploaded
* @param string $merge: The image which we should merge
* @param int $align: The align of the merge image (eg: left, center, right)
* @param int $valign: The vertical align of the merge image( eg: top, middle, bottom)
* @return void
*/
function mergeImage( $field, $merge, $align = 'center', $valign = 'bottom', $transparantColor = null ) {
// is gd enabled ?
if( ! $this->_gd ) {
trigger_error( 'Error! To use the function mergeImage you have to enable GD Libary!', E_USER_WARNING);
return;
}
$this->_convert[$field]['merge'][] = array( $merge, $align, $valign, $transparantColor );
}
/**
* FormHandler::setFocus()
*
* Public: set the focus to a sepcific field
*
* @param string $field: The field which should get the focus
* @return boolean: true if the focus could be set, false if not
*/
function setFocus($field) {
if(!isset($this->_fields[$field])) {
trigger_error('Could net set focus to unknown field '.$field);
return;
}
// some fields have gotten other names... change it.
switch ( get_class($this->_fields[$field][1])) {
case 'datefield':
$field = $field.'_day';
break;
case 'listfield':
$field = $field.'_ListOn';
break;
case 'timefield':
$field = $field.'_hour';
break;
case 'editor':
case 'radiobutton':
case 'checkbox':
case 'hiddenfield':
// buttons cant have the focus
case 'submitbutton':
case 'resetbutton':
case 'imagebutton':
case 'button':
$field = null;
break;
}
$this->_focus = $field;
return !is_null($field);
}
/**
* FormHandler::checkPassword()
*
* Public: Preform a password check on 2 password fields:
* - both values are the same
* - the values are longer then a minimum length (configured in the config file)
* - on an add-form, the fields are required
* - on an edit-form, the fields can be left empty, and the old password will stay (no changes will take place)
*
* @param string $field1: The first password field we should check
* @param string $field2: The second password field we should check
* @return void
*/
function checkPassword($field1, $field2, $setEditMsg = true) {
if(!isset($this->_fields[$field1]) || !isset($this->_fields[$field2]) ||
strtolower( get_class( $this->_fields[$field1][1] ) ) != 'passfield' ||
strtolower( get_class( $this->_fields[$field2][1] ) ) != 'passfield')
{
trigger_error('Error: unknown field used in checkPassword!');
return;
}
// add some text to nitify the user that he only has to enter his
// password when he wants to change it
if($this->edit && $setEditMsg) {
$this->_fields[$field1][1]->setPre(
$this->_text( 25 )
);
}
// is the form posted
if($this->isPosted()) {
// let passfield 1 check if it matches passfield 2
$this->_fields[$field1][1]->checkPassword( $this->_fields[$field2][1] );
}
}
/**
* FormHandler::onCorrect()
*
* Public: Set the function which has to be called when the form is correct
*
* @param string $callback: The name of the function
* @return void
*/
function onCorrect($callback) {
if(!is_array($callback)) {
if(function_exists($callback)) {
$this->_onCorrect = $callback;
} else {
trigger_error("Error, the onCorrect function '".$callback."' does not exists!", E_USER_ERROR);
}
// check if the method exists
} else {
if(method_exists($callback[0], $callback[1])) {
$this->_onCorrect =& $callback;
} else {
trigger_error(
"Error, the onCorrect method '".$callback[1]."' does not exists ".
"in object '".get_class($callback[0])."'!",
E_USER_ERROR);
}
}
}
/**
* FormHandler::onSaved()
*
* Public: Set the function which has to be called when the form data is saved in the database
*
* @param string $callback: The name of the function
* @return void
*/
function onSaved($callback) {
if(!is_array($callback)) {
if(function_exists($callback)) {
$this->_onSaved = $callback;
} else {
trigger_error("Error, the onSaved function '".$callback."' does not exists!", E_USER_ERROR);
}
// check if the method exists
} else {
if(method_exists($callback[0], $callback[1])) {
$this->_onSaved =& $callback;
} else {
trigger_error(
"Error, the onSaved method '".$callback[1]."' does not exists ".
"in object '".get_class($callback[0])."'!",
E_USER_ERROR);
}
}
}
/**
* FormHandler::isPosted()
*
* Public: If the form is posted
*
* @return boolean: if the form is posted or not
*/
function isPosted() {
return $this->_posted;
}
/**
* FormHandler::isCorrect()
*
* Public: return if the form is filled correctly (for the fields which are set!)
*
* @return boolean: the form values valid or not
*/
function isCorrect() {
// walk each field to check if they are valid
$result = true;
reset( $this->_fields );
while( list( $id, $data ) = each($this->_fields) ) {
// check if the fields are valid
if(method_exists($this->_fields[$id][1], 'isvalid') && !$this->_fields[$id][1]->isValid()) {
if(is_null($this->_focus)) {
$this->setFocus($id);
}
$result = false;
// if multiple pages are used, only make sure that
// all pages untill the current page are correct
} else if($data[0] == '__PAGE__') {
if( $this->_curPage == $data[1]) {
break;
}
}
}
// only check for unique fields if the rest of the field is correct and
// the database option is used...
if( $result && isset($this->_db) && is_object($this->_db)) {
$db =& $this->_db;
$unique = $db->fetchUniqueFields();
// any unique fields found ?
if(sizeof( $unique ) > 0) {
// walk all unique fields
foreach( $unique as $key => $field) {
// does the unique field exists
if( $this->fieldExists($field) ) {
// get the form-value of the field
$value = $db->escapeString( $this->_fields[$field][1]->getValue() );
// quotes around the value ?
if(preg_match("/^-?([0-9]*\.?[0-9]+)$/", $value)) {
if( $db->_quoteNumbers ) {
$value = "'".$value."'";
}
} else {
$value = "'".$value."'";
}
// check if the entry is double
$db->Query(
'SELECT COUNT('.$field.') AS num FROM '.$db->getTable().
' WHERE '.$field." = ".$value
);
// if so, set the error message and return false;
$row = $db->getRecord();
if($row['num'] > 0) {
// set the error message
$this->_fields[$field][1]->_sError =
sprintf(
$this->_text(35),
$this->_fields[$field][1]->getValue()
)
;
// return false (the form is not correct)
$result = false;
}
}
}
}
}
return $result;
}
/**
* FormHandler::flush()
*
* Public: prints or returns the form
*
* @return string: the form or null when the form should be printed
*/
function flush( $return = false ) {
// when the form is not posted or the form is not valid
if( !$this->_posted || !$this->isCorrect() ) {
// set the values set by the user
foreach($this->_buffer as $sField => $aInf) {
if(! isset( $this->_fields[$sField] ) ) {
trigger_error('Value set of unknown field '.$sField, E_USER_WARNING );
} else {
list( $bOverwrite, $sValue ) = $aInf;
// if the field does not exists in the database
if($bOverwrite || (!isset($this->_dbData[$sField]) && !$this->isPosted() )) {
$this->_fields[$sField][1]->setValue( $sValue );
}
}
}
// get the form
$form = $this->_getForm();
// when the form is not totaly completed yet (multiple pages)
} else if( $this->_curPage < $this->_pageCounter ) {
// upload and convert uploads
$this->_handleUploads();
// get the next form
$form = $this->_getForm( $this->_curPage + 1 );
// when the form is valid
} else {
// upload and convert uploads
$this->_handleUploads();
// generate the data array
$data = array();
foreach($this->_fields as $name => $fld) {
if(method_exists($fld[1], 'getValue') && $name != $this->_name.'_submit') {
$data[$name] = $fld[1]->getValue();
}
}
// add the user added data to the array
$data = array_merge( $data, $this->_add );
// do whe have to mail the form data?
if( sizeof($this->_mail) ) {
$mailer = new fhMailer( $this->_mail );
// add the attachements
foreach( $this->_upload as $field ) {
if( $this->_fields[$field][1]->isUploaded() ) {
$mailer->attachFile(
$this->_fields[$field][1]->getSavePath().
$this->_fields[$field][1]->getValue()
);
}
}
// mail
$mailer->sendMail( $data );
}
// call the users oncorrect function
if(!empty($this->_onCorrect)) {
if(is_array($this->_onCorrect)) {
$hideForm = call_user_method($this->_onCorrect[1], $this->_onCorrect[0], $data);
} else {
$hideForm = call_user_func($this->_onCorrect, $data);
}
}
// add the user added data again to the array (could have been changed!)
$data = array_merge( $data, $this->_add );
// if the db option is used
if( !is_null($this->_db)) {
// get the data which should be saved
foreach( $data as $field => $value ) {
// do we have to save the field ?
if(!in_array($field, $this->_dontSave)) {// || $value != '') {
// Is the value '' and is it a date or timefield? Then save NULL
// This is needed when the fields are NOT required
if($value == '' && isset($this->_fields[$field])) {
$class = strtolower( get_class( $this->_fields[$field][1] ) );
if($class == 'datefield' || $class == 'timefield') {
$value = 'NULL';
$this->_sql[] = $field;
}
}
$save[$field] = $value;
}
}
// change the date's to the right format
foreach( $this->_date as $field ) {
if($save[$field] != 'NULL' && preg_match('/[0-9]{1,2}-[0-9]{1,2}-[0-9]{4}/', $save[$field])) {
$save[$field] = $this->_db->getDbDate( $save[$field] );
$this->_sql[] = $field;
}
}
// save the data
$id = $this->_db->saveData( $save, $this->_sql, $this->edit, $this->_id );
// get the id
if(is_array($id) && sizeof($id) == 1) {
$id = $id[0];
}
// call the onsaved function
if(!is_null($this->_onSaved)) {
if(is_array($this->_onSaved)) {
$hideForm = call_user_method($this->_onSaved[1], $this->_onSaved[0], $data);
} else {
$hideForm = call_user_func($this->_onSaved, $id, $data);
}
}
}
// display the form again if wanted..
if(isset($hideForm) && $hideForm === false) {
$form = $this->_getForm();
} else if(is_string($hideForm)) {
$form = $hideForm;
} else {
$form = '';
}
}
// return or print the form
if($return) {
return $form;
} else {
echo $form;
return null;
}
}
/*******************/
/**** PRIVATE!! ****/
/*******************/
/**
* FormHandler::_getNewButtonName()
*
* Private static: when no button name is given, get a unique button name
*
* @return string: the new button name
*/
function _getNewButtonName() {
static $counter = 1;
return 'button'.$counter++;
}
/**
* FormHandler::_loadMask()
*
* Private: load the fields into the mask
*
* @param array $data: contains the title and the field object
* @param string $mask: the mask which should be used
* @param string $name: the name of the field
* @return string: the filled mask, or null when the mask isn't filled completly
*/
function _loadMask( $data, $mask, $name ) {
static $result = null;
$title =& $data[0];
$obj =& $data[1];
if($title == '__BUTTON__') {
$title = '';
}
// search and replace values
$search = array(
'/%field%/ie',
'/%error%/ie',
'/%title%/i',
'/%seperator%/ie'
);
$replace = array(
'str_replace("%", "____FH-percent____", '.
'(method_exists($obj, "getField")) ? $obj->getField() : '.
'((method_exists($obj, "getButton")) ? $obj->getButton() : ""))',
'($this->_displayErrors && method_exists($obj, "getError"))?$obj->getError():""',
$title,
'!strlen($title)?"":":"'
);
// for catching the errors
if(!is_null($name) && method_exists($obj, 'getError')) {
$this->errors[$name] = $obj->getError();
}
// return a possible half filled mask if requested
if( is_null($obj) && is_null($mask))
return preg_replace ( $search, array_fill(0, 4, ''), $result );
// is the last mask finished? (if not, load it)
if( !is_null($result) ) {
$mask = $result;
}
// replace the values
$mask = preg_replace ( $search, $replace, $mask, 1 );
// is the mask completly filled?
$matches = array();
preg_match_all('/(%field%|%error%|%title%|%seperator%)/i', $mask, $matches);
if( isset($matches[1]) && count($matches[1]) > 0) {
$result = $mask;
return null;
} else {
$result = null;
return str_replace('____FH-percent____', '%', $mask);
}
}
/**
* FormHandler::_text()
*
* Private: return the given text in the correct language
*
* @param int $index: the index of the text in the textfile
* @return string: the text in the correct language
*/
function _text( $iIndex ) {
// is a language set?
if(!is_array($this->_text)) {
trigger_error('No language file set!', E_USER_ERROR);
return false;
} else if(!array_key_exists($iIndex, $this->_text)) {
trigger_error('Unknown index '.$iIndex.' to get language string!', E_USER_NOTICE);
return '';
}
return $this->_text[$iIndex];
}
/**
* FormHandler::_registerFileName()
*
* Private: Register the filenames which upload fields are using for there
* uploaded file so that other upload fields cannot use these.
*
* @param string $sFilename: the filename to register
* @param string $sField: the field who is registering the file
* @return bool: false if the filename is allready registered, true otherwise
*/
function _registerFileName($sFilename, $sField) {
static $aFilenames = array();
if(isset($aFilenames[$sFilename]) && $aFilenames[$sFilename] != $sField) {
return false;
}
$aFilenames[$sFilename] = $sField;
return true;
}
/**
* FormHandler::_loadDbData()
*
* Public: load the data when it's a edit form
*
* @return void
*/
function _loadDbData() {
$this->_dbData = $this->_db->loadData( $this->_id );
// if data retrieving failed...
if(!is_array($this->_dbData)) {
$this->_dbData = array();
// error, data not found!
// insert the id if its a edit form and the record is not foud
if(FH_AUTO_INSERT) {
$keys = $this->_db->getPrKey();
$size1 = sizeof( $keys );
$size2 = sizeof($this->_id);
for($i = 0; $i < ( $size1 > $size2 ? $size2 : $size1 ) ; $i++ ) {
$this->addValue( $keys[$i], $this->_id[$i] );
}
$this->insert = true;
$this->edit = false;
} else {
trigger_error('Try to edit a none existing record!', E_USER_ERROR);
}
}
}
/**
* FormHandler::_handleUploads()
*
* Private: method to handle the uploads and image convertions
*
* @return void
*/
function _handleUploads() {
// upload the uploaded files
foreach($this->_upload as $name) {
$this->_fields[$name][1]->doUpload();
}
// convert some images if needed
reset( $this->_convert );
while( list( $field, $convertions ) = each( $this->_convert ) ) {
foreach( $convertions as $action => $data ) {
// is the field a uploadfield?
if(in_array($field, $this->_upload)) {
// is there a file uploaded ?
if($this->_fields[$field][1]->isUploaded()) {
$image =
$this->_fields[$field][1]->getSavePath().
$this->_fields[$field][1]->getValue();
// does the file exists?
if(!file_exists($image)) {
trigger_error("Error! Could not find uploaded file $image!", E_USER_WARNING);
unset($image);
}
} else {
// image is not uploaded, continue with next field/image
continue;
}
// it's not a uploadfield... is it an image ?
} else if(file_exists($field)) {
$image = $field;
// unknown field or file!
} else {
trigger_error('Could not find field or file to convert: '.$image , E_USER_WARNING);
}
// do the convert actions with the image (when the uploaded file is a jpg or png!)
if( isset($image) && in_array( strtolower(substr( $image, -4) ), array('.jpg', '.png', 'jpeg')) ) {
$img =& new ImageConverter( $image );
// stop when a error occoured
if( $img->getError() ) {
trigger_error( $img->getError(), E_USER_WARNING );
unset( $img );
continue;
}
foreach($data as $info) {
switch($action) {
case 'merge':
list( $stamp, $align, $valign, $transparant ) = $info;
$img->doMerge( $stamp, $align, $valign, $transparant );
break;
case 'resize':
list( $destination, $maxX, $maxY, $quality ) = $info;
if( empty( $destination ) ) {
$destination = $image;
}
$img->setQuality( $quality );
$img->doResize( $destination, $maxX, $maxY );
break;
}
}
unset( $img );
}
}
}
}
/**
* FormHandler::_getForm()
*
* Private: get the form
*
* @return string: the generated form
*/
function _getForm( $iDisplayPage = null) {
if( is_null( $iDisplayPage ) ) {
$iDisplayPage = $this->_curPage;
}
// set the tab indexes for the fields...
ksort( $this->_tabindexes );
reset( $this->_tabindexes );
while( list( $index, $field ) = each( $this->_tabindexes )) {
if( $this->fieldExists( $field ) ) {
$this->_fields[$field][1]->setTabIndex( $index );
} else {
trigger_error(
'Error, try to set the tabindex of an unknown field "'.$field.'" !'
);
}
}
// set the focus to the first (tab index) field if no focus is set yet
if( is_null($this->_focus)) {
// are there tab indexes set ?
if( sizeof( $this->_tabindexes) > 0 ) {
// set the focus to the element with the lowest positive tab index
reset( $this->_tabindexes );
while( list( $key, $field ) = each( $this->_tabindexes )) {
if( $key >= 0 && $this->setFocus( $field )) {
break;
}
}
}
// no focus set yet. Set the focus to the first field
if( is_null($this->_focus)) {
reset( $this->_fields );
while( list( $name, $data ) = each( $this->_fields ) ) {
// is it a object (only fields + buttons are objects)
if( is_object( $this->_fields[$name][1]) && $this->setFocus( $name )) {
break;
}
}
}
}
// used vars
$hidden = '';
$form = '';
$buffer = array();
$repeat = true;
$page = 1;
// walk trought the fields array
reset( $this->_fields );
while( list($id, $field) = each($this->_fields) ) {
switch( $field[0] ) {
// multiple pages in this form
case '__PAGE__':
if( $field[1] == $iDisplayPage) {
break 2;
}
$page++;
break;
// hidden field
case '__HIDDEN__':
$hidden .= $field[1]->getField()."\n";
break;
// new mask to set
case '__MASK__':
list($this->_mask, $repeat) = $field[1];
break;
// insert html or a line
case '__HTML__':
case '__LINE__':
$form .= $field[1];
break;
// begin new fieldset
case '__FIELDSET__':
array_push( $buffer, array($form, $field[1][0], $field[1][1]) );
$form = '';
break;
// end new fieldset
case '__FIELDSET-END__':
if(sizeof($buffer) > 0) {
$d = array_pop($buffer);
$form = $d[0].
str_replace(
array('%name%', '%caption%', '%content%' ),
array($d[1], $d[2], $form ),
FH_FIELDSET_MASK
);
} else {
trigger_error('Fieldset is closed whyle there is not an open fieldset!');
}
break;
// default action: field or button
default:
if($page != $iDisplayPage ) {
// put the data of the field in a hidden field
if($field[0] != '__BUTTON__') {
$h =& new HiddenField( $this, $id );
$h->setValue( $field[1]->getValue() );
$hidden .= $h->getField() ."\n";
unset( $h );
}
} else {
// field is on the current page.. just display it
$html = $this->_loadMask( $field, $this->_mask, $id );
if($html) {
$form .= $html;
if(!$repeat) {
$this->_mask = FH_DEFAULT_ROW_MASK;
} else if(is_numeric($repeat)) {
$repeat--;
}
}
}
break;
}
}
// give the form a page number...
if($this->_pageCounter > 1) {
$h = new HiddenField( $this, $this->_name .'_page' );
$h->setValue( $iDisplayPage );
$hidden .= $h->getField() ."\n";
unset( $h );
}
// get a possible half filled mask
$form .= $this->_loadMask( null, null, null );
// get errors
$errors =& catchErrors();
$errmsg = '';
foreach($errors as $error) {
switch ($error['no']) {
case E_USER_WARNING: $type = 'Warning'; break;
case E_USER_NOTICE: $type = 'Notice'; break;
case E_USER_ERROR: $type = 'Error'; break;
default: $type = 'Warning'; break;
}
$errmsg .= "<b>".$type.":</b> ".basename($error['file'])." at ".$error['line']." ". $error['text'] ."<br />\n";
}
$result =
$errmsg .
base64_decode(
'PCEtLSANCiAgVGhpcyBmb3JtIGlzIGF1dG9tYXRpY2'.
'x5IGJlaW5nIGdlbmVyYXRlZCBieSBGb3JtSGFuZGxl'.
'ciB2My4NCiAgU2VlIGZvciBtb3JlIGluZm86IGh0dH'.
'A6Ly93d3cuZm9ybWhhbmRsZXIubmV0DQogIFRoaXMg'.
'Y3JlZGl0IE1VU1Qgc3RheSBpbnRhY3QgZm9yIHVzZQ'.
'0KLS0+'
).
"\n<form name='".$this->_name."' method='post' action='".$this->_action."'".
(sizeof($this->_upload) ? ' enctype="multipart/form-data"':'' ).
($this->_extra ? " ".$this->_extra : "" ).">\n".
$hidden.
($this->_table ? "<table border='0' cellspacing='0' cellpadding='3'>\n" : '' ).
$form.
($this->_table ? "\n</table>\n" : '').
(FH_EXPOSE ?
base64_decode(
'PHNtYWxsPjxmb250IGNvbG9yPSdCNUI1QjUnIGZh'.
'Y2U9J3RhaG9tYScgc3R5bGU9J2ZvbnQtZmFtaWx5'.
'OnRhaG9tYTtmb250LXNpemU6MTBweDtjb2xvcjpC'.
'NUI1QjU7Zm9udC13ZWlnaHQ6bm9ybWFsOyc+VGhp'.
'cyBmb3JtIGlzIGdlbmVyYXRlZCBieSA8L2ZvbnQ+'.
'PC9zbWFsbD48YSBocmVmPSdodHRwOi8vd3d3LmZv'.
'cm1oYW5kbGVyLm5ldCcgdGFyZ2V0PSdfYmxhbmsn'.
'PjxzbWFsbD48Zm9udCBjb2xvcj0nQjVCNUI1JyBm'.
'YWNlPSd0YWhvbWEnIHN0eWxlPSdmb250LWZhbWls'.
'eTpUYWhvbWE7Zm9udC1zaXplOjEwcHg7Y29sb3I6'.
'QjVCNUI1O2ZvbnQtd2VpZ2h0Om5vcm1hbDsnPjxi'.
'PkZvcm1IYW5kbGVyPC9iPjwvZm9udD48L3NtYWxs'.
'PjwvYT4='
):'').
"</form>\n".
base64_decode(
'PCEtLSANCiAgVGhpcyBmb3JtIGlzIGF1dG9tYXRpY2'.
'x5IGJlaW5nIGdlbmVyYXRlZCBieSBGb3JtSGFuZGxl'.
'ciB2My4NCiAgU2VlIGZvciBtb3JlIGluZm86IGh0dH'.
'A6Ly93d3cuRm9ybUhhbmRsZXIubmV0DQotLT4='
) .
($this->_focus != null ?
"\n<script language='javascript' type='text/javascript'>\n".
"<!-- // set the focus on a specific field \n".
"var sType = typeof( document.forms['".$this->_name."'].elements['".$this->_focus."'] );\n".
"if( sType != 'undefined' && sType != null ) \n".
" document.forms['".$this->_name."'].elements['".$this->_focus."'].focus();\n".
"//-->\n".
"</script>\n":""
);
return $result;
}
}
?>
|