Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
58.97% covered (warning)
58.97%
23 / 39
66.67% covered (warning)
66.67%
4 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialGlobalPreferences
58.97% covered (warning)
58.97%
23 / 39
66.67% covered (warning)
66.67%
4 / 6
24.67
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
6
 getFormObject
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 showResetForm
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 addHelpLink
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 submitReset
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace GlobalPreferences;
4
5use MediaWiki\Context\DerivativeContext;
6use MediaWiki\Context\IContextSource;
7use MediaWiki\Exception\ErrorPageError;
8use MediaWiki\Exception\PermissionsError;
9use MediaWiki\Exception\UserNotLoggedIn;
10use MediaWiki\HTMLForm\HTMLForm;
11use MediaWiki\Permissions\PermissionManager;
12use MediaWiki\Specials\SpecialPreferences;
13use MediaWiki\User\User;
14use PreferencesFormOOUI;
15
16class SpecialGlobalPreferences extends SpecialPreferences {
17
18    public function __construct(
19        private readonly PermissionManager $permissionManager,
20        private readonly GlobalPreferencesFactory $preferencesFactory,
21    ) {
22        parent::__construct();
23        $this->mName = 'GlobalPreferences';
24    }
25
26    /**
27     * Execute the special page.
28     * @param null|string $par The subpage name, if any.
29     * @throws ErrorPageError
30     * @throws UserNotLoggedIn
31     */
32    public function execute( $par ) {
33        // Remove subpages other than 'reset', including trailing slash.
34        if ( $par !== null && $par !== 'reset' ) {
35            $this->getOutput()->redirect( rtrim( $this->getPageTitle()->getCanonicalURL(), '/' ) );
36            return;
37        }
38        // Dirty override to check user can set global prefs.
39        if ( !$this->getUser()->isNamed() ) {
40            // @todo use our own error messages here
41            $this->setHeaders();
42            throw new UserNotLoggedIn();
43        }
44        if ( !$this->preferencesFactory->isUserGlobalized( $this->getUser() ) ) {
45            $this->setHeaders();
46            throw new ErrorPageError( 'globalprefs-error-header', 'globalprefs-notglobal' );
47        }
48
49        // Add link back to (local) Preferences.
50        if ( $par === null ) {
51            $link = $this->getLinkRenderer()->makeKnownLink(
52                static::getSafeTitleFor( 'Preferences' ),
53                $this->msg( 'mypreferences' )->text()
54            );
55            // Same left-arrow as used in Skin::subPageSubtitle().
56            $this->getOutput()->addSubtitle( "&lt; $link" );
57        }
58
59        // Add module styles and scripts separately
60        // so non-JS users get the styles quicker and to avoid a FOUC.
61        $this->getOutput()->addModuleStyles( 'ext.GlobalPreferences.global-nojs' );
62        $this->getOutput()->addModules( 'ext.GlobalPreferences.global' );
63
64        parent::execute( $par );
65    }
66
67    /**
68     * Get the preferences form to use.
69     * @param User $user
70     * @param IContextSource $context
71     * @return PreferencesFormOOUI|HTMLForm
72     */
73    protected function getFormObject( $user, IContextSource $context ) {
74        $form = $this->preferencesFactory->getForm( $user, $context, GlobalPreferencesFormOOUI::class );
75        return $form;
76    }
77
78    /**
79     * Display the preferences-reset confirmation page.
80     * This is identical to parent::showResetForm except with the message names changed.
81     * @throws PermissionsError
82     */
83    protected function showResetForm() {
84        if ( !$this->permissionManager->userHasRight( $this->getUser(), 'editmyoptions' ) ) {
85            throw new PermissionsError( 'editmyoptions' );
86        }
87
88        $this->getOutput()->addWikiMsg( 'globalprefs-reset-intro' );
89
90        $context = new DerivativeContext( $this->getContext() );
91        // Reset subpage
92        $context->setTitle( $this->getPageTitle( 'reset' ) );
93        $htmlForm = HTMLForm::factory( 'ooui', [], $context, 'globalprefs-restore' );
94
95        $htmlForm->setSubmitTextMsg( 'globalprefs-restoreprefs' );
96        $htmlForm->setSubmitDestructive();
97        $htmlForm->setSubmitCallback( [ $this, 'submitReset' ] );
98
99        $htmlForm->show();
100    }
101
102    /**
103     * Adds help link with an icon via page indicators.
104     * @param string $to Ignored.
105     * @param bool $overrideBaseUrl Whether $url is a full URL, to avoid MW.o.
106     */
107    public function addHelpLink( $to, $overrideBaseUrl = false ) {
108        parent::addHelpLink( 'Help:Extension:GlobalPreferences', $overrideBaseUrl );
109    }
110
111    /**
112     * Handle reset submission (subpage '/reset').
113     * @param string[] $formData The submitted data (not used).
114     * @return bool
115     * @throws PermissionsError
116     */
117    public function submitReset( $formData ) {
118        if ( !$this->permissionManager->userHasRight( $this->getUser(), 'editmyoptions' ) ) {
119            throw new PermissionsError( 'editmyoptions' );
120        }
121
122        $this->preferencesFactory->resetGlobalUserSettings( $this->getUser() );
123
124        $url = $this->getPageTitle()->getFullURL( 'success' );
125
126        $this->getOutput()->redirect( $url );
127
128        return true;
129    }
130}