MediaWiki master
PreferencesFormOOUI.php
Go to the documentation of this file.
1<?php
13
21 protected $mSubSectionBeforeFields = false;
22
24 private $modifiedUser;
25
27 private $privateInfoEditable = true;
28
30 private $optionsEditable = true;
31
33 private $useMobileLayout;
34
38 public function setModifiedUser( $user ) {
39 $this->modifiedUser = $user;
40 }
41
45 public function getModifiedUser() {
46 if ( $this->modifiedUser === null ) {
47 return $this->getUser();
48 } else {
49 return $this->modifiedUser;
50 }
51 }
52
56 public function isPrivateInfoEditable() {
57 return $this->privateInfoEditable;
58 }
59
64 public function setPrivateInfoEditable( $editable ) {
65 $this->privateInfoEditable = $editable;
66 $this->suppressDefaultSubmit( !$this->privateInfoEditable && !$this->optionsEditable );
67 }
68
72 public function areOptionsEditable() {
73 return $this->optionsEditable;
74 }
75
79 public function setOptionsEditable( $optionsEditable ) {
80 $this->optionsEditable = $optionsEditable;
81 $this->suppressDefaultSubmit( !$this->privateInfoEditable && !$this->optionsEditable );
82 }
83
91 return [];
92 }
93
95 public function wrapForm( $html ) {
96 $html = Html::rawElement( 'div', [ 'id' => 'preferences' ], $html );
97
98 return parent::wrapForm( $html );
99 }
100
107 public function filterDataForSubmit( $data ) {
108 foreach ( $this->mFlatFields as $fieldname => $field ) {
109 if ( $field instanceof HTMLNestedFilterable ) {
110 $info = $field->mParams;
111 $prefix = $info['prefix'] ?? $fieldname;
112 foreach ( $field->filterDataForSubmit( $data[$fieldname] ) as $key => $value ) {
113 $data["$prefix$key"] = $value;
114 }
115 unset( $data[$fieldname] );
116 }
117 }
118
119 return $data;
120 }
121
123 protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) {
124 $layout = parent::wrapFieldSetSection( $legend, $section, $attributes, $isRoot );
125
126 $layout->addClasses( [ 'mw-prefs-fieldset-wrapper' ] );
127 $layout->removeClasses( [ 'oo-ui-panelLayout-framed' ] );
128
129 return $layout;
130 }
131
132 private function isMobileLayout(): bool {
133 if ( $this->useMobileLayout === null ) {
134 $skin = $this->getSkin();
135 $this->useMobileLayout = false;
136 $this->getHookRunner()->onPreferencesGetLayout( $this->useMobileLayout,
137 $skin->getSkinName(), [ 'isResponsive' => $skin->isResponsive() ] );
138 }
139 return $this->useMobileLayout;
140 }
141
145 public function addFields( $descriptor ) {
146 // Replace checkbox fields with toggle switchs on Special:Preferences
147 if ( $this->isMobileLayout() && $this->getTitle()->isSpecial( 'Preferences' ) ) {
148 foreach ( $descriptor as $_ => &$info ) {
149 if ( isset( $info['type'] ) && in_array( $info['type'], [ 'check', 'toggle' ] ) ) {
150 unset( $info['type'] );
151 $info['class'] = HTMLToggleSwitchField::class;
152 } elseif ( isset( $info['class'] ) && $info['class'] === HTMLCheckField::class ) {
153 $info['class'] = HTMLToggleSwitchField::class;
154 }
155 }
156 }
157 return parent::addFields( $descriptor );
158 }
159
164 public function getBody() {
165 if ( $this->isMobileLayout() ) {
166 // Import the icons used in the mobile view
167 $this->getOutput()->addModuleStyles(
168 [
169 'oojs-ui.styles.icons-user',
170 'oojs-ui.styles.icons-editing-core',
171 'oojs-ui.styles.icons-editing-advanced',
172 'oojs-ui.styles.icons-wikimediaui',
173 'oojs-ui.styles.icons-content',
174 'oojs-ui.styles.icons-moderation',
175 'oojs-ui.styles.icons-interactions',
176 'oojs-ui.styles.icons-movement',
177 'oojs-ui.styles.icons-wikimedia',
178 'oojs-ui.styles.icons-media',
179 'oojs-ui.styles.icons-accessibility',
180 'oojs-ui.styles.icons-layout',
181 ]
182 );
183 $form = $this->createMobilePreferencesForm();
184 } else {
185 $form = $this->createDesktopPreferencesForm();
186 }
187
188 $header = $this->formatFormHeader();
189
190 return $header . $form;
191 }
192
199 public function getLegend( $key ) {
200 $legend = parent::getLegend( $key );
201 $this->getHookRunner()->onPreferencesGetLegend( $this, $key, $legend );
202 return $legend;
203 }
204
209 public function getPreferenceSections() {
210 return array_keys( array_filter( $this->mFieldTree, 'is_array' ) );
211 }
212
217 private function createMobilePreferencesForm() {
218 $sectionButtons = [];
219 $sectionContents = [];
220 $iconNames = $this->getIconNames();
221
222 foreach ( $this->mFieldTree as $key => $val ) {
223 if ( !is_array( $val ) ) {
224 wfDebug( __METHOD__ . " encountered a field not attached to a section: '$key'" );
225 continue;
226 }
227 $label = $this->getLegend( $key );
228 $content =
229 $this->getHeaderHtml( $key ) .
230 $this->displaySection(
231 $val,
232 "",
233 "mw-prefsection-$key-"
234 ) .
235 $this->getFooterHtml( $key );
236
237 // Creating the header section
238 $label = ( new OOUI\Tag( 'div' ) )->appendContent(
239 ( new OOUI\Tag( 'h5' ) )->appendContent( $label )->addClasses( [ 'mw-prefs-title' ] ),
240 $this->createMobileDescription( $key )
241 );
242 $contentDiv = $this->createContentMobile( $key, $label, $content );
243
244 $sectionButton = new OOUI\ButtonWidget( [
245 'id' => 'mw-mobile-prefs-' . $key,
246 'icon' => $iconNames[ $key ] ?? 'settings',
247 'label' => new OOUI\HtmlSnippet( $label->toString() ),
248 'data' => $key,
249 'classes' => [ 'mw-mobile-prefsection' ],
250 'framed' => false,
251 ] );
252 $sectionButtons[] = $sectionButton;
253 $sectionContents[] = $contentDiv;
254 }
255
256 $buttonGroup = new OOUI\ButtonGroupWidget( [
257 'classes' => [ 'mw-mobile-prefs-sections' ],
258 'infusable' => true,
259 ] );
260 $buttonGroup->addItems( $sectionButtons );
261 $form = ( new OOUI\Tag( 'div' ) )
262 ->setAttributes( [ 'id' => 'mw-prefs-container' ] )
263 ->addClasses( [ 'mw-mobile-prefs-container' ] )
264 ->appendContent( $buttonGroup )
265 ->appendContent( $sectionContents );
266
267 return $form;
268 }
269
274 private function getIconNames() {
275 $iconNames = [
276 'personal' => 'userAvatar',
277 'rendering' => 'palette',
278 'editing' => 'edit',
279 'rc' => 'recentChanges',
280 'watchlist' => 'watchlist',
281 'searchoptions' => 'search',
282 'misc' => '',
283 ];
284 $hookIcons = [];
285 // Get icons from extensions that have their own sections
286 $this->getHookRunner()->onPreferencesGetIcon( $hookIcons );
287 $iconNames += $hookIcons;
288
289 return $iconNames;
290 }
291
297 private function createMobileDescription( $key ) {
298 $prefDescriptionMsg = $this->msg( "prefs-description-" . $key );
299 $prefDescription = $prefDescriptionMsg->exists() ? $prefDescriptionMsg->text() : "";
300 $prefDescriptionElement = ( new OOUI\Tag( 'p' ) )
301 ->appendContent( $prefDescription )
302 ->addClasses( [ 'mw-prefs-description' ] );
303
304 return $prefDescriptionElement;
305 }
306
314 private function createContentMobile( $key, $label, $content ) {
315 $contentDiv = ( new OOUI\Tag( 'div' ) );
316 $contentDiv->addClasses( [
317 'mw-prefs-content-page',
318 'mw-prefs-section-fieldset',
319 ] );
320 $contentDiv->setAttributes( [
321 'id' => 'mw-mobile-prefs-' . $key
322 ] );
323 $contentBody = ( new OOUI\Tag( 'div' ) )
324 ->addClasses( [ 'mw-htmlform-autoinfuse-lazy' ] )
325 ->setAttributes( [
326 'id' => 'mw-mobile-prefs-' . $key . '-content'
327 ] );
328 $contentHeader = ( new OOUI\Tag( 'div' ) )->setAttributes( [
329 'id' => 'mw-mobile-prefs-' . $key . '-head'
330 ] );
331 $contentHeader->addClasses( [ 'mw-prefs-content-head' ] );
332 $contentHeaderTitle = ( new OOUI\Tag( 'h5' ) )->setAttributes( [
333 'id' => 'mw-mobile-prefs-' . $key . '-title',
334 ] );
335 $contentHeaderTitle->appendContent( $label )->addClasses( [ 'mw-prefs-header-title' ] );
336 $formContent = new OOUI\Widget( [
337 'content' => new OOUI\HtmlSnippet( $content )
338 ] );
339 $hiddenForm = ( new OOUI\Tag( 'div' ) )->appendContent( $formContent );
340 $contentHeader->appendContent( $contentHeaderTitle );
341 $contentBody->appendContent( $contentHeader );
342 $contentBody->appendContent( $hiddenForm );
343 $contentDiv->appendContent( $contentBody );
344
345 return $contentDiv;
346 }
347
352 private function createDesktopPreferencesForm() {
353 $tabPanels = [];
354 foreach ( $this->mFieldTree as $key => $val ) {
355 if ( !is_array( $val ) ) {
356 wfDebug( __METHOD__ . " encountered a field not attached to a section: '$key'" );
357 continue;
358 }
359 $label = $this->getLegend( $key );
360 $content =
361 $this->getHeaderHtml( $key ) .
362 $this->displaySection(
363 $val,
364 "",
365 "mw-prefsection-$key-"
366 ) .
367 $this->getFooterHtml( $key );
368
369 $tabPanels[] = new OOUI\TabPanelLayout( 'mw-prefsection-' . $key, [
370 'classes' => [ 'mw-htmlform-autoinfuse-lazy' ],
371 'label' => $label,
372 'content' => new OOUI\FieldsetLayout( [
373 'classes' => [ 'mw-prefs-section-fieldset' ],
374 'id' => "mw-prefsection-$key",
375 'label' => $label,
376 'items' => [
377 new OOUI\Widget( [
378 'content' => new OOUI\HtmlSnippet( $content )
379 ] ),
380 ],
381 ] ),
382 'expanded' => false,
383 'framed' => true,
384 ] );
385 }
386
387 $indexLayout = new OOUI\IndexLayout( [
388 'infusable' => true,
389 'expanded' => false,
390 'autoFocus' => false,
391 'classes' => [ 'mw-prefs-tabs' ],
392 ] );
393 $indexLayout->addTabPanels( $tabPanels );
394
395 $form = new OOUI\PanelLayout( [
396 'framed' => true,
397 'expanded' => false,
398 'classes' => [ 'mw-prefs-tabs-wrapper' ],
399 'content' => $indexLayout
400 ] );
401
402 return $form;
403 }
404}
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:68
suppressDefaultSubmit( $suppressSubmit=true)
Stop a default submit button being shown for this form.
Compact stacked vertical format for forms, implemented using OOUI widgets.
This class is a collection of static functions that serve two purposes:
Definition Html.php:43
User class for the MediaWiki software.
Definition User.php:109
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.to override string|\OOUI\Tag Wrapped HTML.
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)
msg( $key,... $params)