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 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialUncategorizedPages
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 9
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
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
 execute
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getQueryInfo
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
6
 getRecacheDB
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getOrderFields
0.00% covered (danger)
0.00%
0 / 4
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 * @license GPL-2.0-or-later
4 * @file
5 */
6
7namespace MediaWiki\Specials;
8
9use MediaWiki\Deferred\LinksUpdate\CategoryLinksTable;
10use MediaWiki\Languages\LanguageConverterFactory;
11use MediaWiki\Page\LinkBatchFactory;
12use MediaWiki\SpecialPage\PageQueryPage;
13use MediaWiki\Title\NamespaceInfo;
14use Wikimedia\Rdbms\IConnectionProvider;
15
16/**
17 * List of pages without any category.
18 *
19 * @todo FIXME: Make $requestedNamespace selectable, unify all subclasses into one
20 *
21 * @ingroup SpecialPage
22 */
23class SpecialUncategorizedPages extends PageQueryPage {
24    /** @var int|false */
25    protected $requestedNamespace = false;
26
27    private NamespaceInfo $namespaceInfo;
28
29    public function __construct(
30        NamespaceInfo $namespaceInfo,
31        IConnectionProvider $dbProvider,
32        LinkBatchFactory $linkBatchFactory,
33        LanguageConverterFactory $languageConverterFactory
34    ) {
35        parent::__construct( 'Uncategorizedpages' );
36        $this->namespaceInfo = $namespaceInfo;
37        $this->setDatabaseProvider( $dbProvider );
38        $this->setLinkBatchFactory( $linkBatchFactory );
39        $this->setLanguageConverter( $languageConverterFactory->getLanguageConverter( $this->getContentLanguage() ) );
40    }
41
42    /** @inheritDoc */
43    protected function sortDescending() {
44        return false;
45    }
46
47    /** @inheritDoc */
48    public function isExpensive() {
49        return true;
50    }
51
52    /** @inheritDoc */
53    public function isSyndicated() {
54        return false;
55    }
56
57    /** @inheritDoc */
58    public function execute( $par ) {
59        $this->addHelpLink( 'Help:Categories' );
60        parent::execute( $par );
61    }
62
63    /** @inheritDoc */
64    public function getQueryInfo() {
65        return [
66            'tables' => [ 'page', 'categorylinks' ],
67            'fields' => [
68                'namespace' => 'page_namespace',
69                'title' => 'page_title',
70            ],
71            // default for page_namespace is all content namespaces (if requestedNamespace is false)
72            // otherwise, page_namespace is requestedNamespace
73            'conds' => [
74                'cl_from' => null,
75                'page_namespace' => $this->requestedNamespace !== false
76                        ? $this->requestedNamespace
77                        : $this->namespaceInfo->getContentNamespaces(),
78                'page_is_redirect' => 0
79            ],
80            'join_conds' => [
81                'categorylinks' => [ 'LEFT JOIN', 'cl_from = page_id' ]
82            ]
83        ];
84    }
85
86    /** @inheritDoc */
87    protected function getRecacheDB() {
88        return $this->getDatabaseProvider()->getReplicaDatabase(
89            CategoryLinksTable::VIRTUAL_DOMAIN,
90            'vslow'
91        );
92    }
93
94    /** @inheritDoc */
95    protected function getOrderFields() {
96        // For some crazy reason ordering by a constant
97        // causes a filesort
98        if ( $this->requestedNamespace === false &&
99            count( $this->namespaceInfo->getContentNamespaces() ) > 1
100        ) {
101            return [ 'page_namespace', 'page_title' ];
102        }
103
104        return [ 'page_title' ];
105    }
106
107    /** @inheritDoc */
108    protected function getGroupName() {
109        return 'maintenance';
110    }
111}
112
113/**
114 * Retain the old class name for backwards compatibility.
115 * @deprecated since 1.41
116 */
117class_alias( SpecialUncategorizedPages::class, 'SpecialUncategorizedPages' );