Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialMostGloballyLinkedFiles
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 11
240
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
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
 isExpensive
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isSyndicated
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isCacheable
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 / 13
0.00% covered (danger)
0.00%
0 / 1
2
 getCellHtml
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 assertOnSharedRepo
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 isListed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRecacheDB
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Special page to list files with most global usages
4 *
5 * @file
6 * @ingroup SpecialPage
7 * @author Brian Wolff <bawolff+wn@gmail.com>
8 */
9
10namespace MediaWiki\Extension\GlobalUsage;
11
12use MediaWiki\Cache\LinkBatchFactory;
13use MediaWiki\SpecialPage\ImageQueryPage;
14use MediaWiki\WikiMap\WikiMap;
15use RuntimeException;
16use Wikimedia\Rdbms\IConnectionProvider;
17use Wikimedia\Rdbms\IDatabase;
18
19class SpecialMostGloballyLinkedFiles extends ImageQueryPage {
20
21    public function __construct(
22        IConnectionProvider $dbProvider,
23        LinkBatchFactory $linkBatchFactory
24    ) {
25        parent::__construct( 'MostGloballyLinkedFiles' );
26        $this->setDatabaseProvider( $dbProvider );
27        $this->setLinkBatchFactory( $linkBatchFactory );
28    }
29
30    /**
31     * Main execution function. Use the parent if we're on the right wiki.
32     * If we're not on a shared repo, try to redirect there.
33     * @param string $par
34     */
35    public function execute( $par ) {
36        if ( GlobalUsage::onSharedRepo() ) {
37            parent::execute( $par );
38        } else {
39            GlobalUsage::redirectSpecialPageToSharedRepo( $this->getContext() );
40        }
41    }
42
43    /** @inheritDoc */
44    public function isExpensive() {
45        return true;
46    }
47
48    /** @inheritDoc */
49    public function isSyndicated() {
50        return false;
51    }
52
53    /**
54     * Don't want to do cached handling on non-shared repo, since we only redirect.
55     * @return bool
56     */
57    public function isCacheable() {
58        return GlobalUsage::onSharedRepo();
59    }
60
61    /**
62     * What query to do.
63     * @return array
64     */
65    public function getQueryInfo() {
66        $this->assertOnSharedRepo();
67        return [
68            'tables' => [ 'globalimagelinks' ],
69            'fields' => [
70                'namespace' => NS_FILE,
71                'title' => 'gil_to',
72                'value' => 'COUNT(*)'
73            ],
74            'options' => [
75                'GROUP BY' => 'gil_to',
76                'HAVING' => 'COUNT(*) > 1'
77            ]
78        ];
79    }
80
81    /** @inheritDoc */
82    protected function getCellHtml( $row ) {
83        return $this->msg( 'nimagelinks' )->numParams( $row->value )->escaped() . '<br />';
84    }
85
86    /**
87     * Make sure we are on the shared repo.
88     *
89     * This function should only be used as a paranoia check, and should never actually be hit.
90     * There should be actual error handling for any code path a user could hit.
91     */
92    protected function assertOnSharedRepo() {
93        if ( !GlobalUsage::onSharedRepo() ) {
94            throw new RuntimeException(
95                'Special:MostGloballyLinkedFiles should only be processed on the shared repo'
96            );
97        }
98    }
99
100    /**
101     * Only list this special page on the wiki that is the shared repo.
102     *
103     * @return bool Should this be listed in Special:SpecialPages
104     */
105    public function isListed() {
106        return GlobalUsage::onSharedRepo();
107    }
108
109    /**
110     * In most common configs (including WMF's), this wouldn't be needed. However
111     * for completeness support having the shared repo db be separate from the
112     * globalimagelinks db.
113     * @return IDatabase
114     */
115    public function getRecacheDB() {
116        // There's no reason why we couldn't make this special page work on all wikis,
117        // it just doesn't really make sense to. We should be prevented from getting
118        // to this point by $this->isCachable(), but just to be safe:
119        $this->assertOnSharedRepo();
120
121        $globalUsageDatabase = $this->getConfig()->get( 'GlobalUsageDatabase' );
122        if ( $globalUsageDatabase === false || $globalUsageDatabase === WikiMap::getCurrentWikiId() ) {
123            // We are using the local wiki
124            return parent::getRecacheDB();
125        } else {
126            // The global usage db could be on a different db
127            return GlobalUsage::getGlobalDB(
128                DB_REPLICA,
129                [ $this->getName(), 'QueryPage::recache', 'vslow' ]
130            );
131        }
132    }
133
134    /** @inheritDoc */
135    protected function getGroupName() {
136        return 'highuse';
137    }
138}