MediaWiki master
SpecialMIMESearch.php
Go to the documentation of this file.
1<?php
21namespace MediaWiki\Specials;
22
23use File;
24use HtmlArmor;
35use Skin;
36use stdClass;
38
48 protected $major;
50 protected $minor;
52 protected $mime;
53
54 private ILanguageConverter $languageConverter;
55
61 public function __construct(
62 IConnectionProvider $dbProvider,
63 LinkBatchFactory $linkBatchFactory,
64 LanguageConverterFactory $languageConverterFactory
65 ) {
66 parent::__construct( 'MIMEsearch' );
67 $this->setDatabaseProvider( $dbProvider );
68 $this->setLinkBatchFactory( $linkBatchFactory );
69 $this->languageConverter = $languageConverterFactory->getLanguageConverter( $this->getContentLanguage() );
70 }
71
72 public function isExpensive() {
73 return false;
74 }
75
76 public function isSyndicated() {
77 return false;
78 }
79
80 public function isCacheable() {
81 return false;
82 }
83
84 protected function linkParameters() {
85 return [ 'mime' => "{$this->major}/{$this->minor}" ];
86 }
87
88 public function getQueryInfo() {
89 $minorType = [];
90 if ( $this->minor !== '*' ) {
91 // Allow wildcard searching
92 $minorType['img_minor_mime'] = $this->minor;
93 }
94 $fileQuery = FileSelectQueryBuilder::newForFile( $this->getDatabaseProvider()->getReplicaDatabase() )
95 ->getQueryInfo();
96 $qi = [
97 'tables' => $fileQuery['tables'],
98 'fields' => [
99 'namespace' => NS_FILE,
100 'title' => 'img_name',
101 // Still have a value field just in case,
102 // but it isn't actually used for sorting.
103 'value' => 'img_name',
104 'img_size',
105 'img_width',
106 'img_height',
107 'img_timestamp'
108 ],
109 'conds' => [
110 'img_major_mime' => $this->major,
111 // This is in order to trigger using
112 // the img_media_mime index in "range" mode.
113 // @todo how is order defined? use MimeAnalyzer::getMediaTypes?
114 'img_media_type' => [
126 ],
127 ] + $minorType,
128 'join_conds' => $fileQuery['join_conds'],
129 ];
130
131 if ( isset( $fileQuery['fields']['img_user_text'] ) ) {
132 $qi['fields']['img_user_text'] = $fileQuery['fields']['img_user_text'];
133 } else {
134 // file read new
135 $qi['fields'][] = 'img_user_text';
136 }
137
138 return $qi;
139 }
140
150 protected function getOrderFields() {
151 return [];
152 }
153
158 protected function getPageHeader() {
159 $formDescriptor = [
160 'mime' => [
161 'type' => 'combobox',
162 'options' => $this->getSuggestionsForTypes(),
163 'name' => 'mime',
164 'label-message' => 'mimetype',
165 'required' => true,
166 'default' => $this->mime,
167 ],
168 ];
169
170 HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
171 ->setSubmitTextMsg( 'ilsubmit' )
172 ->setTitle( $this->getPageTitle() )
173 ->setMethod( 'get' )
174 ->prepareForm()
175 ->displayForm( false );
176 return '';
177 }
178
179 protected function getSuggestionsForTypes() {
180 $queryBuilder = $this->getDatabaseProvider()->getReplicaDatabase()->newSelectQueryBuilder();
181 $migrationStage = MediaWikiServices::getInstance()->getMainConfig()->get(
183 );
184 if ( $migrationStage & SCHEMA_COMPAT_READ_OLD ) {
185 $queryBuilder
186 // We ignore img_media_type, but using it in the query is needed for MySQL to choose a
187 // sensible execution plan
188 ->select( [ 'img_media_type', 'img_major_mime', 'img_minor_mime' ] )
189 ->from( 'image' )
190 ->groupBy( [ 'img_media_type', 'img_major_mime', 'img_minor_mime' ] );
191 } else {
192 $queryBuilder->select(
193 [
194 'img_media_type' => 'ft_media_type',
195 'img_major_mime' => 'ft_major_mime',
196 'img_minor_mime' => 'ft_minor_mime',
197 ]
198 )
199 ->from( 'filetypes' );
200 }
201
202 $result = $queryBuilder->caller( __METHOD__ )->fetchResultSet();
203
204 $lastMajor = null;
205 $suggestions = [];
206 foreach ( $result as $row ) {
207 $major = $row->img_major_mime;
208 $minor = $row->img_minor_mime;
209 $suggestions[ "$major/$minor" ] = "$major/$minor";
210 if ( $lastMajor === $major ) {
211 // If there are at least two with the same major mime type, also include the wildcard
212 $suggestions[ "$major/*" ] = "$major/*";
213 }
214 $lastMajor = $major;
215 }
216 ksort( $suggestions );
217 return $suggestions;
218 }
219
220 public function execute( $par ) {
221 $this->addHelpLink( 'Help:Managing_files' );
222 $this->mime = $par ?: $this->getRequest()->getText( 'mime' );
223 $this->mime = trim( $this->mime );
224 [ $this->major, $this->minor ] = File::splitMime( $this->mime );
225 $mimeAnalyzer = MediaWikiServices::getInstance()->getMimeAnalyzer();
226
227 if ( $this->major == '' || $this->minor == '' || $this->minor == 'unknown' ||
228 !$mimeAnalyzer->isValidMajorMimeType( $this->major )
229 ) {
230 $this->setHeaders();
231 $this->outputHeader();
232 $this->getPageHeader();
233 return;
234 }
235
236 parent::execute( $par );
237 }
238
244 public function formatResult( $skin, $result ) {
245 $linkRenderer = $this->getLinkRenderer();
246 $nt = Title::makeTitle( $result->namespace, $result->title );
247
248 $text = $this->languageConverter->convertHtml( $nt->getText() );
249 $plink = $linkRenderer->makeLink(
250 Title::newFromText( $nt->getPrefixedText() ),
251 new HtmlArmor( $text )
252 );
253
254 $download = Linker::makeMediaLinkObj( $nt, $this->msg( 'download' )->escaped() );
255 $download = $this->msg( 'parentheses' )->rawParams( $download )->escaped();
256 $lang = $this->getLanguage();
257 $bytes = htmlspecialchars( $lang->formatSize( $result->img_size ) );
258 $dimensions = $this->msg( 'widthheight' )->numParams( $result->img_width,
259 $result->img_height )->escaped();
260 $user = $linkRenderer->makeLink(
261 Title::makeTitle( NS_USER, $result->img_user_text ),
262 $result->img_user_text
263 );
264
265 $time = $lang->userTimeAndDate( $result->img_timestamp, $this->getUser() );
266 $time = htmlspecialchars( $time );
267
268 return "$download $plink . . $dimensions . . $bytes . . $user . . $time";
269 }
270
271 public function preprocessResults( $db, $res ) {
272 $this->executeLBFromResultWrapper( $res );
273 }
274
275 protected function getGroupName() {
276 return 'media';
277 }
278}
279
284class_alias( SpecialMIMESearch::class, 'SpecialMIMESearch' );
const NS_USER
Definition Defines.php:67
const NS_FILE
Definition Defines.php:71
const SCHEMA_COMPAT_READ_OLD
Definition Defines.php:283
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:79
Marks HTML that shouldn't be escaped.
Definition HtmlArmor.php:30
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:209
An interface for creating language converters.
getLanguageConverter( $language=null)
Provide a LanguageConverter for given language.
Some internal bits split of from Skin.php.
Definition Linker.php:63
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.
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:87
setDatabaseProvider(IConnectionProvider $databaseProvider)
executeLBFromResultWrapper(IResultWrapper $res, $ns=null)
Creates a new LinkBatch object, adds all pages from the passed result wrapper (MUST include title and...
setLinkBatchFactory(LinkBatchFactory $linkBatchFactory)
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getPageTitle( $subpage=false)
Get a self-referential title object.
getContext()
Gets the context this SpecialPage is executed in.
getRequest()
Get the WebRequest being used for this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getContentLanguage()
Shortcut to get content language.
getLanguage()
Shortcut to get user's language.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages By default the message key is the canonical name of...
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
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?
preprocessResults( $db, $res)
Do any necessary preprocessing of the result object.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
execute( $par)
This is the actual workhorse.
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.
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:78
The base class for all skins.
Definition Skin.php:64
The shared interface for all language converters.
Provide primary and replica IDatabase connections.
const MEDIATYPE_DRAWING
Definition defines.php:31
const MEDIATYPE_VIDEO
Definition defines.php:36
const MEDIATYPE_OFFICE
Definition defines.php:40
const MEDIATYPE_UNKNOWN
Definition defines.php:27
const MEDIATYPE_AUDIO
Definition defines.php:33
const MEDIATYPE_TEXT
Definition defines.php:42
const MEDIATYPE_BITMAP
Definition defines.php:29
const MEDIATYPE_MULTIMEDIA
Definition defines.php:38
const MEDIATYPE_EXECUTABLE
Definition defines.php:44
const MEDIATYPE_3D
Definition defines.php:48
const MEDIATYPE_ARCHIVE
Definition defines.php:46