X-Git-Url: https://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2FHTMLForm.php;h=33e447efd661a2c7dc8b53acdca3b1150e52e368;hb=63df600442e6614c21c42390a42651a0a9e8c5eb;hp=c08206d22273415eaf1392065feba4249c24f585;hpb=e593d18a886a9a9286753b41e4941fcb456a616a;p=lhc%2Fweb%2Fwiklou.git
diff --git a/includes/HTMLForm.php b/includes/HTMLForm.php
index c08206d222..33e447efd6 100644
--- a/includes/HTMLForm.php
+++ b/includes/HTMLForm.php
@@ -140,6 +140,7 @@ class HTMLForm extends ContextSource {
protected $mSectionFooters = array();
protected $mPost = '';
protected $mId;
+ protected $mTableId = '';
protected $mSubmitID;
protected $mSubmitName;
@@ -200,12 +201,12 @@ class HTMLForm extends ContextSource {
$this->setContext( $context );
$this->mTitle = false; // We don't need them to set a title
$this->mMessagePrefix = $messagePrefix;
- } else {
+ } elseif ( is_null( $context ) && $messagePrefix !== '' ) {
+ $this->mMessagePrefix = $messagePrefix;
+ } elseif ( is_string( $context ) && $messagePrefix === '' ) {
// B/C since 1.18
- if ( is_string( $context ) && $messagePrefix === '' ) {
- // it's actually $messagePrefix
- $this->mMessagePrefix = $context;
- }
+ // it's actually $messagePrefix
+ $this->mMessagePrefix = $context;
}
// Expand out into a tree.
@@ -587,8 +588,8 @@ class HTMLForm extends ContextSource {
}
/**
- * Display the form (sending to $wgOut), with an appropriate error
- * message or stack of messages, and any validation errors, etc.
+ * Display the form (sending to the context's OutputPage object), with an
+ * appropriate error message or stack of messages, and any validation errors, etc.
*
* @attention You should call prepareForm() before calling this function.
* Moreover, when doing method chaining this should be the very last method
@@ -742,7 +743,7 @@ class HTMLForm extends ContextSource {
* @return String
*/
function getBody() {
- return $this->displaySection( $this->mFieldTree );
+ return $this->displaySection( $this->mFieldTree, $this->mTableId );
}
/**
@@ -871,6 +872,18 @@ class HTMLForm extends ContextSource {
return $this;
}
+ /**
+ * Set the id of the \
or outermost \ element.
+ *
+ * @since 1.22
+ * @param string $id new value of the id attribute, or "" to remove
+ * @return HTMLForm $this for chaining calls
+ */
+ public function setTableId( $id ) {
+ $this->mTableId = $id;
+ return $this;
+ }
+
/**
* @param string $id DOM id for the form
* @return HTMLForm $this for chaining calls (since 1.20)
@@ -879,6 +892,7 @@ class HTMLForm extends ContextSource {
$this->mId = $id;
return $this;
}
+
/**
* Prompt the whole form to be wrapped in a "
", with
* this text as its "" element.
@@ -977,7 +991,7 @@ class HTMLForm extends ContextSource {
$hasLabel = true;
}
} elseif ( is_array( $value ) ) {
- $section = $this->displaySection( $value, $key, "$fieldsetIDPrefix$key-" );
+ $section = $this->displaySection( $value, "mw-htmlform-$key", "$fieldsetIDPrefix$key-" );
$legend = $this->getLegend( $key );
if ( isset( $this->mSectionHeaders[$key] ) ) {
$section = $this->mSectionHeaders[$key] . $section;
@@ -1005,7 +1019,7 @@ class HTMLForm extends ContextSource {
);
if ( $sectionName ) {
- $attribs['id'] = Sanitizer::escapeId( "mw-htmlform-$sectionName" );
+ $attribs['id'] = Sanitizer::escapeId( $sectionName );
}
if ( $displayFormat === 'table' ) {
@@ -1093,7 +1107,6 @@ class HTMLForm extends ContextSource {
$this->mAction = $action;
return $this;
}
-
}
/**
@@ -1111,6 +1124,12 @@ abstract class HTMLFormField {
protected $mClass = '';
protected $mDefault;
+ /**
+ * @var bool If true will generate an empty div element with no label
+ * @since 1.22
+ */
+ protected $mShowEmptyLabels = true;
+
/**
* @var HTMLForm
*/
@@ -1203,6 +1222,8 @@ abstract class HTMLFormField {
/**
* Initialise the object
* @param array $params Associative Array. See HTMLForm doc for syntax.
+ *
+ * @since 1.22 The 'label' attribute no longer accepts raw HTML, use 'label-raw' instead
* @throws MWException
*/
function __construct( $params ) {
@@ -1221,7 +1242,14 @@ abstract class HTMLFormField {
$this->mLabel = wfMessage( $msg, $msgInfo )->parse();
} elseif ( isset( $params['label'] ) ) {
- $this->mLabel = $params['label'];
+ if ( $params['label'] === ' ' ) {
+ // Apparently some things set   directly and in an odd format
+ $this->mLabel = ' ';
+ } else {
+ $this->mLabel = htmlspecialchars( $params['label'] );
+ }
+ } elseif ( isset( $params['label-raw'] ) ) {
+ $this->mLabel = $params['label-raw'];
}
$this->mName = "wp{$params['fieldname']}";
@@ -1266,6 +1294,10 @@ abstract class HTMLFormField {
if ( isset( $params['flatlist'] ) ) {
$this->mClass .= ' mw-htmlform-flatlist';
}
+
+ if ( isset( $params['hidelabel'] ) ) {
+ $this->mShowEmptyLabels = false;
+ }
}
/**
@@ -1326,9 +1358,14 @@ abstract class HTMLFormField {
$cellAttributes = array();
$label = $this->getLabelHtml( $cellAttributes );
+ $outerDivClass = array(
+ 'mw-input',
+ 'mw-htmlform-nolabel' => ( $label === '' )
+ );
+
$field = Html::rawElement(
'div',
- array( 'class' => 'mw-input' ) + $cellAttributes,
+ array( 'class' => $outerDivClass ) + $cellAttributes,
$inputHtml . "\n$errors"
);
$html = Html::rawElement( 'div',
@@ -1457,7 +1494,7 @@ abstract class HTMLFormField {
}
function getLabel() {
- return $this->mLabel;
+ return is_null( $this->mLabel ) ? '' : $this->mLabel;
}
function getLabelHtml( $cellAttributes = array() ) {
@@ -1469,20 +1506,32 @@ abstract class HTMLFormField {
$for['for'] = $this->mID;
}
+ $labelValue = trim( $this->getLabel() );
+ $hasLabel = false;
+ if ( $labelValue !== ' ' && $labelValue !== '' ) {
+ $hasLabel = true;
+ }
+
$displayFormat = $this->mParent->getDisplayFormat();
- $labelElement = Html::rawElement( 'label', $for, $this->getLabel() );
+ $html = '';
- if ( $displayFormat == 'table' ) {
- return Html::rawElement( 'td', array( 'class' => 'mw-label' ) + $cellAttributes,
- Html::rawElement( 'label', $for, $this->getLabel() )
- );
- } elseif ( $displayFormat == 'div' ) {
- return Html::rawElement( 'div', array( 'class' => 'mw-label' ) + $cellAttributes,
- Html::rawElement( 'label', $for, $this->getLabel() )
+ if ( $displayFormat === 'table' ) {
+ $html = Html::rawElement( 'td', array( 'class' => 'mw-label' ) + $cellAttributes,
+ Html::rawElement( 'label', $for, $labelValue )
);
- } else {
- return $labelElement;
+ } elseif ( $hasLabel || $this->mShowEmptyLabels ) {
+ if ( $displayFormat === 'div' ) {
+ $html = Html::rawElement(
+ 'div',
+ array( 'class' => 'mw-label' ) + $cellAttributes,
+ Html::rawElement( 'label', $for, $labelValue )
+ );
+ } else {
+ $html = Html::rawElement( 'label', $for, $labelValue );
+ }
}
+
+ return $html;
}
function getDefault() {
@@ -1622,16 +1671,19 @@ class HTMLTextField extends HTMLFormField {
}
}
class HTMLTextAreaField extends HTMLFormField {
+ const DEFAULT_COLS = 80;
+ const DEFAULT_ROWS = 25;
+
function getCols() {
return isset( $this->mParams['cols'] )
? $this->mParams['cols']
- : 80;
+ : static::DEFAULT_COLS;
}
function getRows() {
return isset( $this->mParams['rows'] )
? $this->mParams['rows']
- : 25;
+ : static::DEFAULT_ROWS;
}
function getInputHTML( $value ) {
@@ -1806,9 +1858,39 @@ class HTMLCheckField extends HTMLFormField {
* A checkbox matrix
* Operates similarly to HTMLMultiSelectField, but instead of using an array of
* options, uses an array of rows and an array of columns to dynamically
- * construct a matrix of options.
+ * construct a matrix of options. The tags used to identify a particular cell
+ * are of the form "columnName-rowName"
+ *
+ * Options:
+ * - columns
+ * - Required list of columns in the matrix.
+ * - rows
+ * - Required list of rows in the matrix.
+ * - force-options-on
+ * - Accepts array of column-row tags to be displayed as enabled but unavailable to change
+ * - force-options-off
+ * - Accepts array of column-row tags to be displayed as disabled but unavailable to change.
+ * - tooltips
+ * - Optional array mapping row label to tooltip content
+ * - tooltip-class
+ * - Optional CSS class used on tooltip container span. Defaults to mw-icon-question.
*/
-class HTMLCheckMatrix extends HTMLFormField {
+class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
+
+ static private $requiredParams = array(
+ // Required by underlying HTMLFormField
+ 'fieldname',
+ // Required by HTMLCheckMatrix
+ 'rows', 'columns'
+ );
+
+ public function __construct( $params ) {
+ $missing = array_diff( self::$requiredParams, array_keys( $params ) );
+ if ( $missing ) {
+ throw HTMLFormFieldRequiredOptionsException::create( $this, $missing );
+ }
+ parent::__construct( $params );
+ }
function validate( $value, $alldata ) {
$rows = $this->mParams['rows'];
@@ -1868,27 +1950,42 @@ class HTMLCheckMatrix extends HTMLFormField {
}
$tableContents .= Html::rawElement( 'tr', array(), "\n$headerContents\n" );
+ $tooltipClass = 'mw-icon-question';
+ if ( isset( $this->mParams['tooltip-class'] ) ) {
+ $tooltipClass = $this->mParams['tooltip-class'];
+ }
+
// Build the options matrix
foreach ( $rows as $rowLabel => $rowTag ) {
+ // Append tooltip if configured
+ if ( isset( $this->mParams['tooltips'][$rowLabel] ) ) {
+ $tooltipAttribs = array(
+ 'class' => "mw-htmlform-tooltip $tooltipClass",
+ 'title' => $this->mParams['tooltips'][$rowLabel],
+ );
+ $rowLabel .= ' ' . Html::element( 'span', $tooltipAttribs, '' );
+ }
$rowContents = Html::rawElement( 'td', array(), $rowLabel );
foreach ( $columns as $columnTag ) {
- // Knock out any options that are not wanted
- if ( isset( $this->mParams['remove-options'] )
- && in_array( "$columnTag-$rowTag", $this->mParams['remove-options'] ) )
- {
- $rowContents .= Html::rawElement( 'td', array(), ' ' );
- } else {
- // Construct the checkbox
- $thisAttribs = array(
- 'id' => "{$this->mID}-$columnTag-$rowTag",
- 'value' => $columnTag . '-' . $rowTag
- );
- $checkbox = Xml::check(
- $this->mName . '[]',
- in_array( $columnTag . '-' . $rowTag, (array)$value, true ),
- $attribs + $thisAttribs );
- $rowContents .= Html::rawElement( 'td', array(), $checkbox );
+ $thisTag = "$columnTag-$rowTag";
+ // Construct the checkbox
+ $thisAttribs = array(
+ 'id' => "{$this->mID}-$thisTag",
+ 'value' => $thisTag,
+ );
+ $checked = in_array( $thisTag, (array)$value, true );
+ if ( $this->isTagForcedOff( $thisTag ) ) {
+ $checked = false;
+ $thisAttribs['disabled'] = 1;
+ } elseif ( $this->isTagForcedOn( $thisTag ) ) {
+ $checked = true;
+ $thisAttribs['disabled'] = 1;
}
+ $rowContents .= Html::rawElement(
+ 'td',
+ array(),
+ Xml::check( "{$this->mName}[]", $checked, $attribs + $thisAttribs )
+ );
}
$tableContents .= Html::rawElement( 'tr', array(), "\n$rowContents\n" );
}
@@ -1900,6 +1997,16 @@ class HTMLCheckMatrix extends HTMLFormField {
return $html;
}
+ protected function isTagForcedOff( $tag ) {
+ return isset( $this->mParams['force-options-off'] )
+ && in_array( $tag, $this->mParams['force-options-off'] );
+ }
+
+ protected function isTagForcedOn( $tag ) {
+ return isset( $this->mParams['force-options-on'] )
+ && in_array( $tag, $this->mParams['force-options-on'] );
+ }
+
/**
* Get the complete table row for the input, including help text,
* labels, and whatever.
@@ -1964,6 +2071,27 @@ class HTMLCheckMatrix extends HTMLFormField {
return array();
}
}
+
+ function filterDataForSubmit( $data ) {
+ $columns = HTMLFormField::flattenOptions( $this->mParams['columns'] );
+ $rows = HTMLFormField::flattenOptions( $this->mParams['rows'] );
+ $res = array();
+ foreach ( $columns as $column ) {
+ foreach ( $rows as $row ) {
+ // Make sure option hasn't been forced
+ $thisTag = "$column-$row";
+ if ( $this->isTagForcedOff( $thisTag ) ) {
+ $res[$thisTag] = false;
+ } elseif ( $this->isTagForcedOn( $thisTag ) ) {
+ $res[$thisTag] = true;
+ } else {
+ $res[$thisTag] = in_array( $thisTag, $data );
+ }
+ }
+ }
+
+ return $res;
+ }
}
/**
@@ -2105,7 +2233,7 @@ class HTMLSelectOrOtherField extends HTMLTextField {
/**
* Multi-select field
*/
-class HTMLMultiSelectField extends HTMLFormField {
+class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable {
function validate( $value, $alldata ) {
$p = parent::validate( $value, $alldata );
@@ -2198,6 +2326,17 @@ class HTMLMultiSelectField extends HTMLFormField {
}
}
+ function filterDataForSubmit( $data ) {
+ $options = HTMLFormField::flattenOptions( $this->mParams['options'] );
+
+ $res = array();
+ foreach ( $options as $opt ) {
+ $res["$opt"] = in_array( $opt, $data );
+ }
+
+ return $res;
+ }
+
protected function needsLabel() {
return false;
}
@@ -2653,3 +2792,22 @@ class HTMLApiField extends HTMLFormField {
return '';
}
}
+
+interface HTMLNestedFilterable {
+ /**
+ * Support for seperating multi-option preferences into multiple preferences
+ * Due to lack of array support.
+ * @param $data array
+ */
+ function filterDataForSubmit( $data );
+}
+
+class HTMLFormFieldRequiredOptionsException extends MWException {
+ static public function create( HTMLFormField $field, array $missing ) {
+ return new self( sprintf(
+ "Form type `%s` expected the following parameters to be set: %s",
+ get_class( $field ),
+ implode( ', ', $missing )
+ ) );
+ }
+}