Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 37 |
|
0.00% |
0 / 11 |
CRAP | |
0.00% |
0 / 1 |
SpecialMostGloballyLinkedFiles | |
0.00% |
0 / 37 |
|
0.00% |
0 / 11 |
240 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
isExpensive | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isSyndicated | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isCacheable | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getQueryInfo | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
2 | |||
getCellHtml | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
assertOnSharedRepo | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
isListed | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRecacheDB | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
getGroupName | |
0.00% |
0 / 1 |
|
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 | |
10 | namespace MediaWiki\Extension\GlobalUsage; |
11 | |
12 | use MediaWiki\Cache\LinkBatchFactory; |
13 | use MediaWiki\SpecialPage\ImageQueryPage; |
14 | use MediaWiki\WikiMap\WikiMap; |
15 | use RuntimeException; |
16 | use Wikimedia\Rdbms\IConnectionProvider; |
17 | use Wikimedia\Rdbms\IDatabase; |
18 | |
19 | class 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 | 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 | } |