<?php
//
// +---------------------------------------------------------------------------+
// | Nitro :: Libraries :: Form |
// +---------------------------------------------------------------------------+
// | Copyright (c) 2004-2007 June Systems BV |
// +---------------------------------------------------------------------------+
// | This library is free software; you can redistribute it and/or modify it |
// | under the terms of the GNU Lesser General Public License as published by |
// | the Free Software Foundation; either version 2.1 of the License, or (at |
// | your option) any later version. |
// | |
// | This library is distributed in the hope that it will be useful, but |
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
// | General Public License for more details. |
// | |
// | You should have received a copy of the GNU Lesser General Public License |
// | along with this library; if not, write to the Free Software Foundation, |
// | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
// +---------------------------------------------------------------------------+
// | Authors: Siggi Oskarsson <hide@address.com> |
// | Authors: Jesper Avot <hide@address.com> |
// +---------------------------------------------------------------------------+
//
// $Id: Form.inc.php 230 2008-05-13 13:34:54Z june $
//
/**
* This file contains all the Form classes in Nitro. These can be used
* to create media independant forms which can be drawn for different
* kinds of media, dependant on the template used.
*
* @package Nitro
* @subpackage Libraries
* @author Siggi Oskarsson
* @author Jesper Avot
* @version $Revision: 1.50 $
* @copyright 2004-2007 June Systems BV
*/
/**
* Defines need by the classes in this file
*/
define ('NITRO_DEFAULT_FORMTEMPLATE', "file:".NITRO_PATH."Defaults/Templates/Form.tpl");
define ('NITRO_DEFAULT_WIDGETTEMPLATE', "file:".NITRO_PATH."Defaults/Templates/Widget.tpl");
/**
* Require the Nitro template engine
*/
require_once "Nitro/Template.inc.php";
/**
* The Form Model class
*
* This is the base class for all the other Form classes.
* This class contains the commonly used functions, so they
* don't have to be rewritten in every class.
* This is a private class and should only be used as a parent
* for all Form classes.
*
* @package Nitro
* @subpackage Libraries
* @access private
*/
class FormModel {
/**
* Array with all the option objects.
*
* @var array $Options
*/
var $Options = array();
/**
* Array with all the custom objects/values.
*
* @var array $Custom
*/
var $Custom = array();
/**
* FormModel class constructor
*
* Not used yet, but implemented for future use.
*
* @ignore
*/
function FormModel()
{
}
/**
* FormModel factory
*
* Use this function to create a form instance i.o. the constructor.
*
* @param string $Subclass The subclass to instantiate
* subclasses: Form, Group, Option, Tab
* @param array $aParams The input parameters for the subclass
*
* @todo Split Form.inc.php in separate files for each subclass, build Lazy Load (require_once in switch stmnt)
* Rename *this* file to FormModel.inc.php
*/
function &Factory($Subclass, $aParams)
{
DebugGroup(__CLASS__, __FUNCTION__, '', __FILE__, __LINE__, DEBUG_MOD_OK);
if (!is_array($aParams)) {
Debug(__CLASS__, __FUNCTION__, 'Form: \'aParams\' is not an array', __FILE__, __LINE__, DEBUG_MOD_ERR);
$Subclass = '';
$instance = FALSE;
}
$classname = 'Form' . $Subclass;
switch ($Subclass) {
case 'Form':
//if (file_exists('Form.inc.php')) { } For future use
if (class_exists('Form')) {
//ensure params are set
$aParams['name'] = isset($aParams['name'])
? $Name = $aParams['name'] : $Name = '';
$aParams['action'] = isset($aParams['action'])
? $Action = $aParams['action'] : $Action = FALSE;
$aParams['method'] = isset($aParams['method'])
? $Method = $aParams['method'] : $Method = 'POST';
$aParams['encType'] = isset($aParams['encType'])
? $encType = $aParams['encType'] : $encType = 'multipart/form-data';
$aParams['onsSubmit'] = isset($aParams['onsSubmit'])
? $onSubmit = $aParams['onsSubmit'] : $onSubmit = NULL;
$aParams['splitValues'] = isset($aParams['splitValues'])
? $SplitValues = $aParams['splitValues'] : $SplitValues = FALSE;
$instance = &new Form($Name, $Action , $Method , $encType, $onSubmit, $SplitValues);
} else {
$instance = FALSE;
}
break;
case 'Group':
if (class_exists($classname)) {
//ensure params are set
$aParams['name'] = isset($aParams['name'])
? $Name = $aParams['name'] : $Name = '';
$aParams['id'] = isset($aParams['id'])
? $ID = $aParams['id'] : $ID = NULL;
$aParams['lable'] = isset($aParams['lable'])
? $Lable = $aParams['lable'] : $Lable = NULL;
$aParams['widgetType'] = isset($aParams['widgetType'])
? $WidgetType = $aParams['widgetType'] : $WidgetType = 'GROUP';
$aParams['legend'] = isset($aParams['legend'])
? $Legend = $aParams['legend'] : $Legend = NULL;
$aParams['display'] = isset($aParams['display'])
? $Display = $aParams['display'] : $Display = 'inline';
$instance = &new $classname($Name, $ID, $Lable, $WidgetType, $Legend, $Display);
} else {
$instance = FALSE;
}
break;
case 'Option':
if (class_exists($classname)) {
//ensure params are set
$aParams['name'] = isset($aParams['name'])
? $Name = $aParams['name'] : $Name = '';
$aParams['option'] = isset($aParams['option'])
? $Option = $aParams['option'] : $Option = NULL;
$instance = &new $classname($Name, $Option);
} else {
$instance = FALSE;
}
break;
case 'Tab':
if (class_exists($classname)) {
//ensure params are set
$aParams['name'] = isset($aParams['name'])
? $Name = $aParams['name'] : $Name = '';
$aParams['id'] = isset($aParams['id'])
? $ID = $aParams['id'] : $ID = NULL;
$aParams['NewWay'] = isset($aParams['NewWay'])
? $NewWay = $aParams['NewWay'] : $NewWay = 'no';
$instance = &new $classname($Name, $ID, $NewWay);
} else {
$instance = FALSE;
}
break;
default:
Debug(__CLASS__, __FUNCTION__, "Form: unknown subclass ".$Subclass, __FILE__, __LINE__, DEBUG_MOD_ERR);
$instance = FALSE;
}
DebugCloseGroup(DEBUG_MOD_OK);
return $instance;
}
/**
* AddOptionString
*
* Creates a new option on the form from the standard option string.
* This string is parsed and an object is created which is added to
* the form via the AddOption function.
*
* @see AddOption()
* @see FormOption::ParseOptionString()
* @param string $Name Name of option to add. (default is FALSE)
* @param string $OptionString String definition of option. (default is FALSE)
* @return mixed The output of the AddOption() function.
* @access public
*/
function AddOptionString($Name = FALSE, $OptionString = FALSE)
{
$Option = FALSE;
if ($Name !== FALSE && $OptionString !== FALSE) $Option = new FormOption($Name, $OptionString);
return $this->AddOption($Option);
}
/**
* AddOptionsFromArray
*
* Loops through the given array and adds all the options.
*
* @see AddOptionString()
* @param array $Options Array with the Options to add. (default is FALSE)
* @return mixed The output of the AddOptionString() function.
* @access public
*/
function AddOptionsFromArray($Options = FALSE)
{
$RV = FALSE;
if ($Options !== FALSE && is_array($Options)) {
foreach ($Options AS $Name => $OptionString) {
$this->AddOptionString($Name, $OptionString);
$RV = TRUE;
}
}
return $RV;
}
/**
* AddOption
*
* Adds an new Form option to the Options array.
*
* @param object $Option The new Form option object. (default is FALSE)
* @return bool $RV TRUE or FALSE
* @access public
*/
function AddOption($Option = FALSE)
{
$RV = FALSE;
if ($Option !== FALSE && is_object($Option)) {
$this->Options[] = $Option;
$RV = TRUE;
}
return $RV;
}
/**
* AddTab
*
* Alias for AddOption()
*
* @see AddOption()
* @param object $Option The new Form option object. (default is FALSE)
* @return mixed The output of the AddOption() function.
* @access public
*/
function AddTab($Option = FALSE)
{
return $this->AddOption($Option);
}
/**
* AddCustom
*
* Adds an new Custom object/value to the Custom array.
* The custom object/value can be called within the template
* by {$Custom.xxx}.
*
* @param string $Variable The variable-name of the new Custom object/value.
* @param mixed $Value The value of the new variable.
* @return bool $RV TRUE or FALSE.
* @access public
*/
function AddCustom($Variable = FALSE, $Value = FALSE)
{
$RV = FALSE;
if ($Variable !== FALSE && $Value !== FALSE) {
$this->Custom[$Variable] = $Value;
$RV = TRUE;
}
return $RV;
}
/**
* Draw
*
* This function is just a placeholder, it should be overwritten by the children.
*/
function Draw()
{
}
/**
* DrawXML
*
* This function is just a placeholder, it should be overwritten by the children.
*/
function DrawXML()
{
}
/**
* function array_join
* merges 2 arrays preserving the keys,
* even if they are numeric (unlike array_merge)
* if 2 keys are identical, the last one overwites
* the existing one, just like array_merge
* merges up to 10 arrays, minimum 2.
*
* Author: hide@address.com
* Source: http://nl3.php.net/manual/en/function.array-merge.php#69991
*/
function array_join($a1, $a2, $a3=null, $a4=null, $a5=null, $a6=null, $a7=null, $a8=null, $a9=null, $a10=null)
{
$a = array();
foreach ($a1 AS $key => $value) $a[$key]=$value;
foreach ($a2 AS $key => $value) $a[$key]=$value;
if (is_array($a3)) $a = array_join($a,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$a10);
return $a;
}
}
/**
* The Form class
*
* This class contains the form definition. All controls will
* be added to the main form class to be drawn.
*
* <CODE>
* $myForm = new Form("FormName", "FormAction", "FormMethod: POST or GET", "FormEncType", "FormOnSubmitHandler", "SplitValues: TRUE/FALSE");
*
* $myForm->AddButton('Method[SAVE]', array('Type' => 'SUBMIT', 'ID' => '', 'Value' => Language('Save')));
* $myForm->AddButton('Method[APPLY]', array('Type' => 'SUBMIT', 'ID' => '', 'Value' => Language('Apply')));
* $myForm->AddButton('Method[CANCEL]', array('Type' => 'SUBMIT', 'ID' => '', 'Value' => Language('Cancel')));
*
* $myForm->AddOptionString("ID", "HIDDEN/VALUE=".$ID);
* $myForm->AddOptionString("Name", "TEXT/VALUE=Name/MAXLENGTH=50/LABLE=Name/STYLE=width: 250");
* $myForm->AddOptionString("Username", "TEXT/VALUE=$Username/LABLE=Username/MAXLENGTH=16");
* $myForm->AddOptionString("Password", "PASSWORD/LABLE=Password/MAXLENGTH=16");
* $myForm->AddOptionString("PasswordRepeat", "PASSWORD/LABLE=Repeat Password");
* $myForm->AddOptionString("Active", "CHECKBOX/SELECTED=1/VALUES=1: /LABLE=Active");
* $Query = "SELECT TemplateID AS ID, Name FROM Template ORDER BY Name";
* $myForm->AddOptionString("TemplateID", "SELECT/SELECTED=14/VALUES=: -- Select a Template -- /STYLE=width: 250/QUERY=NitroBO:$Query/LABLE=Template");
* $Query = "SELECT UserID AS ID, UserName AS Name FROM User";
* $myForm->AddOptionString("Selectbox[]", "SELECTMULTIPLE/SELECTED=1,2,3/STYLE=width: 250/QUERY=NitroBO:$Query/LABLE=Security/ROWS=10");
*
* $tab = new FormTab("UserTabs");
* $tab->AddTab("Adress", "Adress");
* $tab->AddOptionString("Address", "TEXT/VALUE=$Adress/LABLE=Address");
* $tab->AddOptionString("Zipcode", "TEXT/VALUE=$Zipcode/LABLE=Zipcode/MAXLENGTH=8");
* $tab->AddOptionString("City", "TEXT/VALUE=$Adress/LABLE=City");
* $tab->AddOptionString("Country", "TEXT/VALUE=$Adress/LABLE=Country");
* $tab->AddOptionString("Directions", "TEXTAREA/VALUE=$Directions/LABLE=Country/ROWS=5/COLS=10");
* $tab->AddTab("Bio", "Bio");
* $tab->AddOptionString("Bio", "HTML/LABLE= /VALUE=".urlencode($Bio));
* $tab->AddTab("Photo", "Photo");
* $tab->AddOptionString("Photo", "FILE/TYPE=IMAGE");
* $tab->AddOptionString("Preview", "PREVIEW/TYPE=IMAGE/VALUE=$PhotoPath");
* $myForm->AddOption($tab);
*
* echo $myForm->Draw();
*</CODE>
*
* @see FormModel class
* @package Nitro
* @subpackage Libraries
* @access public
*/
class Form extends FormModel {
var $Name;
var $Action;
var $Method;
var $Buttons;
var $HideButtons;
var $FormTemplateID = NULL;
var $WidgetTemplateID = NULL;
var $SplitValues = FALSE;
/**
* Form class constructor
*
* @param string $Name Name of the form
* @param string $Action Action of form when submitted (default FALSE, <empty>)
* @param string $Method Method by which to submit form (default POST)
* @param string $encType Encoding to use in the form
* @param string $onSubmit onSubmit javascript action
* @param bool $SplitValues Boolean telling the Form-class if it should split the values (if TRUE, values will be drawn after the form elements have been drawn).
* @access public
*/
function Form ($Name, $Action = FALSE, $Method = "POST", $encType = "multipart/form-data", $onSubmit = NULL, $SplitValues = FALSE)
{
$this->Name = $Name;
$this->ID = $Name;
$this->Action = $Action;
$this->Method = $Method;
$this->encType = $encType;
$this->onSubmit = $onSubmit;
$this->FormTemplateID = FALSE;
$this->WidgetTemplateID = FALSE;
$this->SplitValues = $SplitValues;
parent::FormModel();
}
/**
* Set the Action to do when the form is submitted
*
* @param string $Action Action of form
* @access public
*/
function SetAction($Action)
{
$this->Action = $Action;
}
/**
* Set the Method to use when form is submitted
*
* @param string $Method Method of form
* @access public
*/
function SetMethod($Method)
{
$this->Method = $Method;
}
/**
* Set the templates to use to draw the form
*
* This functions sets the templates to use to draw the form and
* the controls contained on the form. If none are set, the class
* will use the Nitro default templates.
*/
function SetTemplateIDs($FormTemplateID = FALSE, $WidgetTemplateID = FALSE)
{
if ($FormTemplateID) $this->FormTemplateID = $FormTemplateID;
if ($WidgetTemplateID) $this->WidgetTemplateID = $WidgetTemplateID;
}
/**
* Hide all form Buttons
*
* This function tells the form class to hide the default buttons, aswell
* as the buttons set on the form!
*
* @param boolean $Hide Hide or show buttons
* @access public
*/
function HideButtons($Hide = TRUE)
{
$this->HideButtons = $Hide;
}
/**
* Add Button to form
*
* This function adds a button definition to the form. If no buttons are
* added to the form, the default buttons (Reset, Submit, Cancel) will be
* shown.
*
* @param string $Name Name of button
* @param array $Parameters Button parameters used to draw the button in the template
* @access public
*/
function AddButton($Name, $Parameters)
{
$this->Buttons[$Name] = $Parameters;
if(!(array_key_exists('Value', $Parameters) && $Parameters["Value"])) $this->Buttons[$Name]["Value"] = $Name;
}
/**
* Draw the form
*
* This function draws the form and all options contained on the form. First the
* options are drawn via their own draw function, using the Widget template, and
* then the form itself is drawn using the form template.
*
* @access public
*/
function Draw()
{
$Template = new NitroTemplate($this->FormTemplateID);
$Widget = new NitroTemplate($this->WidgetTemplateID);
$ParsedOptions = array();
if (is_array($this->Options)) {
foreach ($this->Options AS $Option) {
$Widget->ClearAll();
if (count($this->Custom)) {
// Add custom values from Form to widgets
foreach ($this->Custom AS $id => $custom) {
if (!isset($Option->Custom[$id])) $Option->AddCustom($id, $custom);
}
}
$ParsedOptions[] = $Option->Draw($Widget, $this->SplitValues);
}
}
$Template->Assign("Options", $ParsedOptions);
$RV = FALSE;
// Assign Form variables
if ($this->Name || $this->Action) {
$Template->Assign("FormType", "OpenForm");
$Template->Assign("Name", $this->Name);
$Template->Assign("Id", $this->ID);
$Template->Assign("Method", $this->Method);
$Template->Assign("Action", $this->Action);
$Template->Assign("encType", $this->encType);
$Template->Assign("onSubmit", $this->onSubmit);
$Template->Assign("SplitValues", $this->SplitValues);
if (count($this->Custom)) $Template->Assign("Custom", $this->Custom);
}
if ($this->Name || $this->Action) {
$Buttons = array();
if (!$this->HideButtons && $this->Buttons) {
$Buttons = $this->Buttons;
} elseif (!$this->HideButtons) {
//Do nothing seems better than always drawing buttons
//Don't agree => Always have defaults ready!!!
$Buttons["Submit"]["Type"] = "SUBMIT";
$Buttons["Submit"]["Value"] = "Submit";
$Buttons["Reset"]["Type"] = "RESET";
$Buttons["Reset"]["Value"] = "Reset";
$Buttons["Cancel"]["Type"] = "BUTTON";
$Buttons["Cancel"]["Value"] = "Cancel";
$Buttons["Cancel"]["onClick"] = "document.location.href='$this->Action'";
}
$Template->Assign("Buttons", $Buttons);
$RV = $Template->Fetch(NITRO_DEFAULT_FORMTEMPLATE);
}
return $RV;
}
/**
* DrawXML
*
* Draws the ValuesXML for the current Form when this->SplitValues is TRUE.
*
* @return string The FormXML of all values. (default is an empty array)
*/
function DrawXML()
{
$ResponseXML = array();
if ($this->SplitValues === TRUE) {
if (is_array($this->Options)) {
foreach ($this->Options AS $Option) {
if (count($this->Custom)) {
// Add custom values from Form to widgets
foreach ($this->Custom AS $id => $custom) {
if (!isset($Option->Custom[$id])) $Option->AddCustom($id, $custom);
}
}
$Option->DrawXML($ResponseXML);
}
}
}
return $ResponseXML;
}
}
/**
* Form option class
*
* This class holds the definitions of the form options themselves.
*
* @see FormModel class
* @package Nitro
* @subpackage Libraries
* @access public
*/
class FormOption extends FormModel {
var $Name;
var $Option;
var $OptionParsed;
var $Type;
var $Values;
var $Style;
var $Lable;
var $AutoSubmit;
var $Script;
var $OnChange;
var $SelectedValues = array();
var $TypesToDrawWithSplitValues = array(
'CHECKBOX', 'CHECKBOXV', 'RADIO', 'RADIOV', 'LABLE'
);
/**
* Form option class constructor
*
* This functions new FormOption();initializes the form option object.
*
* @param string $Name Option name
* @param string $Option Option string definition
* @access public
*/
function FormOption($Name, $Option = NULL)
{
$this->Name = $Name;
$this->Option = $Option;
parent::FormModel();
if ($Option) {
$this->OptionParsed = $this->ParseOptionString($Option);
$this->SetOption($this->OptionParsed);
}
}
/**
* Set option properties from parsed option string
*
* This function sets the object properties from a parsed option string
* definition. This string definition can be parsed by ParseOptionString.
*
* @see ParseOptionString()
* @param array $ParsedOption Parsed option string definition
* @access public
*/
function SetOption($ParsedOption)
{
$this->Type = (isset($ParsedOption["Type"]) ? $ParsedOption["Type"] : '');
$this->ID = (isset($ParsedOption["ID"]) ? $ParsedOption["ID"] : '');
$this->Disabled = (isset($ParsedOption["Disabled"]) ? TRUE : FALSE);
$this->Values = (isset($ParsedOption["Values"]) ? $ParsedOption["Values"] : '');
$this->Style = (isset($ParsedOption["Style"]) ? $ParsedOption["Style"] : '');
$this->Custom = (isset($ParsedOption["Custom"]) ? $ParsedOption["Custom"] : array());
$this->Lable = (isset($ParsedOption["Lable"]) ? $ParsedOption["Lable"] : $this->Name);
$this->Help = (isset($ParsedOption["Help"]) ? $ParsedOption["Help"] : '');
$this->AutoSubmit = (isset($ParsedOption["AutoSubmit"]) ? $ParsedOption["AutoSubmit"] : '');
$this->Script = (isset($ParsedOption["Script"]) ? $ParsedOption["Script"] : '');
$this->OnChange = (isset($ParsedOption["OnChange"]) ? $ParsedOption["OnChange"] : '');
if (isset($ParsedOption["SelectedValues"]) && is_array($ParsedOption["SelectedValues"]) && count($ParsedOption["SelectedValues"])) {
$this->SelectedValues = array_merge($this->SelectedValues, $ParsedOption["SelectedValues"]);
} elseif (isset($ParsedOption["Default"]) && is_array($ParsedOption["Default"]) && count($ParsedOption["Default"])) {
$this->SelectedValues = array_merge($this->SelectedValues, $ParsedOption["Default"]);
}
}
/**
* Add selected values for option
*
* This function adds values that are supposed to be selected in the
* option. It can take either a single value or an array of values as
* its parameter.
*
* @param mixed $Value Selected value(s)
*/
function AddSelected($Value)
{
if (is_array($Value)) {
foreach($Value AS $val) {
if (strlen($val)) $this->SelectedValues[] = $val;
}
} else {
if (strlen($Value)) $this->SelectedValues[] = $Value;
}
}
/**
* Draw the option
*
* This function draws the option according to the widget template passed
* to it.
* <CODE>
* The variables that er passed to the template are:
* - WidgetType = Type of widget
* - Disabled = TRUE or $Value if given
* - Name = Name of widget
* - Lable = Widget lable
* - Values = Selected values
* - Style = Style to set inline
* - Custom = Array of custom elements not recognized by parseOptionString()
* - WidgetAutoSubmit = TRUE or FALSE, auto submit widget on change
* - Script = SCRIPT to add inline to widget
* - Selected = TRUE|FALSE
* - Nitro_Editor = Editor to use for HTML forms
* - SplitValues = TRUE|FALSE
* </CODE>
*
* @param object $Template Widget template object.
* @param bool $SplitValues TRUE or FALSE.
* @return array
* @access public
*/
function Draw(&$Template, $SplitValues = FALSE)
{
$Template->Assign("WidgetType", $this->Type);
$Template->Assign("Disabled", $this->Disabled);
$Template->Assign("Name", $this->Name);
$Template->Assign("Id", $this->ID);
$Template->Assign("Lable", $this->Lable);
$Template->Assign("Help", $this->Help);
$Template->Assign("Style", $this->Style);
$Template->Assign("Custom", $this->Custom);
$Template->Assign("WidgetAutoSubmit", $this->AutoSubmit);
$Template->Assign("Script", $this->Script);
$Template->Assign("OnChange", $this->OnChange);
$Template->Assign("Nitro_Editor", "1"); //Jesper: Why is this always 1?!?!?!
$Template->Assign("SplitValues", $SplitValues);
// Assign values if the current WidetType is in the TypesToDrawWithSplitValues array or SplitValues is FALSE.
if (in_array($this->Type, $this->TypesToDrawWithSplitValues) || $SplitValues === FALSE) {
$Template->Assign("Values", $this->Values);
} else {
$Template->Assign("Values", array());
}
if ($SplitValues === FALSE) {
$Template->Assign("Selected", $this->SelectedValues);
} else {
$Template->Assign("Selected", array());
}
return array(
"WidgetType" => $this->Type,
"Lable" => $this->Lable,
"Help" => $this->Help,
"Name" => $this->Name,
"Id" => $this->ID,
"Custom" => $this->Custom,
"Controls" => $Template->fetch(NITRO_DEFAULT_WIDGETTEMPLATE)
);
}
/**
* DrawXML
*
* Draws the values in XML.
*
* @param array $ResponseXML The ResponseXML array.
* @access public
*/
function DrawXML(&$ResponseXML)
{
if (is_array($ResponseXML)) {
$ResponseXML[$this->Name] = array(
'WidgetType' => $this->Type,
'Values' => array()
);
if (count($this->Values) > 0) {
foreach ($this->Values AS $K => $V) {
$ResponseXML[$this->Name]['Values'][rawurlencode($K)] = array(
'Selected' => (in_array($K, $this->SelectedValues) ? TRUE : FALSE),
'Value' => rawurlencode($V)
);
}
}
}
}
/**
* Parse option string and load into object
*
* This function parses an option string and returns an array of all the
* properties found. This array can be used to set the values in the object.
*
* <CODE>
* Option Types:
* - SELECT = Select box
* - SELECTMULTIPLE = Select box with multiple selection possible
* - TEXT = Text input
* - TEXTAREA = Text area
* - TEXTHTML = HTML area
* - PASSWORD = Password input
* - HIDDEN = Hidden input
* - RADIO = Radio select group
* - CHECKBOX = Checkbox
* - READONLY = Read only element, text
* - BUTTON = Button element
* - TAB = Tab group, uses all other elements
* - GROUP = Group, uses all other elements
* - DATE = Date element, Y-M-D
* - FILE = File input
*
* Option actions:
* - LOOKUP = DB lookup, one answer <- NOT IMPLEMENTED YET
* - VALUE = Single value, may be associative
* e.g. /VALUE=Key:Value/
* e.g. /VALUE=Username/ <- in TEXT, HTML and TEXTAREA
* - VALUES = Range with values (comma seperated)
* e.g. /VALUES=Key1:Value1,Key2:Value2/
* - NUMLIST = Numeric range (id and value identical)
* e.g. /NUMLIST=1:10/ <- List from 1 to 10 with key and value
* - DB = DB lookup, multiple, sets VALUES
* e.g. /DB={[DBAlias]:[Table]:[IDColumn]:[NameColumn]}/
* - QUERY = DB lookup from query, sets VALUES
* e.g. /QUERY=[DBAlias]:$Query/
* - STYLE = Literal string for STYLE of option element
* e.g. /STYLE=color: black; background-color: white/
* - LITERAL = Literal string for options
* e.g. /LITERAL=This is a text that will be literally shown/
* - LABLE = Lable of form element, default is name
* e.g. /LABLE=This is the lable of the element/
* - LABEL = Alias for LABLE
* - ID = ID of element
* e.g. /ID=Element_ID/
* - SELECTED = Value of selected element in RADIO, CHECKBOX, SELECT
* e.g. /SELECTED=1/
* e.g. /SELECTED=1,2,3/
* e.g. /SELECTED=User1,User2/
* - DEFAULT = Default selected element if SELECTED is empty
* e.g. /DEFAULT=User1/
* - DEFAULTS = Alias for DEFAULT
* - AUTO = Auto submit form on element change
* e.g. /AUTO/
* - SCRIPT = Javascript to add inline to element
* e.g. /SCRIPT=onClick:onClickFunction()/
* - DISABLED = Element disabled if true
* e.g. /DISABLED/
* </CODE>
*
* @see GetDBValues()
* @see GetDBValuesFromQuery()
* @param string $Option Option string definition
* @access public
* @return array Parsed option string
*/
function ParseOptionString($Option = FALSE)
{
$ParsedOption = array();
if ($Option !== FALSE) {
$Option = explode('/', $Option);
$OptionType = array_shift($Option);
$ParsedOption["Type"] = $OptionType;
$ParsedOption["Values"] = array();
if (is_array($Option)) {
foreach ($Option AS $OptionType) {
$OptionData = explode('=', $OptionType, 2);
if (isset($OptionData[0])) {
$OptionString = $OptionData[1];
switch (strtoupper($OptionData[0])) {
case "VALUE":
$ParsedOption["Values"] = $this->array_join($ParsedOption["Values"], $this->Option_Value($OptionString));
break;
case "VALUES":
$ParsedOption["Values"] = $this->array_join($ParsedOption["Values"], $this->Option_Value($OptionString, 2));
break;
case "NUMLIST":
$ParsedOption["Values"] = $this->array_join($ParsedOption["Values"], $this->Option_NumList($OptionString));
break;
case "DB":
$ParsedOption["Values"] = $this->array_join($ParsedOption["Values"], $this->Option_DataBase($OptionString));
break;
case "QUERY":
$ParsedOption["Values"] = $this->array_join($ParsedOption["Values"], $this->Option_DataBase($OptionString, 2));
break;
case "STYLE":
$ParsedOption["Style"] = $OptionString;
break;
case "LITERAL":
$ParsedOption["Literal"] = $OptionString;
break;
case "LABEL":
case "LABLE":
$ParsedOption["Lable"] = urldecode($OptionString);
break;
case "HELP":
$ParsedOption["Help"] = urldecode($OptionString);
break;
case "ID":
$ParsedOption["ID"] = $OptionString;
break;
case "SELECTED":
$ParsedOption["SelectedValues"] = $this->Option_Selected($OptionString);
break;
case "DEFAULT":
case "DEFAULTS":
$ParsedOption["Default"] = $this->Option_Default($OptionString);
break;
case "AUTO":
$ParsedOption["AutoSubmit"] = $OptionString;
break;
case "SCRIPT":
$ParsedOption["Script"][] = $this->Option_Script($OptionString);
break;
case "ONCHANGE":
$ParsedOption["OnChange"] = urldecode($OptionString);
break;
case "DISABLED":
$ParsedOption["Disabled"] = (isset($OptionString) ? $OptionString : TRUE);
break;
default:
$ParsedOption["Custom"][$OptionData[0]][] = urldecode($OptionString);
break;
}
}
}
}
}
return $ParsedOption;
}
function Option_Value($OptionString = '', $Type = 1)
{
$RV = array();
if (eregi(',', $OptionString)) {
$Options = explode(',', $OptionString);
foreach ($Options AS $Option) {
$RV = $this->array_join($RV, $this->Option_Value($Option, $Type));
}
} else {
if (eregi(':', $OptionString)) {
$Option = explode(':', $OptionString);
if (isset($Option[1])) {
$RV[urldecode($Option[0])] = urldecode($Option[1]);
} else {
$RV[] = urldecode($Option[0]);
}
} else {
if ($Type === 2) {
$RV[urldecode($OptionString)] = urldecode($OptionString);
} else {
$RV[] = urldecode($OptionString);
}
}
}
return $RV;
}
function Option_NumList($OptionString = '')
{
$RV = array();
if (eregi(':', $OptionString)) {
$Option = explode(':', $OptionString);
if (count($Option) == 2) {
if ($Option[0] > $Option[1]) {
for ($i = $Option[0]; $i >= $Option[1]; $i--) {
$RV[$i] = $i;
}
} else {
for ($i = $Option[0]; $i <= $Option[1]; $i++) {
$RV[$i] = $i;
}
}
}
}
return $RV;
}
function Option_DataBase($OptionString = '', $Type = 1)
{
$RV = array();
$DBValues = ($Type === 2 ? $this->GetDBValuesFromQuery($OptionString) : $this->GetDBValues($OptionString));
foreach ($DBValues AS $Key => $Value) {
$RV[$Key] = $Value;
}
return $RV;
}
function Option_Selected($OptionString = '')
{
return $this->Option_Default($OptionString);
}
function Option_Default($OptionString = '')
{
$RV = array();
if (eregi(',', $OptionString)) {
$Option = explode(',', $OptionString);
foreach($Option AS $Default) {
if (strlen($Default)) $RV[] = $Default;
}
} else {
if (strlen($OptionString)) $RV[] = $OptionString;
}
return $RV;
}
function Option_Script($OptionString = '')
{
$RV = '';
if (eregi(':', $OptionString)) {
$Option = explode(':', $OptionString);
if (count($Option) == 2) $RV = $Option[0].'=\''.urldecode($Option[1]).'\'';
}
return $RV;
}
/**
* Get values from db by query
*
* This function executes the query and fetches the values from the result.
* The default DB array of objects $DB is globalized and used for the query.
*
* <CODE>
* $Query = "SELECT UserID AS ID, UserName AS Name FROM User";
* e.g. string => "[DBAlias]:$Query"
* </CODE>
*
* @param string $String DB query string
* @access private
* @TODO Catch DB Errors!
*/
function GetDBValuesFromQuery($String)
{
global $DB;
$OriginalString = $String;
$String = ereg_replace("^{", "", $String);
if ($OriginalString != $String) $String = ereg_replace("}$", "", $String);
$tmp = explode(":", $String);
$DBAlias = array_shift($tmp);
$Query = array_shift($tmp);
if (DB::isDBCon($DB[$DBAlias])) {
$Result = $DB[$DBAlias]->query($Query);
$Values = array();
while($Row = $Result->FetchArray()) {
$Values[$Row["ID"]] = $Row["Name"];
if ($Row["SELECTED"]) $this->SelectedValues[] = $Row["ID"];
}
$Result->free();
return $Values;
} else {
return FALSE;
}
}
/**
* Get values from db by string
*
* This function parses a DB query string, creates the query and fetches
* the result. It uses GetDBValuesFromQuery to perform the actual query.
* The default DB array of objects $DB is globalized and used for the Lookup.
*
* <CODE>
* Format:
* [DBAlias]:[Table]:[IDColumn]:[NameCol]:[[WHERE CLAUSE]]
* - DBAlias = DB object in $DB array
* - Table = Table in database to use
* - IDColumn = Name of ID column in table to use
* - NameCol = Name of column to use for the name, comma seperated list will be concated
* - WHERE CLAUSE = Optional, extra where clause to use in query after WHERE
*
* e.g. Nitro:Menu:MenuID:Name
* e.g. Nitro:Menu:MenuID:Name:TemplateID=1
* e.g. Nitro:User:UserID:FirstName, ,LastName
* </CODE>
*
* @see GetDBValuesFromQuery()
* @param string $String DB query string
* @access private
* @TODO Catch DB Errors!
*/
function GetDBValues($String)
{
global $DB;
$OriginalString = $String;
$String = ereg_replace("^{", "", $String);
if ($OriginalString != $String) $String = ereg_replace("}$", "", $String);
$tmp = explode(":", $String);
$DBAlias = array_shift($tmp);
$Table = array_shift($tmp);
$IDCol = array_shift($tmp);
$NameCol = explode(",", array_shift($tmp));
$Where = explode(",", implode(":", $tmp));
$Query = "
SELECT
".$IDCol." AS ID,
".(count($NameCol) > 1 ? "
CONCAT(".urldecode(implode(",", $NameCol)).")
" :
urldecode($NameCol[0])
)." AS Name
FROM ".$Table."
";
if (count($Where) && $Where[0] != "") {
foreach ($Where AS $WhereStatement) {
if (ereg("\{LOOKUP\:", $WhereStatement)) {
$tmp = explode("=", $WhereStatement, 2);
$Column = $tmp[0];
$Lookup = $tmp[1];
$OriginalLookup = $Lookup;
$Lookup = ereg_replace("^{", "", $Lookup);
if ($OriginalLookup != $Lookup) $Lookup = ereg_replace("}$", "", $Lookup);
$tmp = explode(":", $Lookup);
$null = array_shift($tmp);
$LookupTable = array_shift($tmp);
$LookupValue = array_shift($tmp);
$LookupWhere = array_shift($tmp);
$LookupQuery = "
SELECT ".$LookupValue."
FROM ".$LookupTable."
WHERE ".$LookupWhere."
";
$LookupResult = $DB[$DBAlias]->getOne($LookupQuery);
$Query.= "
WHERE ".$Column." = ".($LookupResult ? NitroPrepareDB($LookupResult) : "''")."
";
} else {
$Query.= "
WHERE ".$WhereStatement."
";
}
}
}
$Query.= "
ORDER BY Name
";
return $this->GetDBValuesFromQuery($DBAlias.":".$Query);
}
}
/**
* Form group class
*
* With this class multiple options on a form can be grouped together
* into a group of options (Fieldset).
*
* @see FormModel class
* @package Nitro
* @subpackage Libraries
* @access public
*/
class FormGroup extends FormModel {
var $Name;
var $ID;
var $Lable;
var $Legend;
var $WidgetType = 'GROUP';
/**
* Form group class constructor
*
* This is the class constructor of the form group.
*
* @param string $Name Name of the form group
* @param string $ID ID of the form group (default is Name if ID is empty)
* @param string $Lable Lable of form group
* @access public
*/
function FormGroup($Name, $ID = NULL, $Lable = NULL, $WidgetType = 'GROUP', $Legend = NULL, $Display = 'inline')
{
$this->Name = $Name;
$this->ID = ($ID ? $ID : $Name);
$this->Lable = $Lable;
$this->WidgetType = $WidgetType;
$this->Legend = ($Legend ? $Legend : $Lable);
$this->Display = $Display;
parent::FormModel();
}
/**
* Set the lable of the group
*
* @param string $Lable Lable of the group
* @access public
*/
function SetLable($Lable)
{
$this->Lable = $Lable;
}
/**
* Draw the option group
*
* This function draws all options in the group and then the group itself
* using the widget template.
*
* @param object $TemplateHandler Widget template object.
* @param bool $SplitValues TRUE or FALSE.
* @access public
*/
function Draw(&$TemplateHandler, $SplitValues = FALSE)
{
$GroupOptions = array();
if (is_array($this->Options)) {
foreach ($this->Options AS $Option) {
if (count($this->Custom)) {
// Add custom values from Form to widgets
foreach ($this->Custom AS $id => $custom) {
if (!isset($Option->Custom[$id])) $Option->AddCustom($id, $custom);
}
}
$GroupOptions[] = $Option->Draw($TemplateHandler, $SplitValues);
}
}
$TemplateHandler->ClearAll();
$TemplateHandler->assign("WidgetType", $this->WidgetType);
$TemplateHandler->assign("Display", $this->Display);
$TemplateHandler->assign("Name", $this->Name);
$TemplateHandler->assign("ID", $this->ID);
$TemplateHandler->assign("Lable", $this->Lable);
$TemplateHandler->assign("Legend", $this->Legend);
$TemplateHandler->assign("Help", $this->Help);
$TemplateHandler->assign("Controls", $GroupOptions);
if (count($this->Custom)) $TemplateHandler->Assign("Custom", $this->Custom);
return Array(
"WidgetType" => $this->WidgetType,
"Lable" => $this->Lable,
"Name" => $this->Name,
"ID" => $this->ID,
"Controls" => $TemplateHandler->fetch(NITRO_DEFAULT_WIDGETTEMPLATE)
);
}
/**
* DrawXML
*
* Draws the values in XML.
*
* @param array $ResponseXML The ResponseXML array.
* @access public
*/
function DrawXML(&$ResponseXML)
{
if (is_array($ResponseXML)) {
if (is_array($this->Options)) {
foreach ($this->Options AS $Option) {
if (count($this->Custom)) {
// Add custom values from Form to widgets
foreach ($this->Custom AS $id => $custom) {
if (!isset($Option->Custom[$id])) $Option->AddCustom($id, $custom);
}
}
$Option->DrawXML($ResponseXML);
}
}
}
}
}
/**
* Form Tab control
*
* This is the tab control that can be used in a form.
*
* Usage example:
* <CODE>
* $Version = Array(1 => "Version 1", 2 => "Version 2");
* $form = new form("TemplateForm");
* $tab = new FormTab("MainTab", "MainTabID");
* foreach($Version AS $V => $Val) {
* $tab->AddTab($V);
* $tab->AddOptionString("Title", "TEXT/VALUES=$Val");
* $tab2 = new FormTab("SubTab", "SubTabID");
* $tab2->AddTab($V."_sub1");
* $tab2->AddOptionString("1", "TEXT");
* $tab2->AddTab($V."_sub2");
* $tab2->AddOptionString("2", "TEXT");
* $tab2->AddTab($V."_sub3");
* $tab2->AddOptionString("3", "TEXT");
* $tab->AddOption($tab2);
* }
* $form->AddOption($tab);
* $form->Draw()
* </CODE>
*
* @package Nitro
* @subpackage Libraries
* @access public
*/
class FormTab extends FormModel {
var $Name;
var $NewWay;
var $Lable = NULL;
var $Tabs = array();
var $SelectedTab;
var $Actions = array();
var $TabActions = array();
var $TabStyles = array();
var $TabOnClick = array();
var $CurrentTab;
/**
* Form tab constructor
*
* This function initialized the form tab control.
*
* @param string $Name Name of the tab control
* @param string $ID ID of the tab control (default is Name)
*/
function FormTab($Name, $ID = NULL, $NewWay = "no")
{
$this->Name = $Name;
$this->ID = ($ID ? $ID : $Name);
$this->NewWay = $NewWay;
parent::FormModel();
}
/**
* Add tab to tab control
*
* This function adds a new tab to the tab control.
*
* @param string $Name Name of the tab
* @param string $ID ID of the tab (default is Name)
* @param string $Lable Lable of the tab
*/
function AddTab($TabName, $ID = NULL, $Lable = NULL, $Style = NULL, $OnClick = NULL)
{
if (!$ID) $ID = $TabName;
$this->Tabs[$ID] = $TabName;
$this->Lable = $Lable;
$this->TabStyles[$ID] = $Style;
$this->TabOnClick[$ID] = $OnClick;
$this->CurrentTab = $ID;
$RV = TRUE;
return $RV;
}
/**
* Add action to tab control
*
* This function adds an action to the tab control. This action can be used to
* for instance create a new tab of options.
*
* @param string $Name Name of the action
* @param string $URL URL of the tab action
* @param string $Image Image to show as the action button
*/
function AddAction($Name, $URL, $Image = NULL, $onClick = NULL)
{
$this->Actions[] = array("Name" => $Name, "URL" => $URL, "Image" => $Image, "onClick" => $onClick);
}
/**
* Add action to tab
*
* This function adds an action to the tab itself. This action can be used to
* for instance delete a tab. This action should only apply to the tab.
*
* @param string $Name Name of the action
* @param string $URL URL of the tab action
* @param string $Image Image to show as the action button
* @param string $TabID ID of the tab to add an action to (Default is current (last added) tab)
*/
function AddTabAction($Name, $URL, $Image = NULL, $TabID = NULL)
{
if (!$TabID) $TabID = $this->CurrentTab;
$this->TabActions[$TabID][] = array("Name" => $Name, "URL" => $URL, "Image" => $Image);
}
/**
* Set lable of tab control
*
* This function sets the lable of the tab control to show in the form. The form
* template whill show the lable as the label of an option.
*
* @param string $Lable Lable of tab control
*/
function SetLable($Lable)
{
$this->Lable = $Lable;
}
function SetSelectedTab($TabID)
{
$this->SelectedTab = $TabID;
}
/**
* Add option to tab via string
*
* This function creates a new option on the tab from the standard option
* string. This string is parsed and an object is created which is added to
* the form via the AddOption function.
*
* @see AddOption()
* @param string $Name Name of option to add
* @param string $OptionString String definition of option
* @param string $TabID ID of the tab to add the option to (Default is current (last added) tab)
* @access public
*/
function AddOptionString($Name, $OptionString, $TabID = NULL)
{
if (!$TabID) $TabID = $this->CurrentTab;
$Option = new FormOption($Name, $OptionString);
return $this->AddOption($Option, $TabID);
}
/**
* Add multiple options via array of strings
*
* This function accepts an array of options in string format and adds
* them to the tab. The name of the option to add is taken from the key
* of the array. This function uses the AddOption function
* to add the options to the form.
*
* @see AddOption()
* @param array $Options Array of option strings
* @param string $TabID ID of the tab to add the option to (Default is current (last added) tab)
* @access public
*/
function AddOptionsFromArray($Options, $TabID = NULL)
{
if (!$TabID) $TabID = $this->CurrentTab;
if (is_array($Options)) {
foreach($Options AS $ID => $Option) {
$Option = new FormOption($ID, $Option);
$this->AddOption($Option, $TabID);
}
}
}
/**
* Add option to tab
*
* This functions adds the option (object) to the list of controls in
* the tab.
*
* @param object $Option Option object
* @param string $TabID ID of the tab to add the option to (Default is current (last added) tab)
* @access public
*/
function AddOption($Option, $TabID = NULL)
{
if (!$TabID) $TabID = $this->CurrentTab;
if (is_object($Option)) {
$this->Options[$TabID][] = $Option;
$RV = TRUE;
} else {
$RV = FALSE;
}
return $RV;
}
/**
* Draw the tab control
*
* This function draws all options on the tab and then the tab itself
* using the widget template.
*
* @param object $TemplateHandler Widget template object.
* @param bool $SplitValues TRUE or FALSE.
* @access public
*/
function Draw(&$TemplateHandler, $SplitValues = FALSE)
{
$TabOptions = array();
foreach ($this->Tabs AS $ID => $TabName) {
// draw controls on tab template
if ($this->Options[$ID]) {
foreach($this->Options[$ID] AS $Option) {
$Option->Name = $Option->Name;
if (count($this->Custom)) {
// Add custom values from Form to widgets
foreach($this->Custom AS $id => $custom) {
if (!isset($Option->Custom[$id])) $Option->AddCustom($id, $custom);
}
}
$TabOptions[$ID][] = $Option->Draw($TemplateHandler, $SplitValues);
}
}
}
$TemplateHandler->ClearAll();
$TemplateHandler->assign("WidgetType", "TAB");
$TemplateHandler->assign("Name", $this->Name);
$TemplateHandler->assign("Id", $this->ID);
$TemplateHandler->assign("NewWay", $this->NewWay);
$TemplateHandler->assign("Tabs", $this->Tabs);
reset($this->Tabs);
if (!isset($this->SelectedTab) || !strlen($this->SelectedTab)) $this->SelectedTab = key($this->Tabs);
$TemplateHandler->assign("TabStyles", $this->TabStyles);
$TemplateHandler->assign("TabOnClick", $this->TabOnClick);
$TemplateHandler->assign("SelectedTab", $this->SelectedTab);
$TemplateHandler->assign("Actions", $this->Actions);
$TemplateHandler->assign("TabActions", $this->TabActions);
$TemplateHandler->assign("Controls", $TabOptions);
if (count($this->Custom)) $TemplateHandler->Assign("Custom", $this->Custom);
return array(
"WidgetType" => "TAB",
"Lable" => $this->Lable,
"Name" => $this->Name,
"Id" => $this->ID,
"Controls" => $TemplateHandler->fetch(NITRO_DEFAULT_WIDGETTEMPLATE)
);
}
/**
* DrawXML
*
* Draws the values in XML.
*
* @param array $ResponseXML The ResponseXML array.
* @access public
*/
function DrawXML(&$ResponseXML)
{
if (is_array($ResponseXML)) {
if (is_array($this->Tabs)) {
foreach ($this->Tabs AS $ID => $TabName) {
if ($this->Options[$ID]) {
foreach($this->Options[$ID] AS $Option) {
$Option->Name = $Option->Name;
if (count($this->Custom)) {
// Add custom values from Form to widgets
foreach($this->Custom AS $id => $custom) {
if (!isset($Option->Custom[$id])) $Option->AddCustom($id, $custom);
}
}
$Option->DrawXML($ResponseXML);
}
}
}
}
}
}
}
function Nitro_Editor($Name, $Rows = 8, $Cols = 40, $Content = '', $WidgetAutoSubmit = FALSE)
{
global $__NitroConf;
$Return = "";
$Height = (((int)$Rows>0) ? ((int)$Rows)*16 : '384');
$Width = (((int)$Cols>0) ? ((int)$Cols)*16 : '800');
if ($__NitroConf->CONF['Settings']['HTMLEditor'] != "") {
if ($__NitroConf->CONF['Settings']['HTMLEditorInclude'] != "") {
include_once $__NitroConf->CONF['Settings']['HTMLEditorInclude'];
}
if ($__NitroConf->CONF['Settings']['HTMLEditorInit'] != "") {
eval('$Return.= '.$__NitroConf->CONF['Settings']['HTMLEditorInit'].';');
}
} else {
$Return = "<TEXTAREA NAME=\"$Name\" ID=\"$Name\" ROWS=\"".($Rows ? $Rows : 10)."\" COLS=\"".($Cols ? $Cols : 50)."\"".(($WidgetAutoSubmit) ? 'onChange="this.form.submit();"' : '').">$Content</TEXTAREA>";
}
return $Return;
}
?>