3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
21 namespace MediaWiki\Specials
;
23 use MediaWiki\Context\IContextSource
;
24 use MediaWiki\Html\Html
;
25 use MediaWiki\HTMLForm\HTMLForm
;
26 use MediaWiki\MediaWikiServices
;
27 use MediaWiki\Preferences\PreferencesFactory
;
28 use MediaWiki\SpecialPage\SpecialPage
;
29 use MediaWiki\User\Options\UserOptionsManager
;
30 use MediaWiki\User\User
;
32 use OOUI\SearchInputWidget
;
34 use PreferencesFormOOUI
;
37 * A special page that allows users to change their preferences
39 * @ingroup SpecialPage
41 class SpecialPreferences
extends SpecialPage
{
43 private PreferencesFactory
$preferencesFactory;
44 private UserOptionsManager
$userOptionsManager;
47 * @param PreferencesFactory|null $preferencesFactory
48 * @param UserOptionsManager|null $userOptionsManager
50 public function __construct(
51 ?PreferencesFactory
$preferencesFactory = null,
52 ?UserOptionsManager
$userOptionsManager = null
54 parent
::__construct( 'Preferences' );
55 // This class is extended and therefore falls back to global state - T265924
56 $services = MediaWikiServices
::getInstance();
57 $this->preferencesFactory
= $preferencesFactory ??
$services->getPreferencesFactory();
58 $this->userOptionsManager
= $userOptionsManager ??
$services->getUserOptionsManager();
61 public function doesWrites() {
65 public function execute( $par ) {
67 $this->outputHeader();
68 $out = $this->getOutput();
69 $out->disallowUserJs(); # Prevent hijacked user scripts from sniffing passwords etc.
71 $this->requireNamedUser( 'prefsnologintext2' );
72 $this->checkReadOnly();
74 if ( $par == 'reset' ) {
75 $this->showResetForm();
80 $out->addModules( 'mediawiki.special.preferences.ooui' );
81 $out->addModuleStyles( [
82 'mediawiki.special.preferences.styles.ooui',
83 'oojs-ui-widgets.styles',
86 $session = $this->getRequest()->getSession();
87 if ( $session->get( 'specialPreferencesSaveSuccess' ) ) {
88 // Remove session data for the success message
89 $session->remove( 'specialPreferencesSaveSuccess' );
90 $out->addModuleStyles( 'mediawiki.notification.convertmessagebox.styles' );
97 $this->msg( 'savedprefs' )->text()
99 'mw-preferences-messagebox mw-notify-success'
104 $this->addHelpLink( 'Help:Preferences' );
106 // Load the user from the primary DB to reduce CAS errors on double post (T95839)
107 if ( $this->getRequest()->wasPosted() ) {
108 $user = $this->getUser()->getInstanceForUpdate() ?
: $this->getUser();
110 $user = $this->getUser();
113 $htmlForm = $this->getFormObject( $user, $this->getContext() );
114 $sectionTitles = $htmlForm->getPreferenceSections();
117 foreach ( $sectionTitles as $key ) {
120 'label' => $htmlForm->getLegend( $key ),
123 $out->addJsConfigVars( 'wgPreferencesTabs', $prefTabs );
125 $out->addHTML( new FieldLayout(
126 new SearchInputWidget( [
127 'placeholder' => $this->msg( 'searchprefs' )->text(),
130 'classes' => [ 'mw-prefs-search' ],
131 'label' => $this->msg( 'searchprefs' )->text(),
132 'invisibleLabel' => true,
140 * Get the preferences form to use.
142 * @param IContextSource $context
143 * @return PreferencesFormOOUI|HTMLForm
145 protected function getFormObject( $user, IContextSource
$context ) {
146 $form = $this->preferencesFactory
->getForm( $user, $context, PreferencesFormOOUI
::class );
150 protected function showResetForm() {
151 if ( !$this->getAuthority()->isAllowed( 'editmyoptions' ) ) {
152 throw new PermissionsError( 'editmyoptions' );
155 $this->getOutput()->addWikiMsg( 'prefs-reset-intro' );
160 'label-message' => 'prefs-reset-confirm',
164 // TODO: disable the submit button if the checkbox is not checked
165 HTMLForm
::factory( 'ooui', $desc, $this->getContext(), 'prefs-restore' )
166 ->setTitle( $this->getPageTitle( 'reset' ) ) // Reset subpage
167 ->setSubmitTextMsg( 'restoreprefs' )
168 ->setSubmitDestructive()
169 ->setSubmitCallback( [ $this, 'submitReset' ] )
171 ->setCancelTarget( $this->getPageTitle() )
175 public function submitReset( $formData ) {
176 if ( !$this->getAuthority()->isAllowed( 'editmyoptions' ) ) {
177 throw new PermissionsError( 'editmyoptions' );
180 $user = $this->getUser()->getInstanceForUpdate();
181 $this->userOptionsManager
->resetAllOptions( $user );
182 $user->saveSettings();
184 // Set session data for the success message
185 $this->getRequest()->getSession()->set( 'specialPreferencesSaveSuccess', 1 );
187 $url = $this->getPageTitle()->getFullUrlForRedirect();
188 $this->getOutput()->redirect( $url );
193 protected function getGroupName() {
199 * Retain the old class name for backwards compatibility.
200 * @deprecated since 1.41
202 class_alias( SpecialPreferences
::class, 'SpecialPreferences' );