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\IDatabase;
17use Wikimedia\Rdbms\ILoadBalancer;
18
19class SpecialMostGloballyLinkedFiles extends ImageQueryPage {
20
21    public function __construct(
22        ILoadBalancer $loadBalancer,
23        LinkBatchFactory $linkBatchFactory
24    ) {
25        parent::__construct( 'MostGloballyLinkedFiles' );
26        $this->setDBLoadBalancer( $loadBalancer );
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    public function isExpensive() {
44        return true;
45    }
46
47    public function isSyndicated() {
48        return false;
49    }
50
51    /**
52     * Don't want to do cached handling on non-shared repo, since we only redirect.
53     * @return bool
54     */
55    public function isCacheable() {
56        return GlobalUsage::onSharedRepo();
57    }
58
59    /**
60     * What query to do.
61     * @return array
62     */
63    public function getQueryInfo() {
64        $this->assertOnSharedRepo();
65        return [
66            'tables' => [ 'globalimagelinks' ],
67            'fields' => [
68                'namespace' => NS_FILE,
69                'title' => 'gil_to',
70                'value' => 'COUNT(*)'
71            ],
72            'options' => [
73                'GROUP BY' => 'gil_to',
74                'HAVING' => 'COUNT(*) > 1'
75            ]
76        ];
77    }
78
79    protected function getCellHtml( $row ) {
80        return $this->msg( 'nimagelinks' )->numParams( $row->value )->escaped() . '<br />';
81    }
82
83    /**
84     * Make sure we are on the shared repo.
85     *
86     * This function should only be used as a paranoia check, and should never actually be hit.
87     * There should be actual error handling for any code path a user could hit.
88     */
89    protected function assertOnSharedRepo() {
90        if ( !GlobalUsage::onSharedRepo() ) {
91            throw new RuntimeException(
92                'Special:MostGloballyLinkedFiles should only be processed on the shared repo'
93            );
94        }
95    }
96
97    /**
98     * Only list this special page on the wiki that is the shared repo.
99     *
100     * @return bool Should this be listed in Special:SpecialPages
101     */
102    public function isListed() {
103        return GlobalUsage::onSharedRepo();
104    }
105
106    /**
107     * In most common configs (including WMF's), this wouldn't be needed. However
108     * for completeness support having the shared repo db be separate from the
109     * globalimagelinks db.
110     * @return IDatabase
111     */
112    public function getRecacheDB() {
113        global $wgGlobalUsageDatabase;
114
115        // There's no reason why we couldn't make this special page work on all wikis,
116        // it just doesn't really make sense to. We should be prevented from getting
117        // to this point by $this->isCachable(), but just to be safe:
118        $this->assertOnSharedRepo();
119
120        if ( $wgGlobalUsageDatabase === false || $wgGlobalUsageDatabase === WikiMap::getCurrentWikiId() ) {
121            // We are using the local wiki
122            return parent::getRecacheDB();
123        } else {
124            // The global usage db could be on a different db
125            return GlobalUsage::getGlobalDB(
126                DB_REPLICA,
127                [ $this->getName(), 'QueryPage::recache', 'vslow' ]
128            );
129        }
130    }
131
132    protected function getGroupName() {
133        return 'highuse';
134    }
135}