MediaWiki master
SpecialMIMESearch.php
Go to the documentation of this file.
1<?php
7namespace MediaWiki\Specials;
8
9use MediaWiki\Cache\LinkBatchFactory;
14use MediaWiki\Languages\LanguageConverterFactory;
21use stdClass;
24
34 protected $major;
36 protected $minor;
38 protected $mime;
39
40 private ILanguageConverter $languageConverter;
41
42 public function __construct(
43 IConnectionProvider $dbProvider,
44 LinkBatchFactory $linkBatchFactory,
45 LanguageConverterFactory $languageConverterFactory
46 ) {
47 parent::__construct( 'MIMEsearch' );
48 $this->setDatabaseProvider( $dbProvider );
49 $this->setLinkBatchFactory( $linkBatchFactory );
50 $this->languageConverter = $languageConverterFactory->getLanguageConverter( $this->getContentLanguage() );
51 }
52
54 public function isExpensive() {
55 return false;
56 }
57
59 public function isSyndicated() {
60 return false;
61 }
62
64 public function isCacheable() {
65 return false;
66 }
67
69 protected function linkParameters() {
70 return [ 'mime' => "{$this->major}/{$this->minor}" ];
71 }
72
74 public function getQueryInfo() {
75 $minorType = [];
76 if ( $this->minor !== '*' ) {
77 // Allow wildcard searching
78 $minorType['img_minor_mime'] = $this->minor;
79 }
80 $fileQuery = FileSelectQueryBuilder::newForFile( $this->getDatabaseProvider()->getReplicaDatabase() )
81 ->getQueryInfo();
82 $qi = [
83 'tables' => $fileQuery['tables'],
84 'fields' => [
85 'namespace' => NS_FILE,
86 'title' => 'img_name',
87 // Still have a value field just in case,
88 // but it isn't actually used for sorting.
89 'value' => 'img_name',
90 'img_size',
91 'img_width',
92 'img_height',
93 'img_timestamp'
94 ],
95 'conds' => [
96 'img_major_mime' => $this->major,
97 // This is in order to trigger using
98 // the img_media_mime index in "range" mode.
99 // @todo how is order defined? use MimeAnalyzer::getMediaTypes?
100 'img_media_type' => [
112 ],
113 ] + $minorType,
114 'join_conds' => $fileQuery['join_conds'],
115 ];
116
117 if ( isset( $fileQuery['fields']['img_user_text'] ) ) {
118 $qi['fields']['img_user_text'] = $fileQuery['fields']['img_user_text'];
119 } else {
120 // file read new
121 $qi['fields'][] = 'img_user_text';
122 }
123
124 return $qi;
125 }
126
136 protected function getOrderFields() {
137 return [];
138 }
139
144 protected function getPageHeader() {
145 $formDescriptor = [
146 'mime' => [
147 'type' => 'combobox',
148 'options' => $this->getSuggestionsForTypes(),
149 'name' => 'mime',
150 'label-message' => 'mimetype',
151 'required' => true,
152 'default' => $this->mime,
153 ],
154 ];
155
156 HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
157 ->setSubmitTextMsg( 'ilsubmit' )
158 ->setTitle( $this->getPageTitle() )
159 ->setMethod( 'get' )
160 ->prepareForm()
161 ->displayForm( false );
162 return '';
163 }
164
165 protected function getSuggestionsForTypes(): array {
166 $queryBuilder = $this->getDatabaseProvider()->getReplicaDatabase()->newSelectQueryBuilder();
167 $migrationStage = MediaWikiServices::getInstance()->getMainConfig()->get(
169 );
170 if ( $migrationStage & SCHEMA_COMPAT_READ_OLD ) {
171 $queryBuilder
172 // We ignore img_media_type, but using it in the query is needed for MySQL to choose a
173 // sensible execution plan
174 ->select( [ 'img_media_type', 'img_major_mime', 'img_minor_mime' ] )
175 ->from( 'image' )
176 ->groupBy( [ 'img_media_type', 'img_major_mime', 'img_minor_mime' ] );
177 } else {
178 $queryBuilder->select(
179 [
180 'img_media_type' => 'ft_media_type',
181 'img_major_mime' => 'ft_major_mime',
182 'img_minor_mime' => 'ft_minor_mime',
183 ]
184 )
185 ->from( 'filetypes' );
186 }
187
188 $result = $queryBuilder->caller( __METHOD__ )->fetchResultSet();
189
190 $lastMajor = null;
191 $suggestions = [];
192 foreach ( $result as $row ) {
193 $major = $row->img_major_mime;
194 $minor = $row->img_minor_mime;
195 $suggestions[ "$major/$minor" ] = "$major/$minor";
196 if ( $lastMajor === $major ) {
197 // If there are at least two with the same major mime type, also include the wildcard
198 $suggestions[ "$major/*" ] = "$major/*";
199 }
200 $lastMajor = $major;
201 }
202 ksort( $suggestions );
203 return $suggestions;
204 }
205
207 public function execute( $par ) {
208 $this->addHelpLink( 'Help:Managing_files' );
209 $this->mime = $par ?: $this->getRequest()->getText( 'mime' );
210 $this->mime = trim( $this->mime );
211 [ $this->major, $this->minor ] = File::splitMime( $this->mime );
212 $mimeAnalyzer = MediaWikiServices::getInstance()->getMimeAnalyzer();
213
214 if ( $this->major == '' || $this->minor == '' || $this->minor == 'unknown' ||
215 !$mimeAnalyzer->isValidMajorMimeType( $this->major )
216 ) {
217 $this->setHeaders();
218 $this->outputHeader();
219 $this->getPageHeader();
220 return;
221 }
222
223 parent::execute( $par );
224 }
225
231 public function formatResult( $skin, $result ) {
232 $linkRenderer = $this->getLinkRenderer();
233 $nt = Title::makeTitle( $result->namespace, $result->title );
234
235 $text = $this->languageConverter->convertHtml( $nt->getText() );
236 $plink = $linkRenderer->makeLink(
237 Title::newFromText( $nt->getPrefixedText() ),
238 new HtmlArmor( $text )
239 );
240
241 $download = Linker::makeMediaLinkObj( $nt, $this->msg( 'download' )->escaped() );
242 $download = $this->msg( 'parentheses' )->rawParams( $download )->escaped();
243 $lang = $this->getLanguage();
244 $bytes = htmlspecialchars( $lang->formatSize( $result->img_size ) );
245 $dimensions = $this->msg( 'widthheight' )->numParams( $result->img_width,
246 $result->img_height )->escaped();
247 $user = $linkRenderer->makeLink(
248 Title::makeTitle( NS_USER, $result->img_user_text ),
249 $result->img_user_text
250 );
251
252 $time = $lang->userTimeAndDate( $result->img_timestamp, $this->getUser() );
253 $time = htmlspecialchars( $time );
254
255 return "$download $plink . . $dimensions . . $bytes . . $user . . $time";
256 }
257
259 public function preprocessResults( $db, $res ) {
260 $this->executeLBFromResultWrapper( $res );
261 }
262
264 protected function getGroupName() {
265 return 'media';
266 }
267}
268
273class_alias( SpecialMIMESearch::class, 'SpecialMIMESearch' );
const NS_USER
Definition Defines.php:53
const NS_FILE
Definition Defines.php:57
const SCHEMA_COMPAT_READ_OLD
Definition Defines.php:294
const MEDIATYPE_DRAWING
Definition defines.php:17
const MEDIATYPE_VIDEO
Definition defines.php:22
const MEDIATYPE_OFFICE
Definition defines.php:26
const MEDIATYPE_UNKNOWN
Definition defines.php:13
const MEDIATYPE_AUDIO
Definition defines.php:19
const MEDIATYPE_TEXT
Definition defines.php:28
const MEDIATYPE_BITMAP
Definition defines.php:15
const MEDIATYPE_MULTIMEDIA
Definition defines.php:24
const MEDIATYPE_EXECUTABLE
Definition defines.php:30
const MEDIATYPE_3D
Definition defines.php:34
const MEDIATYPE_ARCHIVE
Definition defines.php:32
makeTitle( $linkId)
Convert a link ID to a Title.to override Title
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:79
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:195
Some internal bits split of from Skin.php.
Definition Linker.php:47
A class containing constants representing the names of configuration variables.
const FileSchemaMigrationStage
Name constant for the FileSchemaMigrationStage setting, for use with Config::get()
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
The base class for all skins.
Definition Skin.php:52
This is a class for doing query pages; since they're almost all the same, we factor out some of the f...
Definition QueryPage.php:77
setDatabaseProvider(IConnectionProvider $databaseProvider)
setLinkBatchFactory(LinkBatchFactory $linkBatchFactory)
getPageTitle( $subpage=false)
Get a self-referential title object.
getContext()
Gets the context this SpecialPage is executed in.
getContentLanguage()
Shortcut to get content language.
Search the database for files of the requested MIME type, comparing this with the 'img_major_mime' an...
getQueryInfo()
Subclasses return an SQL query here, formatted as an array with the following keys: tables => Table(s...
__construct(IConnectionProvider $dbProvider, LinkBatchFactory $linkBatchFactory, LanguageConverterFactory $languageConverterFactory)
isExpensive()
Should this query page only be updated offline on large wikis?If the query for this page is considere...
preprocessResults( $db, $res)
Do any necessary preprocessing of the result object.to override
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
execute( $par)
This is the actual workhorse.It does everything needed to make a real, honest-to-gosh query page....
linkParameters()
If using extra form wheely-dealies, return a set of parameters here as an associative array....
getOrderFields()
The index is on (img_media_type, img_major_mime, img_minor_mime) which unfortunately doesn't have img...
getPageHeader()
Generate and output the form.
isSyndicated()
Sometimes we don't want to build rss / atom feeds.to override bool
isCacheable()
Is the output of this query cacheable? Non-cacheable expensive pages will be disabled in miser mode a...
Represents a title within MediaWiki.
Definition Title.php:70
Marks HTML that shouldn't be escaped.
Definition HtmlArmor.php:18
The shared interface for all language converters.
Provide primary and replica IDatabase connections.