55 private $commentStore;
66 private const INDEX_FIELDS = [
67 'img_timestamp' => [
'img_timestamp',
'img_name' ],
68 'img_name' => [
'img_name' ],
69 'img_size' => [
'img_size',
'img_name' ],
100 $this->mIncluding = $including;
101 $this->mShowAll = $showAll;
104 if ( $userName !==
null && $userName !==
'' ) {
105 $nt = Title::makeTitleSafe(
NS_USER, $userName );
106 if ( $nt ===
null ) {
109 $this->mUserName = $nt->getText();
112 $this->mUser = $user;
114 if ( !$user || ( $user->isAnon() && !$userNameUtils->
isIP( $user->getName() ) ) ) {
121 if ( $this->
getRequest()->getText(
'sort',
'img_date' ) ==
'img_date' ) {
132 parent::__construct( $context, $linkRenderer );
133 $this->commentStore = $commentStore;
135 $this->userCache = $userCache;
153 $this->
getOutput()->addHtml( Html::warningBox(
155 'mw-userpage-userdoesnotexist'
169 if ( $this->mUserName !==
null ) {
174 if ( $table ===
'oldimage' ) {
178 $conds[
'oi_deleted'] = 0;
186 if ( !$this->mFieldNames ) {
187 $this->mFieldNames = [
188 'img_timestamp' => $this->
msg(
'listfiles_date' )->text(),
189 'img_name' => $this->
msg(
'listfiles_name' )->text(),
190 'thumb' => $this->
msg(
'listfiles_thumb' )->text(),
191 'img_size' => $this->
msg(
'listfiles_size' )->text(),
193 if ( $this->mUserName ===
null ) {
195 $this->mFieldNames[
'img_actor'] = $this->
msg(
'listfiles_user' )->text();
198 $this->mFieldNames[
'img_description'] = $this->
msg(
'listfiles_description' )->text();
200 if ( !$this->
getConfig()->
get( MainConfigNames::MiserMode ) && !$this->mShowAll ) {
201 $this->mFieldNames[
'count'] = $this->
msg(
'listfiles_count' )->text();
203 if ( $this->mShowAll ) {
204 $this->mFieldNames[
'top'] = $this->
msg(
'listfiles-latestversion' )->text();
212 if ( $this->mIncluding ) {
215 $sortable = array_keys( self::INDEX_FIELDS );
223 if ( $this->
getConfig()->
get( MainConfigNames::MiserMode ) && $this->mUserName !==
null ) {
225 return $field ===
'img_timestamp';
226 } elseif ( $this->
getConfig()->
get( MainConfigNames::MiserMode )
230 return $field ===
'img_name';
233 return in_array( $field, $sortable );
257 $prefix = $table ===
'oldimage' ?
'oi' :
'img';
259 $tables = [ $table,
'actor' ];
262 if ( $table ===
'oldimage' ) {
264 'img_timestamp' =>
'oi_timestamp',
265 'img_name' =>
'oi_name',
266 'img_size' =>
'oi_size',
267 'top' =>
$dbr->addQuotes(
'no' )
269 $join_conds[
'actor'] = [
'JOIN',
'actor_id=oi_actor' ];
275 'top' =>
$dbr->addQuotes(
'yes' )
277 $join_conds[
'actor'] = [
'JOIN',
'actor_id=img_actor' ];
283 $commentQuery = $this->commentStore->getJoin( $prefix .
'_description' );
284 $tables += $commentQuery[
'tables'];
285 $fields += $commentQuery[
'fields'];
286 $join_conds += $commentQuery[
'joins'];
287 $fields[
'description_field'] =
$dbr->addQuotes(
"{$prefix}_description" );
290 $fields[] =
'actor_user';
291 $fields[] =
'actor_name';
293 # Depends on $wgMiserMode
294 # Will also not happen if mShowAll is true.
296 $fields[
'count'] =
$dbr->buildSelectSubquery(
298 'COUNT(oi_archive_name)',
299 'oi_name = img_name',
308 'options' => $options,
309 'join_conds' => $join_conds
325 $this->mTableName =
'image';
326 list( $tables, $fields, $conds, $fname, $options, $join_conds ) =
328 $imageRes =
$dbr->select( $tables, $fields, $conds, $fname, $options, $join_conds );
329 $this->mTableName = $prevTableName;
331 if ( !$this->mShowAll ) {
335 $this->mTableName =
'oldimage';
339 foreach ( $this->mIndexField as &$index ) {
340 if ( substr( $index, 0, 4 ) !==
'img_' ) {
341 throw new MWException(
"Expected to be sorting on an image table field" );
343 $index =
'oi_' . substr( $index, 4 );
346 list( $tables, $fields, $conds, $fname, $options, $join_conds ) =
348 $oldimageRes =
$dbr->select( $tables, $fields, $conds, $fname, $options, $join_conds );
350 $this->mTableName = $prevTableName;
351 $this->mIndexField = $oldIndex;
353 return $this->
combineResult( $imageRes, $oldimageRes, $limit, $order );
370 $topRes1 = $res1->fetchObject();
371 $topRes2 = $res2->fetchObject();
373 for ( $i = 0; $i < $limit && $topRes1 && $topRes2; $i++ ) {
374 if ( strcmp( $topRes1->{$this->mIndexField[0]}, $topRes2->{$this->mIndexField[0]} ) > 0 ) {
376 $resultArray[] = $topRes1;
377 $topRes1 = $res1->fetchObject();
379 $resultArray[] = $topRes2;
380 $topRes2 = $res2->fetchObject();
383 $resultArray[] = $topRes2;
384 $topRes2 = $res2->fetchObject();
386 $resultArray[] = $topRes1;
387 $topRes1 = $res1->fetchObject();
391 for ( ; $i < $limit && $topRes1; $i++ ) {
392 $resultArray[] = $topRes1;
393 $topRes1 = $res1->fetchObject();
396 for ( ; $i < $limit && $topRes2; $i++ ) {
397 $resultArray[] = $topRes2;
398 $topRes2 = $res2->fetchObject();
405 return [ self::INDEX_FIELDS[$this->mSort] ];
409 if ( $this->mShowAll && $this->getConfig()->
get( MainConfigNames::MiserMode ) &&
410 $this->mUserName ===
null ) {
414 return 'img_timestamp';
420 $this->mResult->seek( 0 );
421 foreach ( $this->mResult as $row ) {
422 if ( $row->actor_user ) {
423 $userIds[] = $row->actor_user;
426 # Do a link batch query for names and userpages
427 $this->userCache->doQuery( $userIds, [
'userpage' ], __METHOD__ );
437 $linkRenderer = $this->getLinkRenderer();
440 $opt = [
'time' =>
wfTimestamp( TS_MW, $this->mCurrentRow->img_timestamp ) ];
441 $file = $this->localRepo->findFile( $this->getCurrentRow()->img_name, $opt );
444 $thumb =
$file->transform( [
'width' => 180,
'height' => 360 ] );
446 return $thumb->toHtml( [
'desc-link' =>
true ] );
448 return $this->msg(
'thumbnail_error',
'' )->escaped();
451 return htmlspecialchars( $this->getCurrentRow()->img_name );
453 case 'img_timestamp':
455 return htmlspecialchars( $this->getLanguage()->userTimeAndDate( $value, $this->
getUser() ) );
457 static $imgfile =
null;
458 if ( $imgfile ===
null ) {
459 $imgfile = $this->msg(
'imgfile' )->text();
463 $filePage = Title::makeTitleSafe(
NS_FILE, $value );
465 $link = $linkRenderer->makeKnownLink(
469 $download = Xml::element(
471 [
'href' => $this->localRepo->newFile( $filePage )->getUrl() ],
474 $download = $this->msg(
'parentheses' )->rawParams( $download )->escaped();
478 if ( $this->
getAuthority()->probablyCan(
'delete', $filePage ) ) {
479 $deleteMsg = $this->msg(
'listfiles-delete' )->text();
481 $delete = $linkRenderer->makeKnownLink(
482 $filePage, $deleteMsg, [], [
'action' =>
'delete' ]
484 $delete = $this->msg(
'parentheses' )->rawParams( $delete )->escaped();
486 return "$link $download $delete";
489 return "$link $download";
491 return htmlspecialchars( $value );
494 if ( $this->mCurrentRow->actor_user ) {
495 $name = $this->mCurrentRow->actor_name;
496 $link = $linkRenderer->makeLink(
497 Title::makeTitle(
NS_USER, $name ),
501 $link = $value !==
null ? htmlspecialchars( $value ) :
'';
506 return htmlspecialchars( $this->getLanguage()->formatSize( (
int)$value ) );
507 case 'img_description':
508 $field = $this->mCurrentRow->description_field;
509 $value = $this->commentStore->getComment( $field, $this->mCurrentRow )->text;
512 return htmlspecialchars( $this->getLanguage()->formatNum( intval( $value ) + 1 ) );
515 return $this->msg(
'listfiles-latestversion-' . $value )->escaped();
522 $formDescriptor = [];
523 $formDescriptor[
'limit'] = [
526 'label-message' =>
'table_pager_limit_label',
527 'options' => $this->getLimitSelectList(),
528 'default' => $this->mLimit,
531 $formDescriptor[
'user'] = [
534 'id' =>
'mw-listfiles-user',
535 'label-message' =>
'username',
536 'default' => $this->mUserName,
538 'maxlength' =>
'255',
541 $formDescriptor[
'ilshowall'] = [
543 'name' =>
'ilshowall',
544 'id' =>
'mw-listfiles-show-all',
545 'label-message' =>
'listfiles-show-all',
546 'default' => $this->mShowAll,
549 $query = $this->getRequest()->getQueryValues();
550 unset( $query[
'title'] );
551 unset( $query[
'limit'] );
552 unset( $query[
'ilsearch'] );
553 unset( $query[
'ilshowall'] );
554 unset( $query[
'user'] );
556 HTMLForm::factory(
'ooui', $formDescriptor, $this->
getContext() )
558 ->setId(
'mw-listfiles-form' )
560 ->setSubmitTextMsg(
'table_pager_limit_submit' )
561 ->setWrapperLegendMsg(
'listfiles' )
562 ->addHiddenFields( $query )
568 return parent::getTableClass() .
' listfiles';
572 return parent::getNavClass() .
' listfiles_nav';
576 return parent::getSortHeaderClass() .
' listfiles_sort';
580 $queries = parent::getPagingQueries();
581 if ( $this->mUserName !==
null ) {
582 # Append the username to the query string
583 foreach ( $queries as &$query ) {
584 if ( $query !==
false ) {
585 $query[
'user'] = $this->mUserName;
594 $queries = parent::getDefaultQuery();
595 if ( !isset( $queries[
'user'] ) && $this->mUserName !==
null ) {
596 $queries[
'user'] = $this->mUserName;
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
setContext(IContextSource $context)
static formatComment( $comment, $title=null, $local=false, $wikiId=null)
This function is called by all recent changes variants, by the page history, and by the user contribu...
Local repository that stores files in the local filesystem and registers them in the wiki's own datab...
A class containing constants representing the names of configuration variables.
Prioritized list of file repositories.
getLocalRepo()
Get the local repository, i.e.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
static newFromName( $name, $validate='valid')
Interface for objects which can provide a MediaWiki context on request.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.