Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialLonelyPages
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 8
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 getPageHeader
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
 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
 getQueryInfo
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
6
 getOrderFields
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Implements Special:Lonelypages
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup SpecialPage
22 */
23
24namespace MediaWiki\Specials;
25
26use MediaWiki\Cache\LinkBatchFactory;
27use MediaWiki\Languages\LanguageConverterFactory;
28use MediaWiki\Linker\LinksMigration;
29use MediaWiki\SpecialPage\PageQueryPage;
30use MediaWiki\Title\NamespaceInfo;
31use Wikimedia\Rdbms\IConnectionProvider;
32
33/**
34 * A special page looking for articles with no article linking to them,
35 * thus being lonely.
36 *
37 * @ingroup SpecialPage
38 */
39class SpecialLonelyPages extends PageQueryPage {
40
41    private NamespaceInfo $namespaceInfo;
42    private LinksMigration $linksMigration;
43
44    /**
45     * @param NamespaceInfo $namespaceInfo
46     * @param IConnectionProvider $dbProvider
47     * @param LinkBatchFactory $linkBatchFactory
48     * @param LanguageConverterFactory $languageConverterFactory
49     * @param LinksMigration $linksMigration
50     */
51    public function __construct(
52        NamespaceInfo $namespaceInfo,
53        IConnectionProvider $dbProvider,
54        LinkBatchFactory $linkBatchFactory,
55        LanguageConverterFactory $languageConverterFactory,
56        LinksMigration $linksMigration
57    ) {
58        parent::__construct( 'Lonelypages' );
59        $this->namespaceInfo = $namespaceInfo;
60        $this->setDatabaseProvider( $dbProvider );
61        $this->setLinkBatchFactory( $linkBatchFactory );
62        $this->setLanguageConverter( $languageConverterFactory->getLanguageConverter( $this->getContentLanguage() ) );
63        $this->linksMigration = $linksMigration;
64    }
65
66    protected function getPageHeader() {
67        return $this->msg( 'lonelypagestext' )->parseAsBlock();
68    }
69
70    protected function sortDescending() {
71        return false;
72    }
73
74    public function isExpensive() {
75        return true;
76    }
77
78    public function isSyndicated() {
79        return false;
80    }
81
82    public function getQueryInfo() {
83        $queryInfo = $this->linksMigration->getQueryInfo( 'pagelinks', 'pagelinks', 'LEFT JOIN' );
84        $tables = [ 'page', 'linktarget', 'templatelinks', 'pagelinks' ];
85        $conds = [
86            'pl_from' => null,
87            'page_namespace' => $this->namespaceInfo->getContentNamespaces(),
88            'page_is_redirect' => 0,
89            'tl_from' => null,
90        ];
91        $joinConds = [
92            'templatelinks' => [ 'LEFT JOIN', [ 'tl_target_id=lt_id' ] ],
93            'linktarget' => [
94                'LEFT JOIN', [
95                    "lt_namespace = page_namespace",
96                    "lt_title = page_title"
97                ]
98            ]
99        ];
100
101        if ( !in_array( 'linktarget', $queryInfo['tables'] ) ) {
102            $joinConds['pagelinks'] = [
103                'LEFT JOIN', [
104                    "pl_namespace = page_namespace",
105                    "pl_title = page_title"
106                ]
107            ];
108        }
109
110        // Allow extensions to modify the query
111        $this->getHookRunner()->onLonelyPagesQuery( $tables, $conds, $joinConds );
112
113        return [
114            'tables' => $tables,
115            'fields' => [
116                'namespace' => 'page_namespace',
117                'title' => 'page_title',
118            ],
119            'conds' => $conds,
120            'join_conds' => array_merge( $joinConds, $queryInfo['joins'] )
121        ];
122    }
123
124    protected function getOrderFields() {
125        // For some crazy reason ordering by a constant
126        // causes a filesort in MySQL 5
127        if ( count( $this->namespaceInfo->getContentNamespaces() ) > 1 ) {
128            return [ 'page_namespace', 'page_title' ];
129        } else {
130            return [ 'page_title' ];
131        }
132    }
133
134    protected function getGroupName() {
135        return 'maintenance';
136    }
137}
138
139/** @deprecated class alias since 1.41 */
140class_alias( SpecialLonelyPages::class, 'SpecialLonelyPages' );