MediaWiki  master
HTMLCheckMatrix.php
Go to the documentation of this file.
1 <?php
2 
28  private static $requiredParams = [
29  // Required by underlying HTMLFormField
30  'fieldname',
31  // Required by HTMLCheckMatrix
32  'rows',
33  'columns'
34  ];
35 
40  public function __construct( $params ) {
41  $missing = array_diff( self::$requiredParams, array_keys( $params ) );
42  if ( $missing ) {
43  throw new HTMLFormFieldRequiredOptionsException( $this, $missing );
44  }
45  parent::__construct( $params );
46  }
47 
48  public function validate( $value, $alldata ) {
49  $rows = $this->mParams['rows'];
50  $columns = $this->mParams['columns'];
51 
52  // Make sure user-defined validation callback is run
53  $p = parent::validate( $value, $alldata );
54  if ( $p !== true ) {
55  return $p;
56  }
57 
58  // Make sure submitted value is an array
59  if ( !is_array( $value ) ) {
60  return false;
61  }
62 
63  // If all options are valid, array_intersect of the valid options
64  // and the provided options will return the provided options.
65  $validOptions = [];
66  foreach ( $rows as $rowTag ) {
67  foreach ( $columns as $columnTag ) {
68  $validOptions[] = $columnTag . '-' . $rowTag;
69  }
70  }
71  $validValues = array_intersect( $value, $validOptions );
72  if ( count( $validValues ) == count( $value ) ) {
73  return true;
74  } else {
75  return $this->msg( 'htmlform-select-badoption' );
76  }
77  }
78 
89  public function getInputHTML( $value ) {
90  $html = '';
91  $tableContents = '';
92  $rows = $this->mParams['rows'];
93  $columns = $this->mParams['columns'];
94 
95  $attribs = $this->getAttributes( [ 'disabled', 'tabindex' ] );
96 
97  // Build the column headers
98  $headerContents = Html::rawElement( 'td', [], "\u{00A0}" );
99  foreach ( $columns as $columnLabel => $columnTag ) {
100  $headerContents .= Html::rawElement( 'th', [], $columnLabel );
101  }
102  $thead = Html::rawElement( 'tr', [], "\n$headerContents\n" );
103  $tableContents .= Html::rawElement( 'thead', [], "\n$thead\n" );
104 
105  $tooltipClass = 'mw-icon-question';
106  if ( isset( $this->mParams['tooltip-class'] ) ) {
107  $tooltipClass = $this->mParams['tooltip-class'];
108  }
109 
110  // Build the options matrix
111  foreach ( $rows as $rowLabel => $rowTag ) {
112  // Append tooltip if configured
113  if ( isset( $this->mParams['tooltips'][$rowLabel] ) ) {
114  $tooltipAttribs = [
115  'class' => "mw-htmlform-tooltip $tooltipClass",
116  'title' => $this->mParams['tooltips'][$rowLabel],
117  'aria-label' => $this->mParams['tooltips'][$rowLabel]
118  ];
119  $rowLabel .= ' ' . Html::element( 'span', $tooltipAttribs, '' );
120  }
121  $rowContents = Html::rawElement( 'td', [], $rowLabel );
122  foreach ( $columns as $columnTag ) {
123  $thisTag = "$columnTag-$rowTag";
124  // Construct the checkbox
125  $thisAttribs = [
126  'id' => "{$this->mID}-$thisTag",
127  'value' => $thisTag,
128  ];
129  $checked = in_array( $thisTag, (array)$value, true );
130  if ( $this->isTagForcedOff( $thisTag ) ) {
131  $checked = false;
132  $thisAttribs['disabled'] = 1;
133  $thisAttribs['class'] = 'checkmatrix-forced checkmatrix-forced-off';
134  } elseif ( $this->isTagForcedOn( $thisTag ) ) {
135  $checked = true;
136  $thisAttribs['disabled'] = 1;
137  $thisAttribs['class'] = 'checkmatrix-forced checkmatrix-forced-on';
138  }
139 
140  $checkbox = $this->getOneCheckboxHTML( $checked, $attribs + $thisAttribs );
141 
142  $rowContents .= Html::rawElement(
143  'td',
144  [],
145  $checkbox
146  );
147  }
148  $tableContents .= Html::rawElement( 'tr', [], "\n$rowContents\n" );
149  }
150 
151  // Put it all in a table
152  $html .= Html::rawElement( 'table',
153  [ 'class' => 'mw-htmlform-matrix' ],
154  Html::rawElement( 'tbody', [], "\n$tableContents\n" ) ) . "\n";
155 
156  return $html;
157  }
158 
159  public function getInputOOUI( $value ) {
160  $attribs = $this->getAttributes( [ 'disabled', 'tabindex' ] );
161 
163  [
164  'name' => $this->mName,
165  'infusable' => true,
166  'id' => $this->mID,
167  'rows' => $this->mParams['rows'],
168  'columns' => $this->mParams['columns'],
169  'tooltips' => $this->mParams['tooltips'] ?? [],
170  'forcedOff' => $this->mParams['force-options-off'] ?? [],
171  'forcedOn' => $this->mParams['force-options-on'] ?? [],
172  'values' => $value,
173  ] + OOUI\Element::configFromHtmlAttributes( $attribs )
174  );
175  }
176 
177  protected function getOneCheckboxHTML( $checked, $attribs ) {
178  $checkbox = Xml::check( "{$this->mName}[]", $checked, $attribs );
179  if ( $this->mParent->getConfig()->get( 'UseMediaWikiUIEverywhere' ) ) {
180  $checkbox = Html::openElement( 'div', [ 'class' => 'mw-ui-checkbox' ] ) .
181  $checkbox .
182  Html::element( 'label', [ 'for' => $attribs['id'] ] ) .
183  Html::closeElement( 'div' );
184  }
185  return $checkbox;
186  }
187 
188  protected function isTagForcedOff( $tag ) {
189  return isset( $this->mParams['force-options-off'] )
190  && in_array( $tag, $this->mParams['force-options-off'] );
191  }
192 
193  protected function isTagForcedOn( $tag ) {
194  return isset( $this->mParams['force-options-on'] )
195  && in_array( $tag, $this->mParams['force-options-on'] );
196  }
197 
209  public function getTableRow( $value ) {
210  list( $errors, $errorClass ) = $this->getErrorsAndErrorClass( $value );
211  $inputHtml = $this->getInputHTML( $value );
212  $fieldType = static::class;
213  $helptext = $this->getHelpTextHtmlTable( $this->getHelpText() );
214  $cellAttributes = [ 'colspan' => 2 ];
215 
216  $hideClass = '';
217  $hideAttributes = [];
218  if ( $this->mHideIf ) {
219  $hideAttributes['data-hide-if'] = FormatJson::encode( $this->mHideIf );
220  $hideClass = 'mw-htmlform-hide-if';
221  }
222 
223  $label = $this->getLabelHtml( $cellAttributes );
224 
225  $field = Html::rawElement(
226  'td',
227  [ 'class' => 'mw-input' ] + $cellAttributes,
228  $inputHtml . "\n$errors"
229  );
230 
231  $html = Html::rawElement( 'tr',
232  [ 'class' => "mw-htmlform-vertical-label $hideClass" ] + $hideAttributes,
233  $label );
234  $html .= Html::rawElement( 'tr',
235  [ 'class' => "mw-htmlform-field-$fieldType {$this->mClass} $errorClass $hideClass" ] +
236  $hideAttributes,
237  $field );
238 
239  return $html . $helptext;
240  }
241 
247  public function loadDataFromRequest( $request ) {
248  if ( $this->isSubmitAttempt( $request ) ) {
249  // Checkboxes are just not added to the request arrays if they're not checked,
250  // so it's perfectly possible for there not to be an entry at all
251  return $request->getArray( $this->mName, [] );
252  } else {
253  // That's ok, the user has not yet submitted the form, so show the defaults
254  return $this->getDefault();
255  }
256  }
257 
258  public function getDefault() {
259  return $this->mDefault ?? [];
260  }
261 
262  public function filterDataForSubmit( $data ) {
263  $columns = HTMLFormField::flattenOptions( $this->mParams['columns'] );
264  $rows = HTMLFormField::flattenOptions( $this->mParams['rows'] );
265  $res = [];
266  foreach ( $columns as $column ) {
267  foreach ( $rows as $row ) {
268  // Make sure option hasn't been forced
269  $thisTag = "$column-$row";
270  if ( $this->isTagForcedOff( $thisTag ) ) {
271  $res[$thisTag] = false;
272  } elseif ( $this->isTagForcedOn( $thisTag ) ) {
273  $res[$thisTag] = true;
274  } else {
275  $res[$thisTag] = in_array( $thisTag, $data );
276  }
277  }
278  }
279 
280  return $res;
281  }
282 
283  protected function getOOUIModules() {
284  return [ 'mediawiki.widgets.CheckMatrixWidget' ];
285  }
286 
287  protected function shouldInfuseOOUI() {
288  return true;
289  }
290 }
HTMLCheckMatrix\shouldInfuseOOUI
shouldInfuseOOUI()
Whether the field should be automatically infused.
Definition: HTMLCheckMatrix.php:287
HTMLFormField\getErrorsAndErrorClass
getErrorsAndErrorClass( $value)
Determine form errors to display and their classes.
Definition: HTMLFormField.php:903
MediaWiki\Widget\CheckMatrixWidget
Check matrix widget.
Definition: CheckMatrixWidget.php:11
HTMLCheckMatrix\getDefault
getDefault()
Stable to override.
Definition: HTMLCheckMatrix.php:258
HTMLCheckMatrix\isTagForcedOff
isTagForcedOff( $tag)
Definition: HTMLCheckMatrix.php:188
HTMLCheckMatrix\getInputOOUI
getInputOOUI( $value)
Same as getInputHTML, but returns an OOUI object.
Definition: HTMLCheckMatrix.php:159
$res
$res
Definition: testCompression.php:57
HTMLFormField\getLabelHtml
getLabelHtml( $cellAttributes=[])
Stable to override.
Definition: HTMLFormField.php:957
HTMLFormField\getHelpTextHtmlTable
getHelpTextHtmlTable( $helptext)
Generate help text HTML in table format.
Definition: HTMLFormField.php:786
Html\closeElement
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:315
FormatJson\encode
static encode( $value, $pretty=false, $escaping=0)
Returns the JSON representation of a value.
Definition: FormatJson.php:115
HTMLFormField\getHelpText
getHelpText()
Determine the help text to display Stable to override.
Definition: HTMLFormField.php:852
Xml\check
static check( $name, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox.
Definition: Xml.php:327
HTMLFormField
The parent class to generate form fields.
Definition: HTMLFormField.php:9
HTMLCheckMatrix\getOOUIModules
getOOUIModules()
Get the list of extra ResourceLoader modules which must be loaded client-side before it's possible to...
Definition: HTMLCheckMatrix.php:283
HTMLCheckMatrix\validate
validate( $value, $alldata)
Override this function to add specific validation checks on the field input.
Definition: HTMLCheckMatrix.php:48
HTMLCheckMatrix\getTableRow
getTableRow( $value)
Get the complete table row for the input, including help text, labels, and whatever.
Definition: HTMLCheckMatrix.php:209
HTMLCheckMatrix\getOneCheckboxHTML
getOneCheckboxHTML( $checked, $attribs)
Definition: HTMLCheckMatrix.php:177
HTMLCheckMatrix\filterDataForSubmit
filterDataForSubmit( $data)
Support for separating multi-option preferences into multiple preferences Due to lack of array suppor...
Definition: HTMLCheckMatrix.php:262
HTMLCheckMatrix\loadDataFromRequest
loadDataFromRequest( $request)
Definition: HTMLCheckMatrix.php:247
HTMLFormFieldRequiredOptionsException
@newable Stable to extend
Definition: HTMLFormFieldRequiredOptionsException.php:7
HTMLCheckMatrix\$requiredParams
static $requiredParams
Definition: HTMLCheckMatrix.php:28
HTMLCheckMatrix\getInputHTML
getInputHTML( $value)
Build a table containing a matrix of checkbox options.
Definition: HTMLCheckMatrix.php:89
HTMLCheckMatrix
A checkbox matrix Operates similarly to HTMLMultiSelectField, but instead of using an array of option...
Definition: HTMLCheckMatrix.php:27
HTMLNestedFilterable
Definition: HTMLNestedFilterable.php:3
Html\openElement
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:251
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
HTMLCheckMatrix\__construct
__construct( $params)
Stable to call Initialise the object.Stable to call Associative Array. See HTMLForm doc for syntax....
Definition: HTMLCheckMatrix.php:40
HTMLFormField\isSubmitAttempt
isSubmitAttempt(WebRequest $request)
Can we assume that the request is an attempt to submit a HTMLForm, as opposed to an attempt to just v...
Definition: HTMLFormField.php:378
HTMLFormField\flattenOptions
static flattenOptions( $options)
flatten an array of options to a single array, for instance, a set of "<options>" inside "<optgroups>...
Definition: HTMLFormField.php:1135
HTMLFormField\msg
msg( $key,... $params)
Get a translated interface message.
Definition: HTMLFormField.php:87
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
HTMLCheckMatrix\isTagForcedOn
isTagForcedOn( $tag)
Definition: HTMLCheckMatrix.php:193
HTMLFormField\getAttributes
getAttributes(array $list)
Returns the given attributes from the parameters Stable to override.
Definition: HTMLFormField.php:1039