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