MediaWiki master
PreferencesFormOOUI.php
Go to the documentation of this file.
1<?php
27
35 protected $mSubSectionBeforeFields = false;
36
38 private $modifiedUser;
39
41 private $privateInfoEditable = true;
42
44 private $optionsEditable = true;
45
47 private $useMobileLayout;
48
52 public function setModifiedUser( $user ) {
53 $this->modifiedUser = $user;
54 }
55
59 public function getModifiedUser() {
60 if ( $this->modifiedUser === null ) {
61 return $this->getUser();
62 } else {
63 return $this->modifiedUser;
64 }
65 }
66
70 public function isPrivateInfoEditable() {
71 return $this->privateInfoEditable;
72 }
73
78 public function setPrivateInfoEditable( $editable ) {
79 $this->privateInfoEditable = $editable;
80 $this->suppressDefaultSubmit( !$this->privateInfoEditable && !$this->optionsEditable );
81 }
82
86 public function areOptionsEditable() {
87 return $this->optionsEditable;
88 }
89
93 public function setOptionsEditable( $optionsEditable ) {
94 $this->optionsEditable = $optionsEditable;
95 $this->suppressDefaultSubmit( !$this->privateInfoEditable && !$this->optionsEditable );
96 }
97
105 return [];
106 }
107
108 public function wrapForm( $html ) {
109 $html = Xml::tags( 'div', [ 'id' => 'preferences' ], $html );
110
111 return parent::wrapForm( $html );
112 }
113
120 public function filterDataForSubmit( $data ) {
121 foreach ( $this->mFlatFields as $fieldname => $field ) {
122 if ( $field instanceof HTMLNestedFilterable ) {
123 $info = $field->mParams;
124 $prefix = $info['prefix'] ?? $fieldname;
125 foreach ( $field->filterDataForSubmit( $data[$fieldname] ) as $key => $value ) {
126 $data["$prefix$key"] = $value;
127 }
128 unset( $data[$fieldname] );
129 }
130 }
131
132 return $data;
133 }
134
135 protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) {
136 $layout = parent::wrapFieldSetSection( $legend, $section, $attributes, $isRoot );
137
138 $layout->addClasses( [ 'mw-prefs-fieldset-wrapper' ] );
139 $layout->removeClasses( [ 'oo-ui-panelLayout-framed' ] );
140
141 return $layout;
142 }
143
144 private function isMobileLayout() {
145 if ( $this->useMobileLayout === null ) {
146 $skin = $this->getSkin();
147 $this->useMobileLayout = false;
148 $this->getHookRunner()->onPreferencesGetLayout( $this->useMobileLayout,
149 $skin->getSkinName(), [ 'isResponsive' => $skin->isResponsive() ] );
150 }
151 return $this->useMobileLayout;
152 }
153
157 public function addFields( $descriptor ) {
158 // Replace checkbox fields with toggle switchs on Special:Preferences
159 if ( $this->isMobileLayout() && $this->getTitle()->isSpecial( 'Preferences' ) ) {
160 foreach ( $descriptor as $_ => &$info ) {
161 if ( isset( $info['type'] ) && in_array( $info['type'], [ 'check', 'toggle' ] ) ) {
162 unset( $info['type'] );
163 $info['class'] = HTMLToggleSwitchField::class;
164 } elseif ( isset( $info['class'] ) && $info['class'] === HTMLCheckField::class ) {
165 $info['class'] = HTMLToggleSwitchField::class;
166 }
167 }
168 }
169 return parent::addFields( $descriptor );
170 }
171
176 public function getBody() {
177 if ( $this->isMobileLayout() ) {
178 // Import the icons used in the mobile view
179 $this->getOutput()->addModuleStyles(
180 [
181 'oojs-ui.styles.icons-user',
182 'oojs-ui.styles.icons-editing-core',
183 'oojs-ui.styles.icons-editing-advanced',
184 'oojs-ui.styles.icons-wikimediaui',
185 'oojs-ui.styles.icons-content',
186 'oojs-ui.styles.icons-moderation',
187 'oojs-ui.styles.icons-interactions',
188 'oojs-ui.styles.icons-movement',
189 'oojs-ui.styles.icons-wikimedia',
190 'oojs-ui.styles.icons-media',
191 'oojs-ui.styles.icons-accessibility',
192 'oojs-ui.styles.icons-layout',
193 ]
194 );
195 $form = $this->createMobilePreferencesForm();
196 } else {
197 $form = $this->createDesktopPreferencesForm();
198 }
199
200 $header = $this->formatFormHeader();
201
202 return $header . $form;
203 }
204
211 public function getLegend( $key ) {
212 $legend = parent::getLegend( $key );
213 $this->getHookRunner()->onPreferencesGetLegend( $this, $key, $legend );
214 return $legend;
215 }
216
221 public function getPreferenceSections() {
222 return array_keys( array_filter( $this->mFieldTree, 'is_array' ) );
223 }
224
229 private function createMobilePreferencesForm() {
230 $sectionButtons = [];
231 $sectionContents = [];
232 $iconNames = $this->getIconNames();
233
234 foreach ( $this->mFieldTree as $key => $val ) {
235 if ( !is_array( $val ) ) {
236 wfDebug( __METHOD__ . " encountered a field not attached to a section: '$key'" );
237 continue;
238 }
239 $label = $this->getLegend( $key );
240 $content =
241 $this->getHeaderHtml( $key ) .
242 $this->displaySection(
243 $val,
244 "",
245 "mw-prefsection-$key-"
246 ) .
247 $this->getFooterHtml( $key );
248
249 // Creating the header section
250 $label = ( new OOUI\Tag( 'div' ) )->appendContent(
251 ( new OOUI\Tag( 'h5' ) )->appendContent( $label )->addClasses( [ 'mw-prefs-title' ] ),
252 $this->createMobileDescription( $key )
253 );
254 $contentDiv = $this->createContentMobile( $key, $label, $content );
255
256 $sectionButton = new OOUI\ButtonWidget( [
257 'id' => 'mw-mobile-prefs-' . $key,
258 'icon' => $iconNames[ $key ] ?? 'settings',
259 'label' => new OOUI\HtmlSnippet( $label->toString() ),
260 'data' => $key,
261 'classes' => [ 'mw-mobile-prefsection' ],
262 'framed' => false,
263 ] );
264 $sectionButtons[] = $sectionButton;
265 $sectionContents[] = $contentDiv;
266 }
267
268 $buttonGroup = new OOUI\ButtonGroupWidget( [
269 'classes' => [ 'mw-mobile-prefs-sections' ],
270 'infusable' => true,
271 ] );
272 $buttonGroup->addItems( $sectionButtons );
273 $form = ( new OOUI\Tag( 'div' ) )
274 ->setAttributes( [ 'id' => 'mw-prefs-container' ] )
275 ->addClasses( [ 'mw-mobile-prefs-container' ] )
276 ->appendContent( $buttonGroup )
277 ->appendContent( $sectionContents );
278
279 return $form;
280 }
281
286 private function getIconNames() {
287 $iconNames = [
288 'personal' => 'userAvatar',
289 'rendering' => 'palette',
290 'editing' => 'edit',
291 'rc' => 'recentChanges',
292 'watchlist' => 'watchlist',
293 'searchoptions' => 'search',
294 'misc' => '',
295 ];
296 $hookIcons = [];
297 // Get icons from extensions that have their own sections
298 $this->getHookRunner()->onPreferencesGetIcon( $hookIcons );
299 $iconNames += $hookIcons;
300
301 return $iconNames;
302 }
303
309 private function createMobileDescription( $key ) {
310 $prefDescriptionMsg = $this->msg( "prefs-description-" . $key );
311 $prefDescription = $prefDescriptionMsg->exists() ? $prefDescriptionMsg->text() : "";
312 $prefDescriptionElement = ( new OOUI\Tag( 'p' ) )
313 ->appendContent( $prefDescription )
314 ->addClasses( [ 'mw-prefs-description' ] );
315
316 return $prefDescriptionElement;
317 }
318
326 private function createContentMobile( $key, $label, $content ) {
327 $contentDiv = ( new OOUI\Tag( 'div' ) );
328 $contentDiv->addClasses( [
329 'mw-prefs-content-page',
330 'mw-prefs-section-fieldset',
331 ] );
332 $contentDiv->setAttributes( [
333 'id' => 'mw-mobile-prefs-' . $key
334 ] );
335 $contentBody = ( new OOUI\Tag( 'div' ) )
336 ->addClasses( [ 'mw-htmlform-autoinfuse-lazy' ] )
337 ->setAttributes( [
338 'id' => 'mw-mobile-prefs-' . $key . '-content'
339 ] );
340 $contentHeader = ( new OOUI\Tag( 'div' ) )->setAttributes( [
341 'id' => 'mw-mobile-prefs-' . $key . '-head'
342 ] );
343 $contentHeader->addClasses( [ 'mw-prefs-content-head' ] );
344 $contentHeaderTitle = ( new OOUI\Tag( 'h5' ) )->setAttributes( [
345 'id' => 'mw-mobile-prefs-' . $key . '-title',
346 ] );
347 $contentHeaderTitle->appendContent( $label )->addClasses( [ 'mw-prefs-header-title' ] );
348 $formContent = new OOUI\Widget( [
349 'content' => new OOUI\HtmlSnippet( $content )
350 ] );
351 $hiddenForm = ( new OOUI\Tag( 'div' ) )->appendContent( $formContent );
352 $contentHeader->appendContent( $contentHeaderTitle );
353 $contentBody->appendContent( $contentHeader );
354 $contentBody->appendContent( $hiddenForm );
355 $contentDiv->appendContent( $contentBody );
356
357 return $contentDiv;
358 }
359
364 private function createDesktopPreferencesForm() {
365 $tabPanels = [];
366 foreach ( $this->mFieldTree as $key => $val ) {
367 if ( !is_array( $val ) ) {
368 wfDebug( __METHOD__ . " encountered a field not attached to a section: '$key'" );
369 continue;
370 }
371 $label = $this->getLegend( $key );
372 $content =
373 $this->getHeaderHtml( $key ) .
374 $this->displaySection(
375 $val,
376 "",
377 "mw-prefsection-$key-"
378 ) .
379 $this->getFooterHtml( $key );
380
381 $tabPanels[] = new OOUI\TabPanelLayout( 'mw-prefsection-' . $key, [
382 'classes' => [ 'mw-htmlform-autoinfuse-lazy' ],
383 'label' => $label,
384 'content' => new OOUI\FieldsetLayout( [
385 'classes' => [ 'mw-prefs-section-fieldset' ],
386 'id' => "mw-prefsection-$key",
387 'label' => $label,
388 'items' => [
389 new OOUI\Widget( [
390 'content' => new OOUI\HtmlSnippet( $content )
391 ] ),
392 ],
393 ] ),
394 'expanded' => false,
395 'framed' => true,
396 ] );
397 }
398
399 $indexLayout = new OOUI\IndexLayout( [
400 'infusable' => true,
401 'expanded' => false,
402 'autoFocus' => false,
403 'classes' => [ 'mw-prefs-tabs' ],
404 ] );
405 $indexLayout->addTabPanels( $tabPanels );
406
407 $form = new OOUI\PanelLayout( [
408 'framed' => true,
409 'expanded' => false,
410 'classes' => [ 'mw-prefs-tabs-wrapper' ],
411 'content' => $indexLayout
412 ] );
413
414 return $form;
415 }
416}
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
Module of static functions for generating XML.
Definition Xml.php:37
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