MediaWiki master
OOUIHTMLForm.php
Go to the documentation of this file.
1<?php
2
3namespace MediaWiki\HTMLForm;
4
12use DomainException;
18
24class OOUIHTMLForm extends HTMLForm {
26 private $oouiErrors;
28 private $oouiWarnings;
29
34 public function __construct( $descriptor, IContextSource $context, string $messagePrefix = '' ) {
35 parent::__construct( $descriptor, $context, $messagePrefix );
36 $this->getOutput()->enableOOUI();
37 $this->getOutput()->addModuleStyles( 'mediawiki.htmlform.ooui.styles' );
38 }
39
41 protected $displayFormat = 'ooui';
42
44 public static function loadInputFromParameters( $fieldname, $descriptor,
45 ?HTMLForm $parent = null
46 ) {
47 $field = parent::loadInputFromParameters( $fieldname, $descriptor, $parent );
48 $field->setShowEmptyLabel( false );
49 return $field;
50 }
51
53 public function getButtons() {
54 $buttons = '';
55
56 if ( $this->mShowSubmit ) {
57 $attribs = [
58 'infusable' => true,
59 'classes' => [ 'mw-htmlform-submit' ],
60 'type' => 'submit',
61 'label' => $this->getSubmitText(),
62 'value' => $this->getSubmitText(),
63 'flags' => $this->mSubmitFlags,
64 ];
65
66 if ( $this->mSubmitID !== null ) {
67 $attribs['id'] = $this->mSubmitID;
68 }
69
70 if ( $this->mSubmitName !== null ) {
71 $attribs['name'] = $this->mSubmitName;
72 }
73
74 if ( $this->mSubmitTooltip !== null ) {
75 $attribs += [
76 'title' => Linker::titleAttrib( $this->mSubmitTooltip ),
77 'accessKey' => Linker::accesskey( $this->mSubmitTooltip ),
78 ];
79 }
80
81 if ( $this->mSubmitLockIcon ) {
82 $attribs['icon'] = 'lock';
83 }
84
85 $buttons .= new \OOUI\ButtonInputWidget( $attribs );
86 }
87
88 if ( $this->mShowCancel ) {
89 $buttons .= new \OOUI\ButtonWidget( [
90 'label' => $this->msg( 'cancel' )->text(),
91 'href' => $this->getCancelTargetURL(),
92 ] );
93 }
94
95 foreach ( $this->mButtons as $button ) {
96 $attrs = [];
97
98 if ( $button['attribs'] ) {
99 $attrs += $button['attribs'];
100 }
101
102 if ( isset( $button['id'] ) ) {
103 $attrs['id'] = $button['id'];
104 }
105
106 if ( isset( $button['label-message'] ) ) {
107 $label = new \OOUI\HtmlSnippet( $this->getMessage( $button['label-message'] )->parse() );
108 } elseif ( isset( $button['label'] ) ) {
109 $label = $button['label'];
110 } elseif ( isset( $button['label-raw'] ) ) {
111 $label = new \OOUI\HtmlSnippet( $button['label-raw'] );
112 } else {
113 $label = $button['value'];
114 }
115
116 $attrs['classes'] = isset( $attrs['class'] ) ? (array)$attrs['class'] : [];
117
118 $buttons .= new \OOUI\ButtonInputWidget( [
119 'type' => 'submit',
120 'name' => $button['name'],
121 'value' => $button['value'],
122 'label' => $label,
123 'flags' => $button['flags'],
124 'framed' => $button['framed'],
125 ] + $attrs );
126 }
127
128 if ( !$buttons ) {
129 return '';
130 }
131
132 return Html::rawElement( 'div',
133 [ 'class' => 'mw-htmlform-submit-buttons' ], "\n$buttons" ) . "\n";
134 }
135
140 protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) {
141 // @phan-suppress-previous-line PhanParamSignatureMismatch We're different from our parent intentionally
142 // to get a user visible effect, wrap the fieldset into a framed panel layout
143 $layout = new \OOUI\PanelLayout( [
144 'expanded' => false,
145 'padded' => true,
146 'framed' => true,
147 ] );
148
149 $layout->appendContent(
150 new \OOUI\FieldsetLayout( [
151 'label' => $legend,
152 'items' => [
153 new \OOUI\Widget( [
154 'content' => new \OOUI\HtmlSnippet( $section )
155 ] ),
156 ],
157 ] + $attributes )
158 );
159 return $layout;
160 }
161
166 protected function formatField( HTMLFormField $field, $value ) {
167 return $field->getOOUI( $value );
168 }
169
177 protected function formatSection( array $fieldsHtml, $sectionName, $anyFieldHasLabel ) {
178 if ( !$fieldsHtml ) {
179 // Do not generate any wrappers for empty sections. Sections may be empty if they only have
180 // subsections, but no fields. A legend will still be added in wrapFieldSetSection().
181 return '';
182 }
183
184 $html = implode( '', $fieldsHtml );
185
186 if ( $sectionName ) {
187 return Html::rawElement(
188 'div',
189 [ 'id' => Sanitizer::escapeIdForAttribute( $sectionName ) ],
190 $html
191 );
192 }
193 return $html;
194 }
195
201 public function getErrorsOrWarnings( $elements, $elementsType ) {
202 if ( $elements === '' ) {
203 return '';
204 }
205
206 if ( !in_array( $elementsType, [ 'error', 'warning' ], true ) ) {
207 throw new DomainException( $elementsType . ' is not a valid type.' );
208 }
209 $errors = [];
210 if ( $elements instanceof Status ) {
211 if ( !$elements->isGood() ) {
212 foreach ( $elements->getMessages( $elementsType ) as $msg ) {
213 $errors[] = $this->getMessage( $msg )->parse();
214 }
215 }
216 } elseif ( $elementsType === 'error' ) {
217 if ( is_array( $elements ) ) {
218 foreach ( $elements as $error ) {
219 $errors[] = $this->getMessage( $error )->parse();
220 }
221 } elseif ( $elements && $elements !== true ) {
222 $errors[] = (string)$elements;
223 }
224 }
225
226 foreach ( $errors as &$error ) {
227 $error = new \OOUI\HtmlSnippet( $error );
228 }
229
230 // Used in formatFormHeader()
231 if ( $elementsType === 'error' ) {
232 $this->oouiErrors = $errors;
233 } else {
234 $this->oouiWarnings = $errors;
235 }
236 return '';
237 }
238
240 public function getHeaderHtml( $section = null ) {
241 if ( $section === null ) {
242 // We handle $this->mHeader elsewhere, in getBody()
243 return '';
244 } else {
245 return parent::getHeaderHtml( $section );
246 }
247 }
248
249 protected function formatFormHeader(): string {
250 if ( !( $this->mHeader || $this->oouiErrors || $this->oouiWarnings ) ) {
251 return '';
252 }
253 $classes = [
254 'mw-htmlform-ooui-header',
255 ...$this->oouiErrors ? [ 'mw-htmlform-ooui-header-errors' ] : [],
256 ...$this->oouiWarnings ? [ 'mw-htmlform-ooui-header-warnings' ] : [],
257 ];
258 // if there's no header, don't create an (empty) LabelWidget, simply use a placeholder
259 if ( $this->mHeader ) {
260 $element = new \OOUI\LabelWidget( [ 'label' => new \OOUI\HtmlSnippet( $this->mHeader ) ] );
261 // In case the form header contains any form elements, avoid treating the entire header
262 // as a clickable label (T428359). Maybe it shouldn't be a `<label>` in the first place…
263 $element->setAttributes( [ 'for' => '' ] );
264 } else {
265 $element = new \OOUI\Widget( [] );
266 }
267 return ( new \OOUI\FieldLayout(
268 $element,
269 [
270 'align' => 'top',
271 'errors' => $this->oouiErrors,
272 'notices' => $this->oouiWarnings,
273 'classes' => $classes,
274 ]
275 ) )->toString();
276 }
277
279 public function getBody() {
280 return $this->formatFormHeader() . parent::getBody();
281 }
282
284 public function wrapForm( $html ) {
285 if ( is_string( $this->mWrapperLegend ) ) {
286 $phpClass = $this->mCollapsible ? CollapsibleFieldsetLayout::class : \OOUI\FieldsetLayout::class;
287 $content = new $phpClass( [
288 'label' => $this->mWrapperLegend,
289 'collapsed' => $this->mCollapsed,
290 'items' => [
291 new \OOUI\Widget( [
292 'content' => new \OOUI\HtmlSnippet( $html )
293 ] ),
294 ],
295 ] + \OOUI\Element::configFromHtmlAttributes( $this->mWrapperAttributes ) );
296 } else {
297 $content = new \OOUI\HtmlSnippet( $html );
298 }
299
300 $form = new \OOUI\FormLayout( $this->getFormAttributes() + [
301 'classes' => [ 'mw-htmlform', 'mw-htmlform-ooui' ],
302 'content' => $content,
303 ] );
304
305 // Include a wrapper for style, if requested.
306 $form = new \OOUI\PanelLayout( [
307 'classes' => [ 'mw-htmlform-ooui-wrapper' ],
308 'expanded' => false,
309 'padded' => $this->mWrapperLegend !== false,
310 'framed' => $this->mWrapperLegend !== false,
311 'content' => $form,
312 ] );
313
314 return $form;
315 }
316}
317
319class_alias( OOUIHTMLForm::class, 'OOUIHTMLForm' );
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:71
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
The parent class to generate form fields.
getOOUI( $value)
Get the OOUI version of the div.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:214
getMessage( $value)
Turns a *-message parameter (which could be a MessageSpecifier, or a message name,...
getSubmitText()
Get the text for the submit button, either customised or a default.
Compact stacked vertical format for forms, implemented using OOUI widgets.
getButtons()
Get the submit and (potentially) reset buttons.to override string HTML.
__construct( $descriptor, IContextSource $context, string $messagePrefix='')
wrapForm( $html)
Wrap the form innards in an actual "<form>" element.to override string|\OOUI\Tag Wrapped HTML.
wrapFieldSetSection( $legend, $section, $attributes, $isRoot)
Wraps the given $section into a user-visible fieldset.to overridestring The fieldset's Html
getBody()
Get the whole body of the form.to override string
formatField(HTMLFormField $field, $value)
Generate the HTML for an individual field in the current display format.1.41 to override string|Strin...
formatSection(array $fieldsHtml, $sectionName, $anyFieldHasLabel)
Put a form section together from the individual fields' HTML, merging it and wrapping.
static loadInputFromParameters( $fieldname, $descriptor, ?HTMLForm $parent=null)
getErrorsOrWarnings( $elements, $elementsType)
getHeaderHtml( $section=null)
Get header HTML.to override1.38 string HTML
This class is a collection of static functions that serve two purposes:
Definition Html.php:44
Some internal bits split of from Skin.php.
Definition Linker.php:48
HTML sanitizer for MediaWiki.
Definition Sanitizer.php:34
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:44
Interface for objects which can provide a MediaWiki context on request.