Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialMostLinkedTemplates
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 10
132
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
 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
 sortDescending
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 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 preprocessResults
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 / 15
0.00% covered (danger)
0.00%
0 / 1
6
 makeWlhLink
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getGroupName
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 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @file
5 */
6
7namespace MediaWiki\Specials;
8
9use MediaWiki\Deferred\LinksUpdate\TemplateLinksTable;
10use MediaWiki\Html\Html;
11use MediaWiki\Linker\Linker;
12use MediaWiki\Linker\LinksMigration;
13use MediaWiki\Page\LinkBatchFactory;
14use MediaWiki\Skin\Skin;
15use MediaWiki\SpecialPage\QueryPage;
16use MediaWiki\SpecialPage\SpecialPage;
17use MediaWiki\Title\Title;
18use stdClass;
19use Wikimedia\Rdbms\IConnectionProvider;
20use Wikimedia\Rdbms\IReadableDatabase;
21use Wikimedia\Rdbms\IResultWrapper;
22
23/**
24 * List of templates with a large number of transclusion links,
25 * i.e. "most used" templates
26 *
27 * @ingroup SpecialPage
28 * @author Rob Church <robchur@gmail.com>
29 */
30class SpecialMostLinkedTemplates extends QueryPage {
31
32    private LinksMigration $linksMigration;
33
34    public function __construct(
35        IConnectionProvider $dbProvider,
36        LinkBatchFactory $linkBatchFactory,
37        LinksMigration $linksMigration
38    ) {
39        parent::__construct( 'Mostlinkedtemplates' );
40        $this->setDatabaseProvider( $dbProvider );
41        $this->setLinkBatchFactory( $linkBatchFactory );
42        $this->linksMigration = $linksMigration;
43    }
44
45    /**
46     * Is this report expensive, i.e should it be cached?
47     *
48     * @return bool
49     */
50    public function isExpensive() {
51        return true;
52    }
53
54    /**
55     * Is there a feed available?
56     *
57     * @return bool
58     */
59    public function isSyndicated() {
60        return false;
61    }
62
63    /**
64     * Sort the results in descending order?
65     *
66     * @return bool
67     */
68    public function sortDescending() {
69        return true;
70    }
71
72    /** @inheritDoc */
73    public function getQueryInfo() {
74        $queryInfo = $this->linksMigration->getQueryInfo( 'templatelinks' );
75        [ $ns, $title ] = $this->linksMigration->getTitleFields( 'templatelinks' );
76        return [
77            'tables' => $queryInfo['tables'],
78            'fields' => [
79                'namespace' => $ns,
80                'title' => $title,
81                'value' => 'COUNT(*)'
82            ],
83            'options' => [ 'GROUP BY' => [ $ns, $title ] ],
84            'join_conds' => $queryInfo['joins']
85        ];
86    }
87
88    /**
89     * Pre-cache page existence to speed up link generation
90     *
91     * @param IReadableDatabase $db
92     * @param IResultWrapper $res
93     */
94    public function preprocessResults( $db, $res ) {
95        $this->executeLBFromResultWrapper( $res );
96    }
97
98    /**
99     * Format a result row
100     *
101     * @param Skin $skin
102     * @param stdClass $result Result row
103     * @return string
104     */
105    public function formatResult( $skin, $result ) {
106        $title = Title::makeTitleSafe( $result->namespace, $result->title );
107        if ( !$title ) {
108            return Html::element(
109                'span',
110                [ 'class' => 'mw-invalidtitle' ],
111                Linker::getInvalidTitleDescription(
112                    $this->getContext(),
113                    $result->namespace,
114                    $result->title
115                )
116            );
117        }
118
119        return $this->getLanguage()->specialList(
120            $this->getLinkRenderer()->makeLink( $title ),
121            $this->makeWlhLink( $title, $result )
122        );
123    }
124
125    /**
126     * Make a "what links here" link for a given title
127     *
128     * @param Title $title Title to make the link for
129     * @param stdClass $result Result row
130     * @return string
131     */
132    private function makeWlhLink( $title, $result ) {
133        $wlh = SpecialPage::getTitleFor( 'Whatlinkshere', $title->getPrefixedText() );
134        $label = $this->msg( 'ntransclusions' )->numParams( $result->value )->text();
135
136        return $this->getLinkRenderer()->makeLink( $wlh, $label );
137    }
138
139    /** @inheritDoc */
140    protected function getGroupName() {
141        return 'highuse';
142    }
143
144    /** @inheritDoc */
145    protected function getRecacheDB() {
146        return $this->getDatabaseProvider()->getReplicaDatabase(
147            TemplateLinksTable::VIRTUAL_DOMAIN,
148            'vslow'
149        );
150    }
151}
152
153/**
154 * Retain the old class name for backwards compatibility.
155 * @deprecated since 1.41
156 */
157class_alias( SpecialMostLinkedTemplates::class, 'SpecialMostLinkedTemplates' );