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