$wgDBWindowsAuthentication, which makes the web server authenticate against
the database server using Integrated Windows Authentication instead of
$wgDBuser/$wgDBpassword.
+* HTMLForm 'select', 'selectandother', 'selectorother', 'multiselect', and
+ 'radio' fields can now use message keys as labels via the 'options-messages'
+ parameter, which overrides the 'options' parameter.
=== Bug fixes in 1.23 ===
* (bug 41759) The "updated since last visit" markers (on history pages, recent
* 'default' -- default value when the form is displayed
* 'id' -- HTML id attribute
* 'cssclass' -- CSS class
- * 'options' -- varies according to the specific object.
+ * 'options' -- associative array mapping labels to values.
+ * Some field types support multi-level arrays.
+ * 'options-messages' -- associative array mapping message keys to values.
+ * Some field types support multi-level arrays.
+ * 'options-message' -- message key to be parsed to extract the list of
+ * options (like 'ipbreason-dropdown').
* '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.
protected $mID;
protected $mClass = '';
protected $mDefault;
+ protected $mOptions = false;
+ protected $mOptionsLabelsNotFromMessage = false;
/**
* @var bool If true will generate an empty div element with no label
return $ret;
}
+ /**
+ * Given an array of msg-key => value mappings, returns an array with keys
+ * being the message texts. It also forces values to strings.
+ *
+ * @param array $options
+ * @return array
+ */
+ private function lookupOptionsKeys( $options ) {
+ $ret = array();
+ foreach ( $options as $key => $value ) {
+ $key = $this->msg( $key )->plain();
+ $ret[$key] = is_array( $value )
+ ? $this->lookupOptionsKeys($field, $value)
+ : strval( $value );
+ }
+ return $ret;
+ }
+
+ /**
+ * Recursively forces values in an array to strings, because issues arise
+ * with integer 0 as a value.
+ *
+ * @param array $array
+ * @return array
+ */
+ static function forceToStringRecursive( $array ) {
+ if ( is_array( $array ) ) {
+ return array_map( array( __CLASS__, 'forceToStringRecursive' ), $array );
+ } else {
+ return strval( $array );
+ }
+ }
+
+ /**
+ * Fetch the array of options from the field's parameters. In order, this
+ * checks 'options-messages', 'options', then 'options-message'.
+ *
+ * @return array|null Options array
+ */
+ public function getOptions() {
+ if ( $this->mOptions === false ) {
+ if ( array_key_exists( 'options-messages', $this->mParams ) ) {
+ $this->mOptions = $this->lookupOptionsKeys( $this->mParams['options-messages'] );
+ } elseif ( array_key_exists( 'options', $this->mParams ) ) {
+ $this->mOptionsLabelsNotFromMessage = true;
+ $this->mOptions = self::forceToStringRecursive( $this->mParams['options'] );
+ } elseif ( array_key_exists( 'options-message', $this->mParams ) ) {
+ /** @todo This is copied from Xml::listDropDown(), deprecate/avoid duplication? */
+ $message = $this->msg( $this->mParams['options-message'] )->plain();
+
+ $optgroup = false;
+ $this->mOptions = array();
+ foreach ( explode( "\n", $message ) 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 ) );
+ if ( $optgroup === false ) {
+ $this->mOptions[$opt] = $opt;
+ } else {
+ $this->mOptions[$optgroup][$opt] = $opt;
+ }
+ } else {
+ # groupless reason list
+ $optgroup = false;
+ $this->mOptions[$option] = $option;
+ }
+ }
+ } else {
+ $this->mOptions = null;
+ }
+ }
+
+ return $this->mOptions;
+ }
+
/**
* flatten an array of options to a single array, for instance,
* a set of "<options>" inside "<optgroups>".
# 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'] );
+ $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
$validValues = array_intersect( $value, $validOptions );
if ( count( $validValues ) == count( $value ) ) {
}
function getInputHTML( $value ) {
- $html = $this->formatOptions( $this->mParams['options'], $value );
+ $html = $this->formatOptions( $this->getOptions(), $value );
return $html;
}
$html = '';
$attribs = $this->getAttributes( array( 'disabled', 'tabindex' ) );
+ $elementFunc = array( 'Html', $this->mOptionsLabelsNotFromMessage ? 'rawElement' : 'element' );
foreach ( $options as $label => $info ) {
if ( is_array( $info ) ) {
in_array( $info, $value, true ),
$attribs + $thisAttribs
);
- $checkbox .= ' ' . Html::rawElement(
+ $checkbox .= ' ' . call_user_func( $elementFunc,
'label',
array( 'for' => "{$this->mID}-$info" ),
$label
}
function filterDataForSubmit( $data ) {
- $options = HTMLFormField::flattenOptions( $this->mParams['options'] );
+ $options = HTMLFormField::flattenOptions( $this->getOptions() );
$res = array();
foreach ( $options as $opt ) {
return false;
}
- $validOptions = HTMLFormField::flattenOptions( $this->mParams['options'] );
+ $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
if ( in_array( $value, $validOptions ) ) {
return true;
* @return String
*/
function getInputHTML( $value ) {
- $html = $this->formatOptions( $this->mParams['options'], $value );
+ $html = $this->formatOptions( $this->getOptions(), $value );
return $html;
}
$html = '';
$attribs = $this->getAttributes( array( 'disabled', 'tabindex' ) );
+ $elementFunc = array( 'Html', $this->mOptionsLabelsNotFromMessage ? 'rawElement' : 'element' );
# @todo Should this produce an unordered list perhaps?
foreach ( $options as $label => $info ) {
} else {
$id = Sanitizer::escapeId( $this->mID . "-$info" );
$radio = Xml::radio( $this->mName, $info, $info == $value, $attribs + array( 'id' => $id ) );
- $radio .= ' ' . Html::rawElement( 'label', array( 'for' => $id ), $label );
+ $radio .= ' ' . call_user_func( $elementFunc, 'label', array( 'for' => $id ), $label );
$html .= ' ' . Html::rawElement(
'div',
$params['other'] = null;
}
- 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( wfMessage( $params['options-message'] )->inContentLanguage()->plain(),
- $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 string $otherName 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 = wfMessage( 'htmlform-selectorother-other' )->plain();
+ if ( $this->getOptions() === null ) {
+ # Sulk
+ throw new MWException( 'HTMLSelectAndOtherField called without any options' );
}
-
- $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 ) );
- if ( $optgroup === false ) {
- $options[$opt] = $opt;
- } else {
- $options[$optgroup][$opt] = $opt;
- }
- } else {
- # groupless reason list
- $optgroup = false;
- $options[$option] = $option;
- }
+ if ( !in_array( 'other', $this->mOptions, true ) ) {
+ $this->mOptions[$params['other']] = 'other';
}
+ $this->mFlatOptions = self::flattenOptions( $this->getOptions() );
- return $options;
}
function getInputHTML( $value ) {
return $p;
}
- $validOptions = HTMLFormField::flattenOptions( $this->mParams['options'] );
+ $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
if ( in_array( $value, $validOptions ) ) {
return true;
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 thinks int(0) == 'some string'.
- # Working around this by forcing all of them to strings.
- foreach ( $this->mParams['options'] as &$opt ) {
- if ( is_int( $opt ) ) {
- $opt = strval( $opt );
- }
- }
- unset( $opt ); # PHP keeps $opt around as a reference, which is a bit scary
-
if ( !empty( $this->mParams['disabled'] ) ) {
$select->setAttribute( 'disabled', 'disabled' );
}
$select->setAttribute( 'class', $this->mClass );
}
- $select->addOptions( $this->mParams['options'] );
+ $select->addOptions( $this->getOptions() );
return $select->getHTML();
}
*/
class HTMLSelectOrOtherField extends HTMLTextField {
function __construct( $params ) {
- if ( !in_array( 'other', $params['options'], true ) ) {
+ parent::__construct( $params );
+ $this->getOptions();
+ if ( !in_array( 'other', $this->mOptions, true ) ) {
$msg =
isset( $params['other'] )
? $params['other']
: wfMessage( 'htmlform-selectorother-other' )->text();
- $params['options'][$msg] = 'other';
+ $this->mOptions[$msg] = 'other';
}
- parent::__construct( $params );
- }
-
- static function forceToStringRecursive( $array ) {
- if ( is_array( $array ) ) {
- return array_map( array( __CLASS__, 'forceToStringRecursive' ), $array );
- } else {
- return strval( $array );
- }
}
function getInputHTML( $value ) {
$valInSelect = false;
if ( $value !== false ) {
- $valInSelect = in_array( $value, HTMLFormField::flattenOptions( $this->mParams['options'] ) );
+ $valInSelect = in_array( $value, HTMLFormField::flattenOptions( $this->getOptions() ) );
}
$selected = $valInSelect ? $value : 'other';
- $opts = self::forceToStringRecursive( $this->mParams['options'] );
-
$select = new XmlSelect( $this->mName, $this->mID, $selected );
- $select->addOptions( $opts );
+ $select->addOptions( $this->getOptions() );
$select->setAttribute( 'class', 'mw-htmlform-select-or-other' );