Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialGloballyWantedFiles
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 10
342
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 forceExistenceCheck
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 existenceCheck
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPageHeader
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 isCacheable
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 isListed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getQueryInfo
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 formatResult
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
30
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Implements Special:GloballyWantedFiles, the global equivalent to
4 * Special:WantedFiles
5 *
6 * @file
7 * @author Brian Wolff <bawolff+wn@gmail.com>
8 * @ingroup SpecialPage
9 */
10
11namespace MediaWiki\Extension\GlobalUsage;
12
13use MediaWiki\Cache\LinkBatchFactory;
14use MediaWiki\Html\Html;
15use MediaWiki\SpecialPage\SpecialPage;
16use MediaWiki\SpecialPage\WantedQueryPage;
17use MediaWiki\Title\Title;
18use MediaWiki\WikiMap\WikiMap;
19use RepoGroup;
20use Skin;
21use stdClass;
22use Wikimedia\Rdbms\IConnectionProvider;
23
24class SpecialGloballyWantedFiles extends WantedQueryPage {
25
26    private RepoGroup $repoGroup;
27
28    public function __construct(
29        IConnectionProvider $dbProvider,
30        LinkBatchFactory $linkBatchFactory,
31        RepoGroup $repoGroup
32    ) {
33        parent::__construct( 'GloballyWantedFiles' );
34        $this->setDatabaseProvider( $dbProvider );
35        $this->setLinkBatchFactory( $linkBatchFactory );
36        $this->repoGroup = $repoGroup;
37    }
38
39    /**
40     * Main execution function. Use the parent if we're on the right wiki.
41     * If we're not on a shared repo, try to redirect there.
42     * @param string $par
43     */
44    public function execute( $par ) {
45        if ( GlobalUsage::onSharedRepo() ) {
46            parent::execute( $par );
47        } else {
48            GlobalUsage::redirectSpecialPageToSharedRepo( $this->getContext() );
49        }
50    }
51
52    protected function forceExistenceCheck() {
53        // Same as MediaWiki core WantedFiles
54        return true;
55    }
56
57    protected function existenceCheck( Title $title ) {
58        // Same as MediaWiki core WantedFiles
59        return (bool)$this->repoGroup->findFile( $title );
60    }
61
62    /**
63     * Output an extra header
64     *
65     * @return string html to output
66     */
67    public function getPageHeader() {
68        if ( $this->repoGroup->hasForeignRepos() ) {
69            return $this->msg( 'globallywantedfiles-foreign-repo' )->parseAsBlock();
70        } else {
71            return parent::getPageHeader();
72        }
73    }
74
75    /**
76     * Don't want to do cached handling on non-shared repo, since we only redirect.
77     *
78     * Also make sure that GlobalUsage db same as shared repo.
79     * (To catch the unlikely case where GlobalUsage db is different db from the
80     * shared repo db).
81     * @return bool
82     */
83    public function isCacheable() {
84        global $wgGlobalUsageDatabase;
85        return GlobalUsage::onSharedRepo()
86            && ( !$wgGlobalUsageDatabase || $wgGlobalUsageDatabase === WikiMap::getCurrentWikiId() );
87    }
88
89    /**
90     * Only list this special page on the wiki that is the shared repo.
91     *
92     * @return bool Should this be listed in Special:SpecialPages
93     */
94    public function isListed() {
95        return GlobalUsage::onSharedRepo();
96    }
97
98    public function getQueryInfo() {
99        return GlobalUsage::getWantedFilesQueryInfo();
100    }
101
102    /**
103     * Format a row of the results
104     *
105     * We need to override this in order to link to Special:GlobalUsage
106     * instead of Special:WhatLinksHere.
107     *
108     * @param Skin $skin
109     * @param stdClass $result A row from the database
110     * @return string HTML to output
111     */
112    public function formatResult( $skin, $result ) {
113        // If some of the client wikis are $wgCapitalLinks = false
114        // but the shared repo is not, then we will get some false positives
115        // here. To avoid as much confusion as possible, use the raw (lowercase) version
116        // of the title for displaying, but the safe (properly cased) version of
117        // the title for any checks. (Bug 71359)
118        $title = Title::makeTitle( $result->namespace, $result->title );
119        $safeTitle = Title::makeTitleSafe( $result->namespace, $result->title );
120        if ( $title instanceof Title && $safeTitle instanceof Title ) {
121            $linkRenderer = $this->getLinkRenderer();
122            $pageLink = $linkRenderer->makeLink( $title );
123            if ( $safeTitle->isKnown() &&
124                $this->repoGroup->findFile( $safeTitle )
125            ) {
126                // If the title exists and is a file, than strike.
127                // The RepoGroup::findFile call should already be cached from LinkRenderer::makeLink call
128                // so it shouldn't be too expensive. However a future @todo would be
129                // to do preload existence checks for files all at once via RepoGroup::findFiles.
130                $pageLink = Html::rawElement( 'del', [], $pageLink );
131            }
132
133            $gu = SpecialPage::getTitleFor( 'GlobalUsage', $title->getDBKey() );
134            $label = $this->msg( 'nlinks' )->numParams( $result->value )->text();
135            $usages = $linkRenderer->makeLink( $gu, $label );
136
137            return $this->getLanguage()->specialList( $pageLink, $usages );
138        } else {
139            return $this->msg( 'wantedpages-badtitle', $result->title )->escaped();
140        }
141    }
142
143    protected function getGroupName() {
144        return 'maintenance';
145    }
146}