Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.22% covered (warning)
82.22%
37 / 45
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
InfoboxHandler
82.22% covered (warning)
82.22%
37 / 45
50.00% covered (danger)
50.00%
2 / 4
15.10
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
 addInfoBox
91.43% covered (success)
91.43%
32 / 35
0.00% covered (danger)
0.00%
0 / 1
8.04
 onSpecialContributionsBeforeMainOutput
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 onSpecialPageBeforeExecute
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace MediaWiki\IPInfo\HookHandler;
4
5use CollapsibleFieldsetLayout;
6use ExtensionRegistry;
7use MediaWiki\Hook\SpecialContributionsBeforeMainOutputHook;
8use MediaWiki\MediaWikiServices;
9use MediaWiki\Output\OutputPage;
10use MediaWiki\Permissions\PermissionManager;
11use MediaWiki\SpecialPage\Hook\SpecialPageBeforeExecuteHook;
12use MediaWiki\SpecialPage\SpecialPage;
13use MediaWiki\User\Options\UserOptionsLookup;
14use OOUI\PanelLayout;
15use Wikimedia\IPUtils;
16
17class InfoboxHandler implements
18    SpecialContributionsBeforeMainOutputHook,
19    SpecialPageBeforeExecuteHook
20{
21    private PermissionManager $permissionManager;
22
23    private UserOptionsLookup $userOptionsLookup;
24
25    public function __construct(
26        PermissionManager $permissionManager,
27        UserOptionsLookup $userOptionsLookup
28    ) {
29        $this->permissionManager = $permissionManager;
30        $this->userOptionsLookup = $userOptionsLookup;
31    }
32
33    /**
34     * This function is used to add an info box on Special:Contributions and Special:DeletedContributions
35     *
36     * @param string $username Username or IP Address
37     * @param SpecialPage $sp
38     */
39    private function addInfoBox( $username, $sp ) {
40        // T309363: hide the panel on mobile until T268177 is resolved
41        $services = MediaWikiServices::getInstance();
42        $extensionRegistry = ExtensionRegistry::getInstance();
43        if (
44            $extensionRegistry->isLoaded( 'MobileFrontend' ) &&
45            $services->getService( 'MobileFrontend.Context' )->shouldDisplayMobileView()
46        ) {
47            return;
48        }
49
50        $accessingUser = $sp->getUser();
51        $isBetaFeaturesLoaded = $extensionRegistry->isLoaded( 'BetaFeatures' );
52        if (
53            !$this->permissionManager->userHasRight( $accessingUser, 'ipinfo' ) ||
54            ( $isBetaFeaturesLoaded &&
55                !$this->userOptionsLookup->getOption( $accessingUser, 'ipinfo-beta-feature-enable' )
56            )
57        ) {
58            return;
59        }
60        // Check if the target is an IP address
61        if ( IPUtils::isValid( $username ) ) {
62            $username = IPUtils::prettifyIP( $username );
63        } else {
64            $username = null;
65        }
66
67        if ( !$username ) {
68            return;
69        }
70
71        $out = $sp->getOutput();
72        $out->addModules( 'ext.ipInfo' );
73        $out->addModuleStyles( 'ext.ipInfo.styles' );
74        $panelLayout = new PanelLayout( [
75            'classes' => [ 'ext-ipinfo-panel-layout' ],
76            'framed' => true,
77            'expanded' => false,
78            'padded' => true,
79            'content' => ( new CollapsibleFieldsetLayout(
80                [
81                    'label' => $sp->msg( 'ipinfo-infobox-title' ),
82                    'collapsed' => true,
83                    'classes' => [ 'ext-ipinfo-collapsible-layout' ],
84                    'infusable' => true,
85                ]
86            ) ),
87        ] );
88        OutputPage::setupOOUI();
89        $out->addHTML( $panelLayout );
90    }
91
92    /** @inheritDoc */
93    public function onSpecialContributionsBeforeMainOutput( $id, $user, $sp ) {
94        if ( $sp->getName() !== 'Contributions' ) {
95            return;
96        }
97
98        $this->addInfoBox( $user->getName(), $sp );
99    }
100
101    /** @inheritDoc */
102    public function onSpecialPageBeforeExecute( $sp, $subPage ) {
103        if ( $sp->getName() !== 'DeletedContributions' ) {
104            return;
105        }
106
107        if ( $subPage === null ) {
108            $subPage = $sp->getRequest()->getText( 'target' );
109        }
110
111        $this->addInfoBox( $subPage, $sp );
112    }
113}