Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
62.26% covered (warning)
62.26%
33 / 53
28.57% covered (danger)
28.57%
2 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialWantedFiles
62.26% covered (warning)
62.26%
33 / 53
28.57% covered (danger)
28.57%
2 / 7
15.37
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getPageHeader
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
20
 likelyToHaveFalsePositives
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 forceExistenceCheck
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 existenceCheck
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getQueryInfo
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
1 / 1
1
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Copyright © 2008 Soxred93
4 *
5 * @license GPL-2.0-or-later
6 * @file
7 */
8
9namespace MediaWiki\Specials;
10
11use MediaWiki\FileRepo\RepoGroup;
12use MediaWiki\Page\LinkBatchFactory;
13use MediaWiki\Page\PageReferenceValue;
14use MediaWiki\SpecialPage\WantedQueryPage;
15use MediaWiki\Title\Title;
16use Wikimedia\Rdbms\IConnectionProvider;
17
18/**
19 * List of the most linked non-existent files.
20 *
21 * @ingroup SpecialPage
22 * @author Soxred93 <soxred93@gmail.com>
23 */
24class SpecialWantedFiles extends WantedQueryPage {
25
26    public function __construct(
27        private readonly RepoGroup $repoGroup,
28        IConnectionProvider $dbProvider,
29        LinkBatchFactory $linkBatchFactory,
30    ) {
31        parent::__construct( 'Wantedfiles' );
32        $this->setDatabaseProvider( $dbProvider );
33        $this->setLinkBatchFactory( $linkBatchFactory );
34    }
35
36    /** @inheritDoc */
37    protected function getPageHeader() {
38        # Specifically setting to use "Wanted Files" (NS_MAIN) as title, so as to get what
39        # category would be used on main namespace pages, for those tricky wikipedia
40        # admins who like to do {{#ifeq:{{NAMESPACE}}|foo|bar|....}}.
41        $catMessage = $this->msg( 'broken-file-category' )
42            ->page( PageReferenceValue::localReference( NS_MAIN, "Wanted Files" ) )
43            ->inContentLanguage();
44
45        if ( !$catMessage->isDisabled() ) {
46            $category = Title::makeTitleSafe( NS_CATEGORY, $catMessage->text() );
47        } else {
48            $category = false;
49        }
50
51        $noForeign = '';
52        if ( !$this->likelyToHaveFalsePositives() ) {
53            // Additional messages for grep:
54            // wantedfiletext-cat-noforeign, wantedfiletext-nocat-noforeign
55            $noForeign = '-noforeign';
56        }
57
58        if ( $category ) {
59            return $this
60                ->msg( 'wantedfiletext-cat' . $noForeign, $category->getFullText() )
61                ->parseAsBlock();
62        } else {
63            return $this
64                ->msg( 'wantedfiletext-nocat' . $noForeign )
65                ->parseAsBlock();
66        }
67    }
68
69    /**
70     * Whether foreign repos are likely to cause false positives
71     *
72     * In its own function to allow subclasses to override.
73     * @see SpecialWantedFilesGUOverride in GlobalUsage extension.
74     * @since 1.24
75     * @return bool
76     */
77    protected function likelyToHaveFalsePositives() {
78        return $this->repoGroup->hasForeignRepos();
79    }
80
81    /**
82     * KLUGE: The results may contain false positives for files
83     * that exist e.g. in a shared repo.  Setting this at least
84     * keeps them from showing up as redlinks in the output, even
85     * if it doesn't fix the real problem (T8220).
86     *
87     * @note could also have existing links here from broken file
88     * redirects.
89     * @return bool
90     */
91    protected function forceExistenceCheck() {
92        return true;
93    }
94
95    /**
96     * Does the file exist?
97     *
98     * Use findFile() so we still think file namespace pages without files
99     * are missing, but valid file redirects and foreign files are ok.
100     *
101     * @param Title $title
102     * @return bool
103     */
104    protected function existenceCheck( Title $title ) {
105        return (bool)$this->repoGroup->findFile( $title );
106    }
107
108    /** @inheritDoc */
109    public function getQueryInfo() {
110        return [
111            'tables' => [
112                'imagelinks',
113                'linktarget',
114                'page',
115                'redirect',
116            ],
117            'fields' => [
118                'namespace' => NS_FILE,
119                'title' => 'lt_title',
120                'value' => 'COUNT(*)'
121            ],
122            'conds' => [
123                'page_title' => null,
124                // We also need to exclude file redirects
125                'rd_from' => null,
126            ],
127            'options' => [ 'GROUP BY' => 'lt_title' ],
128            'join_conds' => [
129                'linktarget' => [ 'JOIN', [ 'il_target_id = lt_id' ] ],
130                'page' => [ 'LEFT JOIN', [
131                    'lt_title = page_title',
132                    'page_namespace' => NS_FILE,
133                ] ],
134                'redirect' => [ 'LEFT JOIN', [
135                    'page_id = rd_from',
136                    'rd_namespace' => NS_FILE,
137                    'rd_interwiki' => ''
138                ] ],
139            ]
140        ];
141    }
142
143    /** @inheritDoc */
144    protected function getGroupName() {
145        return 'maintenance';
146    }
147}
148
149// @codeCoverageIgnoreStart
150/**
151 * Retain the old class name for backwards compatibility.
152 * @deprecated since 1.40
153 */
154class_alias( SpecialWantedFiles::class, 'WantedFilesPage' );
155// @codeCoverageIgnoreEnd