$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 : "", or "" if nothing has been selected in the * select dropdown. * FIXME: If made 'required', only the text field should be compulsory. */ class HTMLSelectAndOtherField extends HTMLSelectField { function __construct( $params ) { if ( array_key_exists( 'other', $params ) ) { } elseif( array_key_exists( 'other-message', $params ) ){ $params['other'] = wfMsg( $params['other-message'] ); } else { $params['other'] = wfMsg( 'htmlform-selectorother-other' ); } if ( array_key_exists( 'options', $params ) ) { # Options array already specified } elseif( array_key_exists( 'options-message', $params ) ){ # Generate options array from a system message $params['options'] = self::parseMessage( wfMsg( $params['options-message'], $params['other'] ) ); } else { # Sulk throw new MWException( 'HTMLSelectAndOtherField called without any options' ); } $this->mFlatOptions = self::flattenOptions( $params['options'] ); parent::__construct( $params ); } /** * Build a drop-down box from a textual list. * @param $string String message text * @param $otherName String name of "other reason" option * @return Array * TODO: this is copied from Xml::listDropDown(), deprecate/avoid duplication? */ public static function parseMessage( $string, $otherName=null ) { if( $otherName === null ){ $otherName = wfMsg( 'htmlform-selectorother-other' ); } $optgroup = false; $options = array( $otherName => 'other' ); foreach ( explode( "\n", $string ) as $option ) { $value = trim( $option ); if ( $value == '' ) { continue; } elseif ( substr( $value, 0, 1) == '*' && substr( $value, 1, 1) != '*' ) { # A new group is starting... $value = trim( substr( $value, 1 ) ); $optgroup = $value; } elseif ( substr( $value, 0, 2) == '**' ) { # groupmember $opt = trim( substr( $value, 2 ) ); $parts = array_map( 'trim', explode( '|', $opt, 2 ) ); if( count( $parts ) === 1 ){ $parts[1] = $parts[0]; } if( $optgroup === false ){ $options[$parts[1]] = $parts[0]; } else { $options[$optgroup][$parts[1]] = $parts[0]; } } else { # groupless reason list $optgroup = false; $parts = array_map( 'trim', explode( '|', $opt, 2 ) ); if( count( $parts ) === 1 ){ $parts[1] = $parts[0]; } $options[$parts[1]] = $parts[0]; } } return $options; } function getInputHTML( $value ) { $select = parent::getInputHTML( $value ); $textAttribs = array( 'id' => $this->mID . '-other', 'size' => $this->getSize(), ); foreach ( array( 'required', 'autofocus', 'multiple', 'disabled' ) as $param ) { if ( isset( $this->mParams[$param] ) ) { $textAttribs[$param] = ''; } } $textbox = Html::input( $this->mName . '-other', '', 'text', $textAttribs ); return "$select
\n$textbox"; } function loadDataFromRequest( $request ) { if ( $request->getCheck( $this->mName ) ) { $list = $request->getText( $this->mName ); $text = $request->getText( $this->mName . '-other' ); if ( $list == 'other' ) { return $text; } else { # Need to get the value from the key if( in_array( $list, $this->mFlatOptions ) ){ $list = $this->mFlatOptions[$list]; } else { # User has spoofed the select form to give an option which wasn't # in the original offer. Sulk... return $text; } } if( $text == '' ) { return $list; } else { return $list . wfMsgForContent( 'colon-separator' ) . $text; } } else { return $this->getDefault(); } } function getSize() { return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 45; } } /** * Radio checkbox fields. */ class HTMLRadioField extends HTMLFormField { function validate( $value, $alldata ) { $p = parent::validate( $value, $alldata ); if ( $p !== true ) { return $p; } if ( !is_string( $value ) && !is_int( $value ) ) { return false; } $validOptions = HTMLFormField::flattenOptions( $this->mParams['options'] ); if ( in_array( $value, $validOptions ) ) { return true; } else { 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 ); return $html; } function formatOptions( $options, $value ) { $html = ''; $attribs = array(); if ( !empty( $this->mParams['disabled'] ) ) { $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"; $html .= $this->formatOptions( $info, $value ); } else { $id = Sanitizer::escapeId( $this->mID . "-$info" ); $html .= Xml::radio( $this->mName, $info, $info == $value, $attribs + array( 'id' => $id ) ); $html .= ' ' . Html::rawElement( 'label', array( 'for' => $id ), $label ); $html .= "
\n"; } } return $html; } protected function needsLabel() { return false; } } /** * An information field (text blob), not a proper input. */ class HTMLInfoField extends HTMLFormField { function __construct( $info ) { $info['nodata'] = true; parent::__construct( $info ); } function getInputHTML( $value ) { return !empty( $this->mParams['raw'] ) ? $value : htmlspecialchars( $value ); } function getTableRow( $value ) { if ( !empty( $this->mParams['rawrow'] ) ) { return $value; } return parent::getTableRow( $value ); } protected function needsLabel() { return false; } } class HTMLHiddenField extends HTMLFormField { public function __construct( $params ) { parent::__construct( $params ); # Per HTML5 spec, hidden fields cannot be 'required' # http://dev.w3.org/html5/spec/states-of-the-type-attribute.html#hidden-state unset( $this->mParams['required'] ); } public function getTableRow( $value ) { $params = array(); if ( $this->mID ) { $params['id'] = $this->mID; } $this->mParent->addHiddenField( $this->mName, $this->mDefault, $params ); return ''; } public function getInputHTML( $value ) { return ''; } } /** * Add a submit button inline in the form (as opposed to * HTMLForm::addButton(), which will add it at the end). */ class HTMLSubmitField extends HTMLFormField { function __construct( $info ) { $info['nodata'] = true; parent::__construct( $info ); } function getInputHTML( $value ) { return Xml::submitButton( $value, array( 'class' => 'mw-htmlform-submit', 'name' => $this->mName, 'id' => $this->mID, ) ); } protected function needsLabel() { return false; } /** * Button cannot be invalid */ public function validate( $value, $alldata ){ return true; } } class HTMLEditTools extends HTMLFormField { public function getInputHTML( $value ) { return ''; } public function getTableRow( $value ) { if ( empty( $this->mParams['message'] ) ) { $msg = wfMessage( 'edittools' ); } else { $msg = wfMessage( $this->mParams['message'] ); if ( $msg->isDisabled() ) { $msg = wfMessage( 'edittools' ); } } $msg->inContentLanguage(); return '' . '
' . $msg->parseAsBlock() . "
\n"; } }