Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.55% covered (success)
98.55%
68 / 69
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
GlobalBlockingLinkBuilder
98.55% covered (success)
98.55%
68 / 69
75.00% covered (warning)
75.00%
3 / 4
21
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 buildSubtitleLinks
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
1 / 1
12
 maybeLinkUserpage
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 getActionLinks
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2
3namespace MediaWiki\Extension\GlobalBlocking\Services;
4
5use HtmlArmor;
6use Language;
7use MediaWiki\Config\ServiceOptions;
8use MediaWiki\Linker\LinkRenderer;
9use MediaWiki\Permissions\Authority;
10use MediaWiki\SpecialPage\SpecialPage;
11use MediaWiki\Title\Title;
12use MediaWiki\WikiMap\WikiMap;
13use MessageLocalizer;
14
15/**
16 * A service that builds links to other global blocking special pages and also
17 * builds user links to user pages on other wikis.
18 *
19 * @since 1.42
20 */
21class GlobalBlockingLinkBuilder {
22
23    public const CONSTRUCTOR_OPTIONS = [
24        'GlobalBlockingAllowGlobalAccountBlocks',
25        'ApplyGlobalBlocks',
26    ];
27
28    private ServiceOptions $options;
29    private LinkRenderer $linkRenderer;
30    private MessageLocalizer $messageLocalizer;
31    private Language $language;
32
33    public function __construct(
34        ServiceOptions $options,
35        LinkRenderer $linkRenderer,
36        MessageLocalizer $messageLocalizer,
37        Language $language
38    ) {
39        $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
40        $this->options = $options;
41        $this->linkRenderer = $linkRenderer;
42        $this->messageLocalizer = $messageLocalizer;
43        $this->language = $language;
44    }
45
46    /**
47     * Build links to other global blocking special pages. These are for use in the subtitle of
48     * GlobalBlocking extension special pages.
49     *
50     * @param SpecialPage $sp SpecialPage instance for context
51     * @return string links to special pages
52     */
53    public function buildSubtitleLinks( SpecialPage $sp ): string {
54        // Add a few useful links
55        $links = [];
56        $pagetype = $sp->getName();
57
58        // Don't show a link to a special page on the special page itself.
59        // Show the links only if the user has sufficient rights
60        if ( $pagetype !== 'GlobalBlockList' ) {
61            $title = SpecialPage::getTitleFor( 'GlobalBlockList' );
62            $links[] = $this->linkRenderer->makeKnownLink( $title, $sp->msg( 'globalblocklist' )->text() );
63        }
64        $canBlock = $sp->getAuthority()->isAllowed( 'globalblock' );
65        if ( $pagetype !== 'GlobalBlock' && $canBlock ) {
66            $title = SpecialPage::getTitleFor( 'GlobalBlock' );
67            $messageKey = $this->options->get( 'GlobalBlockingAllowGlobalAccountBlocks' ) ?
68                'globalblocking-goto-block-new' : 'globalblocking-goto-block';
69            $links[] = $this->linkRenderer->makeKnownLink( $title, $sp->msg( $messageKey )->text() );
70        }
71        if ( $pagetype !== 'RemoveGlobalBlock' && $canBlock ) {
72            $title = SpecialPage::getTitleFor( 'RemoveGlobalBlock' );
73            $links[] = $this->linkRenderer->makeKnownLink(
74                $title, $sp->msg( 'globalblocking-goto-unblock' )->text() );
75        }
76        if ( $pagetype !== 'GlobalBlockStatus' && $sp->getAuthority()->isAllowed( 'globalblock-whitelist' ) ) {
77            $title = SpecialPage::getTitleFor( 'GlobalBlockStatus' );
78            $links[] = $this->linkRenderer->makeKnownLink(
79                $title, $sp->msg( 'globalblocking-goto-status' )->text() );
80        }
81        if ( $pagetype === 'GlobalBlock' && $sp->getAuthority()->isAllowed( 'editinterface' ) ) {
82            $title = Title::makeTitle( NS_MEDIAWIKI, 'Globalblocking-block-reason-dropdown' );
83            $links[] = $this->linkRenderer->makeKnownLink(
84                $title,
85                $sp->msg( 'globalblocking-block-edit-dropdown' )->text(),
86                [],
87                [ 'action' => 'edit' ]
88            );
89        }
90        if ( count( $links ) ) {
91            return $sp->msg( 'parentheses' )
92                ->rawParams( $sp->getLanguage()->pipeList( $links ) )
93                ->escaped();
94        }
95        return '';
96    }
97
98    /**
99     * If possible, build a link to the user page of the given user on the given wiki.
100     *
101     * @param string $wikiID
102     * @param string $user
103     * @return string Wikitext which may contain a external link to the user page on the given wiki.
104     */
105    public function maybeLinkUserpage( string $wikiID, string $user ): string {
106        $wiki = WikiMap::getWiki( $wikiID );
107
108        if ( $wiki ) {
109            return "[" . $wiki->getFullUrl( "User:$user" ) . " $user]";
110        }
111        return $user;
112    }
113
114    /**
115     * Get action links to be displayed after the log entry or block list entry.
116     *
117     * @param Authority $authority The authority object for the user
118     * @param string $target The target of the block for the given log entry / block list entry.
119     *
120     * @return string The action links to be displayed
121     */
122    public function getActionLinks( Authority $authority, string $target ): string {
123        $links = [];
124        $canBlock = $authority->isAllowed( 'globalblock' );
125
126        if ( $canBlock ) {
127            $links[] = $this->linkRenderer->makeKnownLink(
128                SpecialPage::getTitleFor( 'RemoveGlobalBlock' ),
129                new HtmlArmor( $this->messageLocalizer->msg( 'globalblocking-list-unblock' )->parse() ),
130                [],
131                [ 'address' => $target ]
132            );
133        }
134
135        if ( $this->options->get( 'ApplyGlobalBlocks' ) && $authority->isAllowed( 'globalblock-whitelist' ) ) {
136            $links[] = $this->linkRenderer->makeKnownLink(
137                SpecialPage::getTitleFor( 'GlobalBlockStatus' ),
138                new HtmlArmor( $this->messageLocalizer->msg( 'globalblocking-list-whitelist' )->parse() ),
139                [],
140                [ 'address' => $target ]
141            );
142        }
143
144        if ( $canBlock ) {
145            $links[] = $this->linkRenderer->makeKnownLink(
146                SpecialPage::getTitleFor( 'GlobalBlock' ),
147                new HtmlArmor( $this->messageLocalizer->msg( 'globalblocking-list-modify' )->parse() ),
148                [],
149                [ 'wpAddress' => $target ]
150            );
151        }
152
153        if ( count( $links ) ) {
154            return $this->messageLocalizer->msg( 'parentheses' )
155                ->rawParams( $this->language->pipeList( $links ) )
156                ->escaped();
157        }
158        return '';
159    }
160}