PHP Classes

File: class.FormHandler.php

Recommend this page to a friend!
  Classes of T. H.   FormHandler   class.FormHandler.php   Download  
File: class.FormHandler.php
Role: Class source
Content type: text/plain
Description: Main class
Class: FormHandler
Generate and validate Web forms
Author: By
Last change:
Date: 18 years ago
Size: 84,996 bytes
 

Contents

Class file image Download
<?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; } } ?>