Document and tidy HTMLForm.php. :P
This commit is contained in:
parent
7f3929a02a
commit
7732401c9b
1 changed files with 323 additions and 71 deletions
|
|
@ -1,16 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Object handling generic submission, CSRF protection, layout and
|
||||
* other logic for UI forms. in a reusable manner.
|
||||
*
|
||||
* In order to generate the form, the HTMLForm object takes an array
|
||||
* structure detailing the form fields available. Each element of the
|
||||
* array is a basic property-list, including the type of field, the
|
||||
* label it is to be given in the form, callbacks for validation and
|
||||
* 'filtering', and other pertinent information.
|
||||
*
|
||||
* Field types are implemented as subclasses of the generic HTMLFormField
|
||||
* object, and typically implement at least getInputHTML, which generates
|
||||
* the HTML for the input field to be placed in the table.
|
||||
*
|
||||
* The constructor input is an associative array of $fieldname => $info,
|
||||
* where $info is an Associative Array with any of the following:
|
||||
*
|
||||
* 'class' -- the subclass of HTMLFormField that will be used
|
||||
* to create the object. *NOT* the CSS class!
|
||||
* 'type' -- roughly translates into the <select> type attribute.
|
||||
* if 'class' is not specified, this is used as a map
|
||||
* through HTMLForm::$typeMappings to get the class name.
|
||||
* 'default' -- default value when the form is displayed
|
||||
* 'id' -- HTML id attribute
|
||||
* 'options' -- varies according to the specific object.
|
||||
* 'label-message' -- message key for a message to use as the label.
|
||||
* can be an array of msg key and then parameters to
|
||||
* the message.
|
||||
* 'label' -- alternatively, a raw text message. Overridden by
|
||||
* label-message
|
||||
* 'help-message' -- message key for a message to use as a help text.
|
||||
* can be an array of msg key and then parameters to
|
||||
* the message.
|
||||
* 'required' -- passed through to the object, indicating that it
|
||||
* is a required field.
|
||||
* 'size' -- the length of text fields
|
||||
* 'filter-callback -- a function name to give you the chance to
|
||||
* massage the inputted value before it's processed.
|
||||
* @see HTMLForm::filter()
|
||||
* 'validation-callback' -- a function name to give you the chance
|
||||
* to impose extra validation on the field input.
|
||||
* @see HTMLForm::validate()
|
||||
*
|
||||
* TODO: Document 'section' / 'subsection' stuff
|
||||
*/
|
||||
class HTMLForm {
|
||||
static $jsAdded = false;
|
||||
|
||||
/* The descriptor is an array of arrays.
|
||||
i.e. array(
|
||||
'fieldname' => array( 'section' => 'section/subsection',
|
||||
properties... ),
|
||||
...
|
||||
)
|
||||
*/
|
||||
|
||||
# A mapping of 'type' inputs onto standard HTMLFormField subclasses
|
||||
static $typeMappings = array(
|
||||
'text' => 'HTMLTextField',
|
||||
'select' => 'HTMLSelectField',
|
||||
|
|
@ -28,8 +66,25 @@ class HTMLForm {
|
|||
'email' => 'HTMLTextField',
|
||||
'password' => 'HTMLTextField',
|
||||
);
|
||||
|
||||
protected $mMessagePrefix;
|
||||
protected $mFlatFields;
|
||||
protected $mFieldTree;
|
||||
protected $mShowReset;
|
||||
public $mFieldData;
|
||||
protected $mSubmitCallback;
|
||||
protected $mValidationErrorMessage;
|
||||
protected $mIntro;
|
||||
protected $mSubmitID;
|
||||
protected $mSubmitText;
|
||||
protected $mTitle;
|
||||
|
||||
function __construct( $descriptor, $messagePrefix ) {
|
||||
/**
|
||||
* Build a new HTMLForm from an array of field attributes
|
||||
* @param $descriptor Array of Field constructs, as described above
|
||||
* @param $messagePrefix String a prefix to go in front of default messages
|
||||
*/
|
||||
public function __construct( $descriptor, $messagePrefix='' ) {
|
||||
$this->mMessagePrefix = $messagePrefix;
|
||||
|
||||
// Expand out into a tree.
|
||||
|
|
@ -43,7 +98,7 @@ class HTMLForm {
|
|||
|
||||
$info['name'] = $fieldname;
|
||||
|
||||
$field = $this->loadInputFromParameters( $info );
|
||||
$field = self::loadInputFromParameters( $info );
|
||||
$field->mParent = $this;
|
||||
|
||||
$setSection =& $loadedDescriptor;
|
||||
|
|
@ -70,6 +125,10 @@ class HTMLForm {
|
|||
$this->mShowReset = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the HTMLForm-specific JavaScript, if it hasn't been
|
||||
* done already.
|
||||
*/
|
||||
static function addJS() {
|
||||
if( self::$jsAdded ) return;
|
||||
|
||||
|
|
@ -78,6 +137,11 @@ class HTMLForm {
|
|||
$wgOut->addScriptClass( 'htmlform' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise a new Object for the field
|
||||
* @param $descriptor input Descriptor, as described above
|
||||
* @return HTMLFormField subclass
|
||||
*/
|
||||
static function loadInputFromParameters( $descriptor ) {
|
||||
if ( isset( $descriptor['class'] ) ) {
|
||||
$class = $descriptor['class'];
|
||||
|
|
@ -95,15 +159,21 @@ class HTMLForm {
|
|||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* The here's-one-I-made-earlier option: do the submission if
|
||||
* posted, or display the form with or without funky valiation
|
||||
* errors
|
||||
* @return Bool whether submission was successful.
|
||||
*/
|
||||
function show() {
|
||||
$html = '';
|
||||
|
||||
self::addJS();
|
||||
|
||||
// Load data from the request.
|
||||
# Load data from the request.
|
||||
$this->loadData();
|
||||
|
||||
// Try a submission
|
||||
# Try a submission
|
||||
global $wgUser, $wgRequest;
|
||||
$editToken = $wgRequest->getVal( 'wpEditToken' );
|
||||
|
||||
|
|
@ -114,23 +184,31 @@ class HTMLForm {
|
|||
if( $result === true )
|
||||
return $result;
|
||||
|
||||
// Display form.
|
||||
# Display form.
|
||||
$this->displayForm( $result );
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Return values:
|
||||
* TRUE == Successful submission
|
||||
* FALSE == No submission attempted
|
||||
* Anything else == Error to display.
|
||||
*/
|
||||
/**
|
||||
* Validate all the fields, and call the submision callback
|
||||
* function if everything is kosher.
|
||||
* @return Mixed Bool true == Successful submission, Bool false
|
||||
* == No submission attempted, anything else == Error to
|
||||
* display.
|
||||
*/
|
||||
function trySubmit() {
|
||||
// Check for validation
|
||||
# Check for validation
|
||||
foreach( $this->mFlatFields as $fieldname => $field ) {
|
||||
if ( !empty( $field->mParams['nodata'] ) ) continue;
|
||||
if ( $field->validate( $this->mFieldData[$fieldname],
|
||||
$this->mFieldData ) !== true ) {
|
||||
return isset( $this->mValidationErrorMessage ) ?
|
||||
$this->mValidationErrorMessage : array( 'htmlform-invalid-input' );
|
||||
if ( !empty( $field->mParams['nodata'] ) )
|
||||
continue;
|
||||
if ( $field->validate(
|
||||
$this->mFieldData[$fieldname],
|
||||
$this->mFieldData )
|
||||
!== true )
|
||||
{
|
||||
return isset( $this->mValidationErrorMessage )
|
||||
? $this->mValidationErrorMessage
|
||||
: array( 'htmlform-invalid-input' );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -143,18 +221,40 @@ class HTMLForm {
|
|||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to a function to do something with the form
|
||||
* once it's been successfully validated.
|
||||
* @param $cb String function name. The function will be passed
|
||||
* the output from HTMLForm::filterDataForSubmit, and must
|
||||
* return Bool true on success, Bool false if no submission
|
||||
* was attempted, or String HTML output to display on error.
|
||||
*/
|
||||
function setSubmitCallback( $cb ) {
|
||||
$this->mSubmitCallback = $cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a message to display on a validation error.
|
||||
* @param $msg Mixed String or Array of valid inputs to wfMsgExt()
|
||||
* (so each entry can be either a String or Array)
|
||||
*/
|
||||
function setValidationErrorMessage( $msg ) {
|
||||
$this->mValidationErrorMessage = $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the introductory message
|
||||
* @param $msg String complete text of message to display
|
||||
*/
|
||||
function setIntro( $msg ) {
|
||||
$this->mIntro = $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the form (sending to wgOut), with an appropriate error
|
||||
* message or stack of messages, and any validation errors, etc.
|
||||
* @param $submitResult Mixed output from HTMLForm::trySubmit()
|
||||
*/
|
||||
function displayForm( $submitResult ) {
|
||||
global $wgOut;
|
||||
|
||||
|
|
@ -179,6 +279,11 @@ class HTMLForm {
|
|||
$wgOut->addHTML( $html );
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the form innards in an actual <form> element
|
||||
* @param $html String HTML contents to wrap.
|
||||
* @return String wrapped HTML.
|
||||
*/
|
||||
function wrapForm( $html ) {
|
||||
return Html::rawElement(
|
||||
'form',
|
||||
|
|
@ -190,6 +295,10 @@ class HTMLForm {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hidden fields that should go inside the form.
|
||||
* @return String HTML.
|
||||
*/
|
||||
function getHiddenFields() {
|
||||
global $wgUser;
|
||||
$html = '';
|
||||
|
|
@ -200,6 +309,10 @@ class HTMLForm {
|
|||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the submit and (potentially) reset buttons.
|
||||
* @return String HTML.
|
||||
*/
|
||||
function getButtons() {
|
||||
$html = '';
|
||||
|
||||
|
|
@ -225,10 +338,17 @@ class HTMLForm {
|
|||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the whole body of the form.
|
||||
*/
|
||||
function getBody() {
|
||||
return $this->displaySection( $this->mFieldTree );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format and display an error message stack.
|
||||
* @param $errors Mixed String or Array of message keys
|
||||
*/
|
||||
function displayErrors( $errors ) {
|
||||
if ( is_array( $errors ) ) {
|
||||
$errorstr = $this->formatErrors( $errors );
|
||||
|
|
@ -242,6 +362,11 @@ class HTMLForm {
|
|||
$wgOut->addHTML( $errorstr );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a stack of error messages into a single HTML string
|
||||
* @param $errors Array of message keys/values
|
||||
* @return String HTML, a <ul> list of errors
|
||||
*/
|
||||
static function formatErrors( $errors ) {
|
||||
$errorstr = '';
|
||||
foreach ( $errors as $error ) {
|
||||
|
|
@ -263,30 +388,62 @@ class HTMLForm {
|
|||
return $errorstr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text for the submit button
|
||||
* @param $t String plaintext.
|
||||
*/
|
||||
function setSubmitText( $t ) {
|
||||
$this->mSubmitText = $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text for the submit button, either customised or a default.
|
||||
* @return unknown_type
|
||||
*/
|
||||
function getSubmitText() {
|
||||
return isset( $this->mSubmitText ) ? $this->mSubmitText : wfMsg( 'htmlform-submit' );
|
||||
return $this->mSubmitText
|
||||
? $this->mSubmitText
|
||||
: wfMsg( 'htmlform-submit' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id for the submit button.
|
||||
* @param $t String. FIXME: Integrity is *not* validated
|
||||
*/
|
||||
function setSubmitID( $t ) {
|
||||
$this->mSubmitID = $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the prefix for various default messages
|
||||
* TODO: currently only used for the <fieldset> legend on forms
|
||||
* with multiple sections; should be used elsewhre?
|
||||
* @param $p String
|
||||
*/
|
||||
function setMessagePrefix( $p ) {
|
||||
$this->mMessagePrefix = $p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title for form submission
|
||||
* @param $t Title of page the form is on/should be posted to
|
||||
*/
|
||||
function setTitle( $t ) {
|
||||
$this->mTitle = $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title
|
||||
* @return Title
|
||||
*/
|
||||
function getTitle() {
|
||||
return $this->mTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Document
|
||||
* @param $fields
|
||||
*/
|
||||
function displaySection( $fields ) {
|
||||
$tableHtml = '';
|
||||
$subsectionHtml = '';
|
||||
|
|
@ -295,8 +452,8 @@ class HTMLForm {
|
|||
foreach( $fields as $key => $value ) {
|
||||
if ( is_object( $value ) ) {
|
||||
$v = empty( $value->mParams['nodata'] )
|
||||
? $this->mFieldData[$key]
|
||||
: $value->getDefault();
|
||||
? $this->mFieldData[$key]
|
||||
: $value->getDefault();
|
||||
$tableHtml .= $value->getTableRow( $v );
|
||||
|
||||
if( $value->getLabel() != ' ' )
|
||||
|
|
@ -319,6 +476,9 @@ class HTMLForm {
|
|||
return $subsectionHtml . "\n" . $tableHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the form fields from the Descriptor array
|
||||
*/
|
||||
function loadData() {
|
||||
global $wgRequest;
|
||||
|
||||
|
|
@ -333,7 +493,7 @@ class HTMLForm {
|
|||
}
|
||||
}
|
||||
|
||||
// Filter data.
|
||||
# Filter data.
|
||||
foreach( $fieldData as $name => &$value ) {
|
||||
$field = $this->mFlatFields[$name];
|
||||
$value = $field->filter( $value, $this->mFlatFields );
|
||||
|
|
@ -342,33 +502,60 @@ class HTMLForm {
|
|||
$this->mFieldData = $fieldData;
|
||||
}
|
||||
|
||||
function importData( $fieldData ) {
|
||||
// Filter data.
|
||||
foreach( $fieldData as $name => &$value ) {
|
||||
$field = $this->mFlatFields[$name];
|
||||
$value = $field->filter( $value, $this->mFlatFields );
|
||||
}
|
||||
|
||||
foreach( $this->mFlatFields as $fieldname => $field ) {
|
||||
if ( !isset( $fieldData[$fieldname] ) )
|
||||
$fieldData[$fieldname] = $field->getDefault();
|
||||
}
|
||||
|
||||
$this->mFieldData = $fieldData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop a reset button being shown for this form
|
||||
* @param $suppressReset Bool set to false to re-enable the
|
||||
* button again
|
||||
*/
|
||||
function suppressReset( $suppressReset = true ) {
|
||||
$this->mShowReset = !$suppressReset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overload this if you want to apply special filtration routines
|
||||
* to the form as a whole, after it's submitted but before it's
|
||||
* processed.
|
||||
* @param $data
|
||||
* @return unknown_type
|
||||
*/
|
||||
function filterDataForSubmit( $data ) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The parent class to generate form fields. Any field type should
|
||||
* be a subclass of this.
|
||||
*/
|
||||
abstract class HTMLFormField {
|
||||
|
||||
protected $mValidationCallback;
|
||||
protected $mFilterCallback;
|
||||
protected $mName;
|
||||
public $mParams;
|
||||
protected $mLabel; # String label. Set on construction
|
||||
protected $mID;
|
||||
protected $mDefault;
|
||||
public $mParent;
|
||||
|
||||
/**
|
||||
* This function must be implemented to return the HTML to generate
|
||||
* the input object itself. It should not implement the surrounding
|
||||
* table cells/rows, or labels/help messages.
|
||||
* @param $value String the value to set the input to; eg a default
|
||||
* text for a text input.
|
||||
* @return String valid HTML.
|
||||
*/
|
||||
abstract function getInputHTML( $value );
|
||||
|
||||
/**
|
||||
* Override this function to add specific validation checks on the
|
||||
* field input. Don't forget to call parent::validate() to ensure
|
||||
* that the user-defined callback mValidationCallback is still run
|
||||
* @param $value String the value the field was submitted with
|
||||
* @param $alldata $all the data collected from the form
|
||||
* @return Bool is the input valid
|
||||
*/
|
||||
function validate( $value, $alldata ) {
|
||||
if ( isset( $this->mValidationCallback ) ) {
|
||||
return call_user_func( $this->mValidationCallback, $value, $alldata );
|
||||
|
|
@ -395,6 +582,12 @@ abstract class HTMLFormField {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value that this input has been set to from a posted form,
|
||||
* or the input's default value if it has not been set.
|
||||
* @param $request WebRequest
|
||||
* @return String the value
|
||||
*/
|
||||
function loadDataFromRequest( $request ) {
|
||||
if( $request->getCheck( $this->mName ) ) {
|
||||
return $request->getText( $this->mName );
|
||||
|
|
@ -403,9 +596,14 @@ abstract class HTMLFormField {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the object
|
||||
* @param $params Associative Array. See HTMLForm doc for syntax.
|
||||
*/
|
||||
function __construct( $params ) {
|
||||
$this->mParams = $params;
|
||||
|
||||
# Generate the label from a message, if possible
|
||||
if( isset( $params['label-message'] ) ) {
|
||||
$msgInfo = $params['label-message'];
|
||||
|
||||
|
|
@ -453,8 +651,14 @@ abstract class HTMLFormField {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the complete table row for the input, including help text,
|
||||
* labels, and whatever.
|
||||
* @param $value String the value to set the input to.
|
||||
* @return String complete HTML table row.
|
||||
*/
|
||||
function getTableRow( $value ) {
|
||||
// Check for invalid data.
|
||||
# Check for invalid data.
|
||||
global $wgRequest;
|
||||
|
||||
$errors = $this->validate( $value, $this->mParent->mFieldData );
|
||||
|
|
@ -517,7 +721,14 @@ abstract class HTMLFormField {
|
|||
}
|
||||
}
|
||||
|
||||
static function flattenOptions( $options ) {
|
||||
/**
|
||||
* flatten an array of options to a single array, for instance,
|
||||
* a set of <options> inside <optgroups>.
|
||||
* @param $options Associative Array with values either Strings
|
||||
* or Arrays
|
||||
* @return Array flattened input
|
||||
*/
|
||||
public static function flattenOptions( $options ) {
|
||||
$flatOpts = array();
|
||||
|
||||
foreach( $options as $key => $value ) {
|
||||
|
|
@ -533,11 +744,11 @@ abstract class HTMLFormField {
|
|||
}
|
||||
|
||||
class HTMLTextField extends HTMLFormField {
|
||||
# Override in derived classes to use other Xml::... functions
|
||||
protected $mFunction = 'input';
|
||||
|
||||
function getSize() {
|
||||
return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 45;
|
||||
return isset( $this->mParams['size'] )
|
||||
? $this->mParams['size']
|
||||
: 45;
|
||||
}
|
||||
|
||||
function getInputHTML( $value ) {
|
||||
|
|
@ -572,21 +783,25 @@ class HTMLTextField extends HTMLFormField {
|
|||
$attribs[$param] = '';
|
||||
}
|
||||
}
|
||||
|
||||
# Implement tiny differences between some field variants
|
||||
# here, rather than creating a new class for each one which
|
||||
# is essentially just a clone of this one.
|
||||
if ( isset( $this->mParams['type'] ) ) {
|
||||
switch ( $this->mParams['type'] ) {
|
||||
case 'email':
|
||||
$attribs['type'] = 'email';
|
||||
break;
|
||||
case 'int':
|
||||
$attribs['type'] = 'number';
|
||||
break;
|
||||
case 'float':
|
||||
$attribs['type'] = 'number';
|
||||
$attribs['step'] = 'any';
|
||||
break;
|
||||
case 'password':
|
||||
$attribs['type'] = 'password';
|
||||
break;
|
||||
case 'email':
|
||||
$attribs['type'] = 'email';
|
||||
break;
|
||||
case 'int':
|
||||
$attribs['type'] = 'number';
|
||||
break;
|
||||
case 'float':
|
||||
$attribs['type'] = 'number';
|
||||
$attribs['step'] = 'any';
|
||||
break;
|
||||
case 'password':
|
||||
$attribs['type'] = 'password';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -595,9 +810,15 @@ class HTMLTextField extends HTMLFormField {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A field that will contain a numeric value
|
||||
*/
|
||||
class HTMLFloatField extends HTMLTextField {
|
||||
|
||||
function getSize() {
|
||||
return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 20;
|
||||
return isset( $this->mParams['size'] )
|
||||
? $this->mParams['size']
|
||||
: 20;
|
||||
}
|
||||
|
||||
function validate( $value, $alldata ) {
|
||||
|
|
@ -611,8 +832,8 @@ class HTMLFloatField extends HTMLTextField {
|
|||
|
||||
$in_range = true;
|
||||
|
||||
# The "int" part of these message names is rather confusing. They make
|
||||
# equal sense for all numbers.
|
||||
# The "int" part of these message names is rather confusing.
|
||||
# They make equal sense for all numbers.
|
||||
if ( isset( $this->mParams['min'] ) ) {
|
||||
$min = $this->mParams['min'];
|
||||
if ( $min > $value )
|
||||
|
|
@ -629,6 +850,9 @@ class HTMLFloatField extends HTMLTextField {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A field that must contain a number
|
||||
*/
|
||||
class HTMLIntField extends HTMLFloatField {
|
||||
function validate( $value, $alldata ) {
|
||||
$p = parent::validate( $value, $alldata );
|
||||
|
|
@ -643,6 +867,9 @@ class HTMLIntField extends HTMLFloatField {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A checkbox field
|
||||
*/
|
||||
class HTMLCheckField extends HTMLFormField {
|
||||
function getInputHTML( $value ) {
|
||||
if ( !empty( $this->mParams['invert'] ) )
|
||||
|
|
@ -657,8 +884,12 @@ class HTMLCheckField extends HTMLFormField {
|
|||
Html::rawElement( 'label', array( 'for' => $this->mID ), $this->mLabel );
|
||||
}
|
||||
|
||||
/**
|
||||
* For a checkbox, the label goes on the right hand side, and is
|
||||
* added in getInputHTML(), rather than HTMLFormField::getRow()
|
||||
*/
|
||||
function getLabel() {
|
||||
return ' '; // In the right-hand column.
|
||||
return ' ';
|
||||
}
|
||||
|
||||
function loadDataFromRequest( $request ) {
|
||||
|
|
@ -682,6 +913,9 @@ class HTMLCheckField extends HTMLFormField {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A select dropdown field. Basically a wrapper for Xmlselect class
|
||||
*/
|
||||
class HTMLSelectField extends HTMLFormField {
|
||||
|
||||
function validate( $value, $alldata ) {
|
||||
|
|
@ -698,9 +932,9 @@ class HTMLSelectField extends HTMLFormField {
|
|||
function getInputHTML( $value ) {
|
||||
$select = new XmlSelect( $this->mName, $this->mID, strval( $value ) );
|
||||
|
||||
// If one of the options' 'name' is int(0), it is automatically selected.
|
||||
// because PHP sucks and things int(0) == 'some string'.
|
||||
// Working around this by forcing all of them to strings.
|
||||
# If one of the options' 'name' is int(0), it is automatically selected.
|
||||
# because PHP sucks and things int(0) == 'some string'.
|
||||
# Working around this by forcing all of them to strings.
|
||||
$options = array_map( 'strval', $this->mParams['options'] );
|
||||
|
||||
if( !empty( $this->mParams['disabled'] ) ) {
|
||||
|
|
@ -713,6 +947,9 @@ class HTMLSelectField extends HTMLFormField {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select dropdown field, with an additional "other" textbox.
|
||||
*/
|
||||
class HTMLSelectOrOtherField extends HTMLTextField {
|
||||
static $jsAdded = false;
|
||||
|
||||
|
|
@ -783,15 +1020,19 @@ class HTMLSelectOrOtherField extends HTMLTextField {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-select field
|
||||
*/
|
||||
class HTMLMultiSelectField extends HTMLFormField {
|
||||
|
||||
function validate( $value, $alldata ) {
|
||||
$p = parent::validate( $value, $alldata );
|
||||
if( $p !== true ) return $p;
|
||||
|
||||
if( !is_array( $value ) ) return false;
|
||||
|
||||
// If all options are valid, array_intersect of the valid options and the provided
|
||||
// options will return the provided options.
|
||||
# If all options are valid, array_intersect of the valid options
|
||||
# and the provided options will return the provided options.
|
||||
$validOptions = HTMLFormField::flattenOptions( $this->mParams['options'] );
|
||||
|
||||
$validValues = array_intersect( $value, $validOptions );
|
||||
|
|
@ -834,7 +1075,7 @@ class HTMLMultiSelectField extends HTMLFormField {
|
|||
}
|
||||
|
||||
function loadDataFromRequest( $request ) {
|
||||
// won't work with getCheck
|
||||
# won't work with getCheck
|
||||
if( $request->getCheck( 'wpEditToken' ) ) {
|
||||
$arr = $request->getArray( $this->mName );
|
||||
|
||||
|
|
@ -860,6 +1101,9 @@ class HTMLMultiSelectField extends HTMLFormField {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Radio checkbox fields.
|
||||
*/
|
||||
class HTMLRadioField extends HTMLFormField {
|
||||
function validate( $value, $alldata ) {
|
||||
$p = parent::validate( $value, $alldata );
|
||||
|
|
@ -876,6 +1120,10 @@ class HTMLRadioField extends HTMLFormField {
|
|||
return wfMsgExt( 'htmlform-select-badoption', 'parseinline' );
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a block of all the radio options, in one cell.
|
||||
* @see includes/HTMLFormField#getInputHTML()
|
||||
*/
|
||||
function getInputHTML( $value ) {
|
||||
$html = $this->formatOptions( $this->mParams['options'], $value );
|
||||
|
||||
|
|
@ -890,6 +1138,7 @@ class HTMLRadioField extends HTMLFormField {
|
|||
$attribs['disabled'] = 'disabled';
|
||||
}
|
||||
|
||||
# TODO: should this produce an unordered list perhaps?
|
||||
foreach( $options as $label => $info ) {
|
||||
if( is_array( $info ) ) {
|
||||
$html .= Html::rawElement( 'h1', array(), $label ) . "\n";
|
||||
|
|
@ -913,6 +1162,9 @@ class HTMLRadioField extends HTMLFormField {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An information field (text blob), not a proper input.
|
||||
*/
|
||||
class HTMLInfoField extends HTMLFormField {
|
||||
function __construct( $info ) {
|
||||
$info['nodata'] = true;
|
||||
|
|
|
|||
Loading…
Reference in a new issue