MediaWiki master
PreferencesFormOOUI.php
Go to the documentation of this file.
1<?php
26
34 protected $mSubSectionBeforeFields = false;
35
37 private $modifiedUser;
38
40 private $privateInfoEditable = true;
41
43 private $optionsEditable = true;
44
46 private $useMobileLayout;
47
51 public function setModifiedUser( $user ) {
52 $this->modifiedUser = $user;
53 }
54
58 public function getModifiedUser() {
59 if ( $this->modifiedUser === null ) {
60 return $this->getUser();
61 } else {
62 return $this->modifiedUser;
63 }
64 }
65
69 public function isPrivateInfoEditable() {
70 return $this->privateInfoEditable;
71 }
72
77 public function setPrivateInfoEditable( $editable ) {
78 $this->privateInfoEditable = $editable;
79 $this->suppressDefaultSubmit( !$this->privateInfoEditable && !$this->optionsEditable );
80 }
81
85 public function areOptionsEditable() {
86 return $this->optionsEditable;
87 }
88
92 public function setOptionsEditable( $optionsEditable ) {
93 $this->optionsEditable = $optionsEditable;
94 $this->suppressDefaultSubmit( !$this->privateInfoEditable && !$this->optionsEditable );
95 }
96
104 return [];
105 }
106
107 public function wrapForm( $html ) {
108 $html = Xml::tags( 'div', [ 'id' => 'preferences' ], $html );
109
110 return parent::wrapForm( $html );
111 }
112
119 public function filterDataForSubmit( $data ) {
120 foreach ( $this->mFlatFields as $fieldname => $field ) {
121 if ( $field instanceof HTMLNestedFilterable ) {
122 $info = $field->mParams;
123 $prefix = $info['prefix'] ?? $fieldname;
124 foreach ( $field->filterDataForSubmit( $data[$fieldname] ) as $key => $value ) {
125 $data["$prefix$key"] = $value;
126 }
127 unset( $data[$fieldname] );
128 }
129 }
130
131 return $data;
132 }
133
134 protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) {
135 $layout = parent::wrapFieldSetSection( $legend, $section, $attributes, $isRoot );
136
137 $layout->addClasses( [ 'mw-prefs-fieldset-wrapper' ] );
138 $layout->removeClasses( [ 'oo-ui-panelLayout-framed' ] );
139
140 return $layout;
141 }
142
143 private function isMobileLayout() {
144 if ( $this->useMobileLayout === null ) {
145 $skin = $this->getSkin();
146 $this->useMobileLayout = false;
147 $this->getHookRunner()->onPreferencesGetLayout( $this->useMobileLayout,
148 $skin->getSkinName(), [ 'isResponsive' => $skin->isResponsive() ] );
149 }
150 return $this->useMobileLayout;
151 }
152
156 public function addFields( $descriptor ) {
157 // Replace checkbox fields with toggle switchs on Special:Preferences
158 if ( $this->isMobileLayout() && $this->getTitle()->isSpecial( 'Preferences' ) ) {
159 foreach ( $descriptor as $_ => &$info ) {
160 if ( isset( $info['type'] ) && in_array( $info['type'], [ 'check', 'toggle' ] ) ) {
161 unset( $info['type'] );
162 $info['class'] = HTMLToggleSwitchField::class;
163 } elseif ( isset( $info['class'] ) && $info['class'] === HTMLCheckField::class ) {
164 $info['class'] = HTMLToggleSwitchField::class;
165 }
166 }
167 }
168 return parent::addFields( $descriptor );
169 }
170
175 public function getBody() {
176 if ( $this->isMobileLayout() ) {
177 // Import the icons used in the mobile view
178 $this->getOutput()->addModuleStyles(
179 [
180 'oojs-ui.styles.icons-user',
181 'oojs-ui.styles.icons-editing-core',
182 'oojs-ui.styles.icons-editing-advanced',
183 'oojs-ui.styles.icons-wikimediaui',
184 'oojs-ui.styles.icons-content',
185 'oojs-ui.styles.icons-moderation',
186 'oojs-ui.styles.icons-interactions',
187 'oojs-ui.styles.icons-movement',
188 'oojs-ui.styles.icons-wikimedia',
189 'oojs-ui.styles.icons-media',
190 'oojs-ui.styles.icons-accessibility',
191 'oojs-ui.styles.icons-layout',
192 ]
193 );
194 $form = $this->createMobilePreferencesForm();
195 } else {
196 $form = $this->createDesktopPreferencesForm();
197 }
198
199 $header = $this->formatFormHeader();
200
201 return $header . $form;
202 }
203
210 public function getLegend( $key ) {
211 $legend = parent::getLegend( $key );
212 $this->getHookRunner()->onPreferencesGetLegend( $this, $key, $legend );
213 return $legend;
214 }
215
220 public function getPreferenceSections() {
221 return array_keys( array_filter( $this->mFieldTree, 'is_array' ) );
222 }
223
228 private function createMobilePreferencesForm() {
229 $sectionButtons = [];
230 $sectionContents = [];
231 $iconNames = $this->getIconNames();
232
233 foreach ( $this->mFieldTree as $key => $val ) {
234 if ( !is_array( $val ) ) {
235 wfDebug( __METHOD__ . " encountered a field not attached to a section: '$key'" );
236 continue;
237 }
238 $label = $this->getLegend( $key );
239 $content =
240 $this->getHeaderHtml( $key ) .
241 $this->displaySection(
242 $val,
243 "",
244 "mw-prefsection-$key-"
245 ) .
246 $this->getFooterHtml( $key );
247
248 // Creating the header section
249 $label = ( new OOUI\Tag( 'div' ) )->appendContent(
250 ( new OOUI\Tag( 'h5' ) )->appendContent( $label )->addClasses( [ 'mw-prefs-title' ] ),
251 $this->createMobileDescription( $key )
252 );
253 $contentDiv = $this->createContentMobile( $key, $label, $content );
254
255 $sectionButton = new OOUI\ButtonWidget( [
256 'id' => 'mw-mobile-prefs-' . $key,
257 'icon' => $iconNames[ $key ] ?? 'settings',
258 'label' => new OOUI\HtmlSnippet( $label->toString() ),
259 'data' => $key,
260 'classes' => [ 'mw-mobile-prefsection' ],
261 'framed' => false,
262 ] );
263 $sectionButtons[] = $sectionButton;
264 $sectionContents[] = $contentDiv;
265 }
266
267 $buttonGroup = new OOUI\ButtonGroupWidget( [
268 'classes' => [ 'mw-mobile-prefs-sections' ],
269 'infusable' => true,
270 ] );
271 $buttonGroup->addItems( $sectionButtons );
272 $form = ( new OOUI\Tag( 'div' ) )
273 ->setAttributes( [ 'id' => 'mw-prefs-container' ] )
274 ->addClasses( [ 'mw-mobile-prefs-container' ] )
275 ->appendContent( $buttonGroup )
276 ->appendContent( $sectionContents );
277
278 return $form;
279 }
280
285 private function getIconNames() {
286 $iconNames = [
287 'personal' => 'userAvatar',
288 'rendering' => 'palette',
289 'editing' => 'edit',
290 'rc' => 'recentChanges',
291 'watchlist' => 'watchlist',
292 'searchoptions' => 'search',
293 'misc' => '',
294 ];
295 $hookIcons = [];
296 // Get icons from extensions that have their own sections
297 $this->getHookRunner()->onPreferencesGetIcon( $hookIcons );
298 $iconNames += $hookIcons;
299
300 return $iconNames;
301 }
302
308 private function createMobileDescription( $key ) {
309 $prefDescriptionMsg = $this->msg( "prefs-description-" . $key );
310 $prefDescription = $prefDescriptionMsg->exists() ? $prefDescriptionMsg->text() : "";
311 $prefDescriptionElement = ( new OOUI\Tag( 'p' ) )
312 ->appendContent( $prefDescription )
313 ->addClasses( [ 'mw-prefs-description' ] );
314
315 return $prefDescriptionElement;
316 }
317
325 private function createContentMobile( $key, $label, $content ) {
326 $contentDiv = ( new OOUI\Tag( 'div' ) );
327 $contentDiv->addClasses( [
328 'mw-prefs-content-page',
329 'mw-prefs-section-fieldset',
330 ] );
331 $contentDiv->setAttributes( [
332 'id' => 'mw-mobile-prefs-' . $key
333 ] );
334 $contentBody = ( new OOUI\Tag( 'div' ) )
335 ->addClasses( [ 'mw-htmlform-autoinfuse-lazy' ] )
336 ->setAttributes( [
337 'id' => 'mw-mobile-prefs-' . $key . '-content'
338 ] );
339 $contentHeader = ( new OOUI\Tag( 'div' ) )->setAttributes( [
340 'id' => 'mw-mobile-prefs-' . $key . '-head'
341 ] );
342 $contentHeader->addClasses( [ 'mw-prefs-content-head' ] );
343 $contentHeaderTitle = ( new OOUI\Tag( 'h5' ) )->setAttributes( [
344 'id' => 'mw-mobile-prefs-' . $key . '-title',
345 ] );
346 $contentHeaderTitle->appendContent( $label )->addClasses( [ 'mw-prefs-header-title' ] );
347 $formContent = new OOUI\Widget( [
348 'content' => new OOUI\HtmlSnippet( $content )
349 ] );
350 $hiddenForm = ( new OOUI\Tag( 'div' ) )->appendContent( $formContent );
351 $contentHeader->appendContent( $contentHeaderTitle );
352 $contentBody->appendContent( $contentHeader );
353 $contentBody->appendContent( $hiddenForm );
354 $contentDiv->appendContent( $contentBody );
355
356 return $contentDiv;
357 }
358
363 private function createDesktopPreferencesForm() {
364 $tabPanels = [];
365 foreach ( $this->mFieldTree as $key => $val ) {
366 if ( !is_array( $val ) ) {
367 wfDebug( __METHOD__ . " encountered a field not attached to a section: '$key'" );
368 continue;
369 }
370 $label = $this->getLegend( $key );
371 $content =
372 $this->getHeaderHtml( $key ) .
373 $this->displaySection(
374 $val,
375 "",
376 "mw-prefsection-$key-"
377 ) .
378 $this->getFooterHtml( $key );
379
380 $tabPanels[] = new OOUI\TabPanelLayout( 'mw-prefsection-' . $key, [
381 'classes' => [ 'mw-htmlform-autoinfuse-lazy' ],
382 'label' => $label,
383 'content' => new OOUI\FieldsetLayout( [
384 'classes' => [ 'mw-prefs-section-fieldset' ],
385 'id' => "mw-prefsection-$key",
386 'label' => $label,
387 'items' => [
388 new OOUI\Widget( [
389 'content' => new OOUI\HtmlSnippet( $content )
390 ] ),
391 ],
392 ] ),
393 'expanded' => false,
394 'framed' => true,
395 ] );
396 }
397
398 $indexLayout = new OOUI\IndexLayout( [
399 'infusable' => true,
400 'expanded' => false,
401 'autoFocus' => false,
402 'classes' => [ 'mw-prefs-tabs' ],
403 ] );
404 $indexLayout->addTabPanels( $tabPanels );
405
406 $form = new OOUI\PanelLayout( [
407 'framed' => true,
408 'expanded' => false,
409 'classes' => [ 'mw-prefs-tabs-wrapper' ],
410 'content' => $indexLayout
411 ] );
412
413 return $form;
414 }
415}
getUser()
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
suppressDefaultSubmit( $suppressSubmit=true)
Stop a default submit button being shown for this form.
displaySection( $fields, $sectionName='', $fieldsetIDPrefix='', &$hasUserVisibleFields=false)
getFooterHtml( $section=null)
Get footer HTML.
Compact stacked vertical format for forms, implemented using OOUI widgets.
getHeaderHtml( $section=null)
Get header HTML.
internal since 1.36
Definition User.php:93
Form to edit user preferences.
filterDataForSubmit( $data)
Separate multi-option preferences into multiple preferences, since we have to store them separately.
getPreferenceSections()
Get the keys of each top level preference section.
getBody()
Get the whole body of the form.
wrapForm( $html)
Wrap the form innards in an actual "<form>" element.
bool $mSubSectionBeforeFields
Override default value from HTMLForm.
addFields( $descriptor)
Add fields to the form.1.34HTMLForm
getLegend( $key)
Get the "<legend>" for a given section key.
wrapFieldSetSection( $legend, $section, $attributes, $isRoot)
Wraps the given $section into a user-visible fieldset.to overridestring The fieldset's Html\OOUI\Pane...
getExtraSuccessRedirectParameters()
Get extra parameters for the query string when redirecting after successful save.
setPrivateInfoEditable( $editable)
Whether the.
setOptionsEditable( $optionsEditable)
$header