MediaWiki  master
HTMLSelectAndOtherField.php
Go to the documentation of this file.
1 <?php
2 
15  private $mFlatOptions;
16 
17  public function __construct( $params ) {
18  if ( array_key_exists( 'other', $params ) ) {
19  // Do nothing
20  } elseif ( array_key_exists( 'other-message', $params ) ) {
21  $params['other'] = $this->getMessage( $params['other-message'] )->plain();
22  } else {
23  $params['other'] = $this->msg( 'htmlform-selectorother-other' )->plain();
24  }
25 
26  parent::__construct( $params );
27 
28  if ( $this->getOptions() === null ) {
29  // Sulk
30  throw new MWException( 'HTMLSelectAndOtherField called without any options' );
31  }
32  if ( !in_array( 'other', $this->mOptions, true ) ) {
33  // Have 'other' always as first element
34  $this->mOptions = [ $params['other'] => 'other' ] + $this->mOptions;
35  }
36  $this->mFlatOptions = self::flattenOptions( $this->getOptions() );
37  }
38 
39  public function getInputHTML( $value ) {
40  $select = parent::getInputHTML( $value[1] );
41 
42  $textAttribs = [
43  'id' => $this->mID . '-other',
44  'size' => $this->getSize(),
45  'class' => [ 'mw-htmlform-select-and-other-field' ],
46  'data-id-select' => $this->mID,
47  ];
48 
49  if ( $this->mClass !== '' ) {
50  $textAttribs['class'][] = $this->mClass;
51  }
52 
53  if ( isset( $this->mParams['maxlength-unit'] ) ) {
54  $textAttribs['data-mw-maxlength-unit'] = $this->mParams['maxlength-unit'];
55  }
56 
57  $allowedParams = [
58  'required',
59  'autofocus',
60  'multiple',
61  'disabled',
62  'tabindex',
63  'maxlength', // gets dynamic with javascript, see mediawiki.htmlform.js
64  'maxlength-unit', // 'bytes' or 'codepoints', see mediawiki.htmlform.js
65  ];
66 
67  $textAttribs += $this->getAttributes( $allowedParams );
68 
69  $textbox = Html::input( $this->mName . '-other', $value[2], 'text', $textAttribs );
70 
71  return "$select<br />\n$textbox";
72  }
73 
74  protected function getOOUIModules() {
75  return [ 'mediawiki.widgets.SelectWithInputWidget' ];
76  }
77 
78  public function getInputOOUI( $value ) {
79  $this->mParent->getOutput()->addModuleStyles( 'mediawiki.widgets.SelectWithInputWidget.styles' );
80 
81  # TextInput
82  $textAttribs = [
83  'name' => $this->mName . '-other',
84  'value' => $value[2],
85  ];
86 
87  $allowedParams = [
88  'required',
89  'autofocus',
90  'multiple',
91  'disabled',
92  'tabindex',
93  'maxlength',
94  ];
95 
96  $textAttribs += OOUI\Element::configFromHtmlAttributes(
97  $this->getAttributes( $allowedParams )
98  );
99 
100  if ( $this->mClass !== '' ) {
101  $textAttribs['classes'] = [ $this->mClass ];
102  }
103 
104  # DropdownInput
105  $dropdownInputAttribs = [
106  'name' => $this->mName,
107  'id' => $this->mID . '-select',
108  'options' => $this->getOptionsOOUI(),
109  'value' => $value[1],
110  ];
111 
112  $allowedParams = [
113  'tabindex',
114  'disabled',
115  ];
116 
117  $dropdownInputAttribs += OOUI\Element::configFromHtmlAttributes(
118  $this->getAttributes( $allowedParams )
119  );
120 
121  if ( $this->mClass !== '' ) {
122  $dropdownInputAttribs['classes'] = [ $this->mClass ];
123  }
124 
125  $disabled = false;
126  if ( isset( $this->mParams[ 'disabled' ] ) && $this->mParams[ 'disabled' ] ) {
127  $disabled = true;
128  }
129 
130  return $this->getInputWidget( [
131  'id' => $this->mID,
132  'disabled' => $disabled,
133  'textinput' => $textAttribs,
134  'dropdowninput' => $dropdownInputAttribs,
135  'or' => false,
136  'required' => $this->mParams[ 'required' ] ?? false,
137  'classes' => [ 'mw-htmlform-select-and-other-field' ],
138  'data' => [
139  'maxlengthUnit' => $this->mParams['maxlength-unit'] ?? 'bytes'
140  ],
141  ] );
142  }
143 
144  public function getInputWidget( $params ) {
145  return new MediaWiki\Widget\SelectWithInputWidget( $params );
146  }
147 
151  public function getDefault() {
152  $default = parent::getDefault();
153 
154  // Default values of empty form
155  $final = '';
156  $list = 'other';
157  $text = '';
158 
159  if ( $default !== null ) {
160  $final = $default;
161  // Assume the default is a text value, with the 'other' option selected.
162  // Then check if that assumption is correct, and update $list and $text if not.
163  $text = $final;
164  foreach ( $this->mFlatOptions as $option ) {
165  $match = $option . $this->msg( 'colon-separator' )->inContentLanguage()->text();
166  if ( strpos( $final, $match ) === 0 ) {
167  $list = $option;
168  $text = substr( $final, strlen( $match ) );
169  break;
170  }
171  }
172  }
173 
174  return [ $final, $list, $text ];
175  }
176 
182  public function loadDataFromRequest( $request ) {
183  if ( $request->getCheck( $this->mName ) ) {
184  $list = $request->getText( $this->mName );
185  $text = $request->getText( $this->mName . '-other' );
186 
187  // Should be built the same as in mediawiki.htmlform.js
188  if ( $list == 'other' ) {
189  $final = $text;
190  } elseif ( !in_array( $list, $this->mFlatOptions, true ) ) {
191  # User has spoofed the select form to give an option which wasn't
192  # in the original offer. Sulk...
193  $final = $text;
194  } elseif ( $text == '' ) {
195  $final = $list;
196  } else {
197  $final = $list . $this->msg( 'colon-separator' )->inContentLanguage()->text() . $text;
198  }
199  return [ $final, $list, $text ];
200  }
201  return $this->getDefault();
202  }
203 
204  public function getSize() {
205  return $this->mParams['size'] ?? 45;
206  }
207 
208  public function validate( $value, $alldata ) {
209  # HTMLSelectField forces $value to be one of the options in the select
210  # field, which is not useful here. But we do want the validation further up
211  # the chain
212  $p = parent::validate( $value[1], $alldata );
213 
214  if ( $p !== true ) {
215  return $p;
216  }
217 
218  if ( isset( $this->mParams['required'] )
219  && $this->mParams['required'] !== false
220  && $value[0] === ''
221  ) {
222  return $this->msg( 'htmlform-required' );
223  }
224 
225  return true;
226  }
227 }
Double field with a dropdown list constructed from a system message in the format.
getOptions()
Fetch the array of options from the field&#39;s parameters.
A select dropdown field.
static input( $name, $value='', $type='text', array $attribs=[])
Convenience function to produce an "<input>" element.
Definition: Html.php:667
getOptionsOOUI()
Get options and make them into arrays suitable for OOUI.
msg( $key,... $params)
Get a translated interface message.
getMessage( $value)
Turns a *-message parameter (which could be a MessageSpecifier, or a message name, or a name + parameters array) into a Message.
getAttributes(array $list)
Returns the given attributes from the parameters.
array bool null $mOptions