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