Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.49% covered (warning)
86.49%
32 / 37
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
PermissionsError
86.49% covered (warning)
86.49%
32 / 37
0.00% covered (danger)
0.00%
0 / 2
12.36
0.00% covered (danger)
0.00%
0 / 1
 __construct
94.12% covered (success)
94.12%
32 / 34
0.00% covered (danger)
0.00%
0 / 1
10.02
 report
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
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.
7 *
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.
12 *
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
17 *
18 * @file
19 */
20
21use MediaWiki\Context\RequestContext;
22use MediaWiki\Debug\DeprecationHelper;
23use MediaWiki\MediaWikiServices;
24use MediaWiki\Permissions\PermissionStatus;
25
26/**
27 * Show an error when a user tries to do something they do not have the necessary
28 * permissions for.
29 *
30 * @newable
31 * @since 1.18
32 * @ingroup Exception
33 */
34class PermissionsError extends ErrorPageError {
35
36    use DeprecationHelper;
37
38    private ?string $permission;
39    private PermissionStatus $status;
40
41    /**
42     * @stable to call
43     *
44     * @param string|null $permission A permission name or null if unknown
45     * @param PermissionStatus|array $status PermissionStatus containing an array of errors,
46     *   or an error array like in PermissionManager::getPermissionErrors();
47     *   must not be empty if $permission is null
48     */
49    public function __construct( ?string $permission, $status = [] ) {
50        $this->deprecatePublicProperty( 'permission', '1.43' );
51        $this->deprecatePublicPropertyFallback( 'errors', '1.43',
52            function () {
53                return $this->status->toLegacyErrorArray();
54            },
55            function ( $errors ) {
56                $this->status = PermissionStatus::newEmpty();
57                foreach ( $errors as $error ) {
58                    if ( is_array( $error ) ) {
59                        // @phan-suppress-next-line PhanParamTooFewUnpack
60                        $this->status->fatal( ...$error );
61                    } else {
62                        $this->status->fatal( $error );
63                    }
64                }
65            }
66        );
67
68        if ( is_array( $status ) ) {
69            $errors = $status;
70            $status = PermissionStatus::newEmpty();
71            foreach ( $errors as $error ) {
72                if ( is_array( $error ) ) {
73                    // @phan-suppress-next-line PhanParamTooFewUnpack
74                    $status->fatal( ...$error );
75                } else {
76                    $status->fatal( $error );
77                }
78            }
79        } elseif ( !( $status instanceof PermissionStatus ) ) {
80            throw new \InvalidArgumentException( __METHOD__ .
81                ': $status must be PermissionStatus or array, got ' . get_debug_type( $status ) );
82        }
83
84        if ( $permission === null && $status->isGood() ) {
85            throw new \InvalidArgumentException( __METHOD__ .
86                ': $permission and $status cannot both be empty' );
87        }
88
89        $this->permission = $permission;
90
91        if ( $status->isGood() ) {
92            $status = MediaWikiServices::getInstance()
93                ->getPermissionManager()
94                // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Null on permission is check when used here
95                ->newFatalPermissionDeniedStatus( $this->permission, RequestContext::getMain() );
96        }
97
98        $this->status = $status;
99
100        // Give the parent class something to work with
101        parent::__construct( 'permissionserrors', $status->getMessages()[0] );
102    }
103
104    public function report( $action = self::SEND_OUTPUT ) {
105        global $wgOut;
106
107        $wgOut->showPermissionStatus( $this->status, $this->permission );
108        if ( $action === self::SEND_OUTPUT ) {
109            $wgOut->output();
110        }
111    }
112}