- <?php
- /*
- * Lokorin.com
- * Copyright 2004-2006
- * Licensed under the GNU LGPL. See COPYING for full terms.
- */
- /**
- * A library for creating and using forms.
- * @author Andreas Launila
- * @version $Revision: 1.16 $
- * @package com.lokorin.lokorin.lib
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
- */
-
- /**
- * For access to common constants and functions.
- */
- require_once('common.php');
- CssHandler::getInstance()->includeCss('forms');
-
- /**
- * Meant as an interface for validatable objects.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- interface Validatable {
- /**
- * Checks if the object's state is valid or not.
- * @return boolean True if the object's state is valid, false otherwise.
- */
- public function isValid();
-
- /**
- * Returns the reason for an object is not in a valid state. This assumes
- * that the isValid() function returns false (so check that first).
- * @return string An error message.
- */
- public function getError();
- }
-
- /**
- * Describes a field in a form.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- abstract class Field implements Validatable {
- /**
- * The name of the field.
- * @var string
- */
- private $name;
- /**
- * If the field has to be entered to be valid.
- * @var boolean
- */
- private $required;
- /**
- * The value of the field.
- * @var string
- */
- private $value;
- /**
- * The unique identifier for the field.
- * @var integer
- */
- private $id;
- /**
- * Any additional attributes where the key is the attribute name and the
- * value is the the attribute value.
- * @var array
- */
- private $attributes;
- /**
- * True if the current value was entered by a user, false otherwise.
- * @var boolean
- */
- private $hasUserValue;
-
- /**
- * Constructor for Field.
- * @param string $name The name of the field.
- * @param boolean $required True if the field has to contain something to be valid,
- * false otherwise. False by default.
- */
- public function __construct($name, $required = false) {
- $this->name = $name;
- $this->required = $required;
- $this->attributes = array("name" => $name);
- $this->hasUserValue = false;
-
- //Check if there is a value for the field, if so then give the
- //field that value.
- if(isset($_REQUEST[$name])) {
- $this->setValue($_REQUEST[$name]);
- $this->hasUserValue = true;
- }
- }
-
- /**
- * Gets the name of the field.
- * @return string A field name.
- */
- public function getName() {
- return $this->name;
- }
-
- /**
- * Gets the value of the field.
- * @return string A field value.
- */
- public function getValue() {
- return $this->value;
- }
-
- /**
- * Sets the value of the field.
- * @param mixed $newValue The new value for the field.
- */
- public function setValue($newValue) {
- $this->value = $newValue;
- $this->attributes["value"] = $this->value;
- $this->hasUserValue = false;
- }
-
- /**
- * Returns the (X)HTML representation of the field. This function should
- * be concidered as an abstract function, any subclasses should override
- * this.
- * @return string An field in HTML.
- */
- public abstract function getAsHtml();
-
- /**
- * Gets the field's id.
- * @return string An field id.
- */
- public function getId() {
- return $this->id;
- }
-
- /**
- * Sets the field's id.
- * @param string $newId The id to be used by the field.
- */
- public function setId($newId) {
- $this->id = $newId;
- $this->attributes["id"] = $newId;
- }
-
- /**
- * Gets the (X)HTML information containing all base information.
- * @return string A bunch of attributes.
- */
- protected function getAttributes() {
- $attributes = "";
- foreach($this->attributes as $name => $value) {
- $attributes .= htmlspecialchars($name).'="'.
- htmlspecialchars($value).'" ';
- }
- return $attributes;
- }
-
- /**
- * @see Validatable.isValid()
- */
- public function isValid() {
- return ($this->required === false) || $this->hasValue();
- }
-
- /**
- * @see Validatable.getError()
- */
- public function getError() {
- return 'This field requires a value to be entered.';
- }
-
- /**
- * Sets one of the firleds attributes. If the attribute does not exist
- * then it is created. The attributes 'id', 'name' and 'value' can not be
- * modified throught this function.
- * @param string $name The name of the attribute.
- * @param string $value The value that the attribute should have.
- */
- public function setAttribute($name, $value) {
- $this->attributes[$name] = $value;
- }
-
- /**
- * Checks if the field has a non empty value.
- * @return boolean True if the field has a non empty value, false
- * otherwise.
- */
- public function hasValue() {
- return $this->value != '';
- }
-
- /**
- * Checks if the field has a non empty value that has been supplied by
- * a user.
- * @return boolean True if the field has a non empty value supplied by
- * the user, false otherwise.
- */
- public function hasUserValue() {
- return $this->hasUserValue;
- }
-
- /**
- * Formats any additional data that should be appended to the field. Any
- * '%id' entities in the formatted string are replaced with the field's
- * id. Any '%name' entities in the formatted string are replaced with the
- * field's name.
- * @param $additionToFormat The addition that should be formatted.
- * @return mixed The formatted addition, the function may return it intact,
- * modified or fully removed if it wished. The only guarantee is that
- * there will be no '%id' or '%name' entities in the result.
- */
- public function formatAddition($additionToFormat) {
- return str_replace('%name', $this->name,
- str_replace('%id', $this->id, $additionToFormat));
- }
-
- /**
- * Clears the field, making it so that it appears to never have received a
- * value.
- */
- public function clear() {
- $this->value = '';
- unset($this->attributes["value"]);
- }
- }
-
- /**
- * Describes a hidden field.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class Hidden extends Field {
- /**
- * Constructor for Hidden.
- * @param string $name The name of the hidden field.
- * @param string $value The value of the hidden field (nothing by default).
- */
- public function __construct($name, $value = '') {
- parent::__construct($name, false);
- if(strlen($value) != 0) {
- $this->setValue($value);
- }
- }
-
- /**
- * @see Field.getAsHtml()
- */
- public function getAsHtml() {
- return sprintf('<input type="hidden" class="hidden" %s/>',
- $this->getAttributes());
- }
-
- /**
- * @see Field.hasUserValue()
- */
- public function hasUserValue() {
- //This can not be set by users.
- return false;
- }
- }
-
- /**
- * Describes a field that is read only. I.e. just prints the contents of it,
- * not really a field, but it's useful at times.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class ReadOnly extends Field {
- /**
- * A callback that the value should be processed through before being
- * displayed. An empty string means that there is no callback.
- * @var callback
- */
- private $callback;
-
- /**
- * Constructor for ReadOnly.
- * @param string $name The name of the read only field.
- * @param string $value The value to display.
- * @param callback $formatCallback A callback that should be applied to
- * the value before displaying it. The callback should take one
- * argument, the value, and return the string that should be displayed
- * instead of the value.
- */
- public function __construct($name, $value = '', $formatCallback = '') {
- parent::__construct($name, false);
- $this->setValue($value);
- $this->callback = $formatCallback;
- }
-
- /**
- * @see Field.getAsHtml()
- */
- public function getAsHtml() {
- $value = $this->getValue();
- if($this->callback != '') {
- $callback = $this->callback;
- $value = $callback($value);
- }
- return '<p>'.$value.'</p>';
- }
- }
-
- /**
- * Describes a checkbox.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class Checkbox extends Field {
- /**
- * Constructor for Checkbox.
- * @param string $name The name of the checkbox.
- */
- public function __construct($name) {
- parent::__construct($name, false);
- }
-
- /**
- * @see Field.getAsHtml()
- */
- public function getAsHtml() {
- $filler = $this->getAttributes();
- if(strpos($filler, "value") !== false) {
- $filler = preg_replace("/value=\".*?\"/", $filler, 'checked="checked"');
- }
- return sprintf('<input type="checkbox" %s/>', $filler);
- }
- }
-
- /**
- * Describes a button.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class Button extends Field {
- /**
- * Constructor for Button.
- * @param string $name The name of the button.
- * @param string $value The value to displayed as the button's text.
- */
- public function __construct($name, $value = '') {
- parent::__construct($name, false);
- $this->setValue($value);
- }
-
- /**
- * @see Field.getAsHtml()
- */
- public function getAsHtml() {
- return sprintf('<input type="button" %s/>', $this->getAttributes());
- }
-
- /**
- * @see Field.clear()
- */
- public function clear() {
- //A button can not be cleared.
- }
- }
-
- /**
- * Describes a submit button.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class SubmitButton extends Field {
- /**
- * Constructor for SubmitButton.
- * @param string $name The name of the button.
- * @param string $value The value to displayed as the button's text.
- */
- public function __construct($name, $value = '') {
- parent::__construct($name, false);
- $this->setValue($value);
- }
-
- /**
- * @see Field.getAsHtml()
- */
- public function getAsHtml() {
- return sprintf('<input class="submitButton" type="submit" %s/>', $this->getAttributes());
- }
-
- /**
- * @see Field.hasUserValue()
- */
- public function hasUserValue() {
- //This never has any user value.
- return false;
- }
-
- /**
- * @see Field.clear()
- */
- public function clear() {
- //A button can not be cleared.
- }
- }
-
- /**
- * Describes a reset button.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class ResetButton extends Field {
- /**
- * Constructor for ResetButton.
- * @param string $name The name of the button.
- * @param string $value The value to displayed as the button's text.
- */
- public function __construct($name, $value = '') {
- parent::Field($name, false);
- $this->setValue($value);
- }
-
- /**
- * @see field.getAsHtml()
- */
- public function getAsHtml() {
- return sprintf('<input type="reset" %s/>', $this->getAttributes());
- }
-
- /**
- * @see Field.clear()
- */
- public function clear() {
- //A button can not be cleared.
- }
- }
-
- /**
- * Describes a field that can be sized.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- abstract class SizedField extends Field {
- /**
- * The height of the field, 0 means that no height has been set.
- * @var integer
- */
- private $height;
- /**
- * The width of the field, 0 means that no width has been set.
- * @var integer
- */
- private $width;
-
- /**
- * Constructor for SizedField.
- * @param string $name The name of the SizedField.
- * @param boolean $required True if the field has to contain something to be valid,
- * false otherwise. False by default.
- */
- public function __construct($name, $required = false) {
- parent::__construct($name, $required);
- }
-
- /**
- * Sets the height of the field.
- * @param integer $new_height The new height.
- */
- public function setHeight($new_height) {
- $this->height = $new_height;
- }
-
- /**
- * Sets the width of the field.
- * @param integer $new_width The new width.
- */
- public function setWidth($new_width) {
- $this->width = $new_width;
- }
-
- /**
- * Gets the height of the field.
- * @return integer A field height.
- */
- public function getHeight() {
- return $this->height;
- }
-
- /**
- * Gets the width of the field.
- * @return integer A field width.
- */
- public function getWidth() {
- return $this->width;
- }
-
- /**
- * @see field.getAttributes()
- */
- protected function getAttributes() {
- $filler = parent::getAttributes();
- if($this->width != 0) {
- $filler .= 'width="'.$this->width.'" ';
- }
- if($this->height != 0) {
- $filler .= 'height="'.$this->height.'" ';
- }
- return $filler;
- }
- }
-
- /**
- * Describes a textfield.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class TextField extends SizedField {
- /**
- * Constructor for TextField.
- * @param string $name The name of the SizedField.
- * @param boolean $required True if the field has to contain something to be valid,
- * false otherwise. False by default.
- */
- public function __construct($name, $required = false) {
- parent::__construct($name, $required);
- }
-
- /**
- * @see field.getAsHtml()
- */
- public function getAsHtml() {
- //To fix a mistake.
- $this->setHeight(0);
- $attributes = preg_replace('/width="(.*?)"/', 'size="$1"', $this->getAttributes());
- return sprintf('<input type="text" %s/>', $attributes);
- }
- }
-
- /**
- * Describes a password field.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class PasswordField extends SizedField {
- /**
- * Constructor for PasswordField.
- * @param string $name The name of the SizedField.
- * @param boolean $required True if the field has to contain something to be valid,
- * false otherwise. False by default.
- */
- public function __construct($name, $required = false) {
- parent::__construct($name, $required);
- }
-
- /**
- * @see field.getAsHtml()
- */
- public function getAsHtml() {
- return sprintf('<input type="password" %s/>', $this->getAttributes());
- }
- }
-
- /**
- * Describes a textarea.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class TextArea extends SizedField {
- /**
- * Constructor for TextArea.
- * @param string $name The name of the SizedField.
- * @param boolean $required True if the field has to contain something to
- * be valid, false otherwise. False by default.
- * @param integer $rows The number of rows that the textarea should have
- * (default is 20).
- * @param integer $cols The number of columns that the textarea should
- * have (default is 30).
- */
- public function __construct($name, $required = false, $rows = 10, $cols = 40) {
- parent::__construct($name, $required);
- $this->setHeight($rows);
- $this->setWidth($cols);
- }
-
- /**
- * @see field.getAsHtml()
- */
- public function getAsHtml() {
- $filler = '';
- if($this->getWidth() != 0) {
- $filler .= 'cols="'.$this->getWidth().'" ';
- }
- if($this->getHeight() != 0) {
- $filler .= 'rows="'.$this->getHeight().'" ';
- }
- if(strlen($this->getId()) > 0) {
- $filler .= 'id="'.$this->getId().'" ';
- }
- return sprintf('<textarea name="%s" %s>%s</textarea>', $this->getName(),
- $filler, htmlspecialchars($this->getValue()));
- }
- }
-
- /**
- * Describes a select field.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class Select extends Field {
- /**
- * The options that should be displayed in the select element. The
- * value as key and the name of the option as value.
- * @var array
- */
- private $options;
-
- /**
- * Constructor for Select.
- * @param string $name The name of the Select field.
- * @param array $options The options to be used. To be given as option value as key and
- * name as value.
- */
- public function __construct($name, $options) {
- parent::__construct($name, false);
- $this->options = $options;
- }
-
- /**
- * @see field.getAsHtml()
- */
- public function getAsHtml() {
- //Build the options and select the current value.
- $options = '';
- foreach($this->options as $value => $name) {
- $options .= '<option value="'.$value.'">'.$name.'</option>'."\n";
- }
- if($this->getValue() != '') {
- $options = preg_replace('/(value="'.$this->getValue().'")/','$1 selected="selected"',$options);
- }
-
- $attributes = preg_replace('/value="[^"]*"/', "", $this->getAttributes());
- return sprintf('<select %s>%s</select><br />', $attributes, $options);
- }
- }
-
- /**
- * Describes a field (or rather group of fields) that allows the user to
- * select a specific date by selecting year, month and day.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class DateField extends Field {
- /**
- * The year selection field.
- * @var Select
- */
- protected $year;
- /**
- * The month selection field.
- * @var Select
- */
- protected $month;
- /**
- * The date selection field.
- * @var TextField
- */
- protected $day;
- /**
- * The lowest unix timestamp that the user should allow to select.
- * @var integer
- */
- protected $timeMin;
- /**
- * The highest unix timestamp that the user should allow to select.
- * @var integer
- */
- protected $timeMax;
- /**
- * The value that should be displayed as legend for the fieldset.
- * @var string
- */
- protected $legend;
- /**
- * The initial value (unix timestamp) that should be used for the field.
- * $var integer
- */
- private $initialValue;
-
- /**
- * Constructor for DateField.
- * @param string $name The name identifier of the date field.
- * @param string $displayName The name that should be displayed to the
- * user.
- * @param integer $timeMin The lowest unix timestamp that the date field
- * should allow the user to select.
- * @param integer $timeMax The highest unix timestamp that the date field
- * should allow the user to select.
- * @param integer $initialValue The unix timestamp that should be
- * displayed initially.
- * @access public
- */
- public function __construct($name, $displayName, $timeMin = 0,
- $timeMax = 2000000000, $initialValue = 0) {
- parent::__construct($name, false);
-
- //Perform a basic sanity check.
- if($timeMin > $timeMax) {
- //Exchange the values, they are in the wrong order.
- $tmp = $timeMax;
- $timeMax = $timeMin;
- $timeMin = $timeMax;
- }
-
- $this->timeMin = $timeMin;
- $this->timeMax = $timeMax;
- $this->legend = $displayName;
-
- //Set up the fields.
- /*
- * Year
- */
- $yearMin = date('Y', $timeMin);
- $yearMax = date('Y', $timeMax);
- //Create and add the year selection.
- $years = array();
- for($i = $yearMin; $i<=$yearMax; $i++) {
- $years[$i] = $i;
- }
- $this->year = new Select($name.'_year', $years);
-
- /*
- * Month
- */
- $months = array(
- 1 => 'January',
- 2 => 'February',
- 3 => 'March',
- 4 => 'April',
- 5 => 'May',
- 6 => 'June',
- 7 => 'July',
- 8 => 'August',
- 9 => 'September',
- 10 => 'October',
- 11 => 'November',
- 12 => 'December'
- );
- $this->month = new Select($name.'_month', $months);
-
- /*
- * Day
- */
- $day = new TextField($name.'_day');
- $day->setWidth(5);
- $this->day = $day;
-
- $day = $this->day;
- $month = $this->month;
- $year = $this->year;
-
- if($this->hasUserValue()) {
- //Dirty hack to make this compatible with lib_search.
- $_REQUEST[$name] = $this->getValue();
- } else {
- $this->setValue($initialValue);
- $this->initialValue = $this->getValue();
- }
- }
-
- /**
- * @see Field.getValue()
- */
- public function getValue() {
- //Retrieve the represented unix timestamp.
- $day = $this->day;
- $month = $this->month;
- $year = $this->year;
- $time = mktime(0, 0, 0, $month->getValue(), $day->getValue(),
- $year->getValue());
-
- //Make sure it's within the permitted interval.
- if($time < $this->timeMin) {
- $time = $this->timeMin;
- }
- if($time > $this->timeMax) {
- $time = $this->timeMax;
- }
- $this->value = $time;
- return $time;
- }
-
- /**
- * @see Field.setValue(mixed)
- */
- public function setValue($newValue) {
- $this->day->setValue(date('j', $newValue));
- $this->month->setValue(date('n', $newValue));
- $this->year->setValue(date('Y', $newValue));
- }
-
- /**
- * @see Field.getAsHtml()
- */
- public function getAsHTML() {
- $day = $this->day;
- $month = $this->month;
- $year = $this->year;
-
- $output = '<fieldset><legend>'.$this->legend.'</legend>';
- $output .= '<label for="'.$year->getName().'">Year</label>';
- $output .= $year->getAsHTML();
- $output .= '<label for="'.$month->getName().'">Month</label>';
- $output .= $month->getAsHTML();
- $output .= '<label for="'.$day->getName().'">Day</label>';
- $output .= $day->getAsHTML();
- $output .= '</fieldset><br />';
- return $output;
- }
-
- /**
- * @see Field.hasValue()
- */
- public function hasValue() {
- return $this->initialValue != $this->getValue();
- }
-
- /**
- * @see Field.hasUserValue()
- */
- public function hasUserValue() {
- return $this->day->hasUserValue() || $this->month->hasUserValue() ||
- $this->year->hasUserValue();
- }
-
- /**
- * No additions are allowed.
- * @see Field.formatAddition()
- */
- public function formatAddition($addition) {
- return '';
- }
- }
-
- /**
- * Describes a field (or rather a group of fields) that allows the user to
- * select a certain timestamp (year, month, day, hour, minute and second).
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class TimeField extends DateField {
- /**
- * The hour selection field.
- * @var TextField
- */
- private $hour;
- /**
- * The minute selection field.
- * @var TextField
- */
- private $minute;
- /**
- * The second selection field.
- * @var TextField
- */
- private $second;
-
- /**
- * Constructor for TimeField.
- * @param string $name The name identifier of the date field.
- * @param string $displayName The name that should be displayed to the
- * user.
- * @param integer $timeMin The lowest unix timestamp that the date field
- * should allow the user to select.
- * @param integer $timeMax The highest unix timestamp that the date field
- * should allow the user to select.
- * @param integer $initialValue The unix timestamp that should be
- * displayed initially.
- */
- public function __construct($name, $displayName, $timeMin = 0,
- $timeMax = 2000000000, $initialValue = 0) {
- //Set up the fields.
- /*
- * Hour
- */
- $this->hour = new TextField($name.'_hour');
- $this->hour->setWidth(4);
-
- /*
- * Minute
- */
- $this->minute = new TextField($name.'_minute');
- $this->minute->setWidth(4);
-
- /*
- * Second
- */
- $this->second = new TextField($name.'_second');
- $this->second->setWidth(4);
-
- parent::__construct($name, $displayName, $timeMin, $timeMax, $initialValue);
- }
-
- /**
- * @see Field.hasUserValue()
- */
- public function hasUserValue() {
- return parent::hasUserValue() || $this->hour->hasUserValue() ||
- $this->minute->hasUserValue() || $this->second->hasUserValue();
- }
-
- /**
- * @see Field.getValue()
- */
- public function getValue() {
- //Retrieve the represented unix timestamp.
- $time = mktime(
- $this->hour->getValue(),
- $this->minute->getValue(),
- $this->second->getValue(),
- parent::$this->month->getValue(),
- parent::$this->day->getValue(),
- parent::$this->year->getValue()
- );
-
- //Make sure it's within the permitted interval.
- if($time < parent::$this->timeMin) {
- $time = $this->timeMin;
- }
- if($time > parent::$this->timeMax) {
- $time = $this->timeMax;
- }
- $this->value = $time;
- return $time;
- }
-
- /**
- * @see Field.setValue()
- */
- public function setValue($newValue) {
- parent::setValue($newValue);
- $this->hour->setValue(date('G', $newValue));
- $this->minute->setValue(date('i', $newValue));
- $this->second->setValue(date('s', $newValue));
- }
-
- /**
- * @see Field.getAsHtml()
- */
- public function getAsHTML() {
- $output = '<fieldset><legend>'.parent::$this->legend.'</legend>';
- $output .= '<label for="'.$this->year->getName().'">Year</label>';
- $output .= $this->year->getAsHTML();
- $output .= '<label for="'.$this->month->getName().'">Month</label>';
- $output .= $this->month->getAsHTML();
- $output .= '<label for="'.$this->day->getName().'">Day</label>';
- $output .= $this->day->getAsHTML();
- $output .= '<label for="'.$this->hour->getName().'">Hour</label>';
- $output .= $this->hour->getAsHTML();
- $output .= '<label for="'.$this->minute->getName().'">Minute</label>';
- $output .= $this->minute->getAsHTML();
- $output .= '<label for="'.$this->second->getName().'">Second</label>';
- $output .= $this->second->getAsHTML();
- $output .= '</fieldset><br />';
- return $output;
- }
- }
-
- /**
- * Describes a file field.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class Browse extends SizedField {
- /**
- * Constructor for Browse.
- * @param boolean $required True if the field has to contain something to
- * be valid, false otherwise. False by default.
- */
- public function __construct($name, $required = false) {
- parent::__construct($name, $required);
- $this->setValue('');
- }
-
- /**
- * @see field.getAsHtml()
- */
- public function getAsHtml() {
- return sprintf('<input type="file" %s/>', $this->getAttributes());
- }
- }
-
- /**
- * Describes an form.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class Form implements Validatable {
- /**
- * Contains arrays describing contained fields with two keys each:
- * (Field)field: The actual field.
- * (string)displayName: The name to be displayed for the field.
- * @var array
- */
- private $fields;
- /**
- * The action to be used by the form.
- * @var string
- */
- private $action;
- /**
- * The method to be used by the form.
- * @var string
- */
- private $method;
- /**
- * The legend value that should be used for the form.
- * @var string
- */
- private $legend;
- /**
- * The encoding type to use for the form.
- * @var string
- */
- private $encType;
- /**
- * If errors should be displayed or not (true by default).
- * @var boolean
- */
- private $displayErrors;
- /**
- * The css class to be used by the form element.
- * @var string
- */
- private $cssClass;
-
- /**
- * Constructor for Form.
- * @param string $legend The legends that should be used for the form,
- * none by default.
- * @param string $method The method to be used bt the form (post by
- * default).
- * @param string $action The action to be used by the form. By default the
- * action is set to the requested uri.
- * @param string $encType The encoding type that should be used for the
- * form.
- */
- public function __construct($legend = '', $method = 'post', $action = '', $encType = '') {
- if($action == '') {
- $action = SELF;
- }
- $this->action = $action;
- $this->method = $method;
- $this->legend = $legend;
- $this->encType = $encType;
- $this->displayErrors = true;
- }
-
- /**
- * Adds a new field to the form.
- * @param field $field The actual field.
- * @param string $displayName The name that should be shown to the user. If
- * nothing specified then nothing is shown to the user.
- */
- public function addField($field, $displayName = '') {
- //Add the field.
- $this->fields[] = array(
- 'displayName' => $displayName,
- 'field' => $field);
- }
-
- /**
- * Adds multiple fields to the form.
- * @param array $fields An array with key being the display name and value
- * being the associated field.
- */
- public function addFields($fields) {
- foreach($fields as $dispName => $field) {
- $this->addField($field, $dispName);
- }
- }
-
- /**
- * Gets the (X)HTML representation of the form.
- * @return string A form.
- */
- public function getForm() {
- $form = '<form action="'.$this->action.'" method="'.$this->method.'"';
- if(strlen($this->cssClass) != 0) {
- $form .= ' class="'.$this->cssClass.'"';
- }
- if(strlen($this->encType) != 0) {
- $form .= ' enctype="'.$this->encType.'"';
- }
- $form .= '><fieldset>'."\n";
- if(strlen($this->legend) != 0) {
- $form .= '<legend>'.$this->legend.'</legend>';
- }
-
- foreach($this->fields as $field) {
- //Should we add an label?
- if(strlen($field['displayName']) != 0) {
- //Add a label for the field.
- $id = $field['field']->getId();
- if(strlen($id) == 0) {
- //We have to define an id for the field, use the name.
- $id = $field['field']->getName();
- $field['field']->setId($id);
- }
- $form .= $field['field']->formatAddition('<label for="%id">'.
- $field['displayName'].'</label>'."\n");
- }
-
- if($this->displayErrors && $this->hasAnyUserValue()) {
- //Check if there is an error.
- if(!$field['field']->isValid()) {
- //Add the error message
- $form .= '<span class="error">'.$field['field']->getError().'</span>';
- }
- }
-
- //Add the field itself
- $form .= $field['field']->getAsHtml()."\n";
- if(is_subclass_of($field['field'], 'SizedField')) {
- $form .= '<br />';
- }
- }
-
- $form .= '</fieldset></form>';
- return $form;
- }
-
- /**
- * @see Validatable.isValid()
- */
- public function isValid() {
- foreach($this->fields as $field) {
- if(!$field['field']->isValid()) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * @see Validatable.getError()
- */
- public function getError() {
- return 'The form is not correctly filled out.';
- }
-
- /**
- * Gets the field instance corresponding to the given (field) name.
- * @param string $name The name of the field to search for.
- * @return Field The requested field (if one is found), false otherwise.
- */
- public function getField($name) {
- foreach($this->fields as $field) {
- if($field['field']->getName() == $name) {
- return $field['field'];
- }
- }
- return false;
- }
-
- /**
- * Gets the value of one of the form's fields.
- * @param string $fieldName The name of the field to get the value for.
- * @return mixed The value of the field (if the field was found), an
- * empty string otherwise.
- */
- public function getValue($fieldName) {
- $field = $this->getField($fieldName);
- if($field === false) {
- return '';
- } else {
- return $field->getValue();
- }
- }
-
- /**
- * Checks if the form has a field with the specified name and if that
- * field has a non empty value.
- * @param string $fieldName The name of the field to check.
- * @return boolean True if the field exists and has a non empty value,
- * false otherwise.
- */
- public function hasValue($fieldName) {
- $field = $this->getField($fieldName);
- if($field === false) {
- return false;
- }
- return $field->hasValue();
- }
-
- /**
- * Sets a specified field's value to a new specified value.
- * @param string $fieldName The name of the field which's value should be
- * set.
- * @param mixed $newValue The new value that should be used.
- */
- public function setValue($fieldName, $newValue) {
- $this->getField($fieldName)->setValue($newValue);
- }
-
- /**
- * Removes all recorded field values from the form.
- */
- public function clear() {
- foreach($this->fields as $field) {
- $field['field']->clear();
- }
- }
-
- /**
- * Sets if the form should display errors or not (the default is true).
- * @param boolean $newVal True if errors should be displayed, false
- * otherwise.
- */
- public function setDisplayErrors($newVal) {
- $this->displayErrors = $newVal;
- }
-
- /**
- * Sets the css class to be used by the form element.
- * @param string $newCssClass The new css class name to use.
- */
- public function setCssClass($newCssClass) {
- $this->cssClass = $newCssClass;
- }
-
- /**
- * Removes the first field encountered with the specified field name.
- * @param string $fieldName The name of the field that should be removed.
- */
- public function removeField($fieldName) {
- foreach($this->fields as $key => $field) {
- if($field['field']->getName() == $fieldName) {
- unset($this->fields[$key]);
- return;
- }
- }
- }
-
- /**
- * Checks if any of the form's fields has any user set values.
- * @return boolean True if at least a field has a non empty value that
- * has been set by a user, false otherwise.
- */
- public function hasAnyUserValue() {
- foreach($this->fields as $field) {
- if($field['field']->hasUserValue()) {
- return true;
- }
- }
- return false;
- }
- }
-
- ?>