From 2647cbc4a456b0154bdafe70386ae0ef04d997a1 Mon Sep 17 00:00:00 2001 From: Matthias Mullie Date: Thu, 16 Mar 2017 15:27:49 +0100 Subject: [PATCH] Add media type based filtering to Special:NewFiles Change-Id: Iff6e25055489f2181d6f9868e9250e03a54b91b7 --- includes/libs/mime/MimeAnalyzer.php | 9 ++++++ includes/specials/SpecialMIMEsearch.php | 1 + includes/specials/SpecialNewimages.php | 37 ++++++++++++++++++++++ includes/specials/pagers/NewFilesPager.php | 4 +++ languages/i18n/en.json | 1 + languages/i18n/qqq.json | 1 + 6 files changed, 53 insertions(+) diff --git a/includes/libs/mime/MimeAnalyzer.php b/includes/libs/mime/MimeAnalyzer.php index 565c157331..c361fdfa0d 100644 --- a/includes/libs/mime/MimeAnalyzer.php +++ b/includes/libs/mime/MimeAnalyzer.php @@ -1144,6 +1144,15 @@ EOT; return MEDIATYPE_UNKNOWN; } + /** + * Returns an array of media types (MEDIATYPE_xxx constants) + * + * @return array + */ + public function getMediaTypes() { + return array_keys( $this->mediaTypes ); + } + /** * Get the MIME types that various versions of Internet Explorer would * detect from a chunk of the content. diff --git a/includes/specials/SpecialMIMEsearch.php b/includes/specials/SpecialMIMEsearch.php index 52cb30a1bc..7087cff4c0 100644 --- a/includes/specials/SpecialMIMEsearch.php +++ b/includes/specials/SpecialMIMEsearch.php @@ -74,6 +74,7 @@ class MIMEsearchPage extends QueryPage { 'img_major_mime' => $this->major, // This is in order to trigger using // the img_media_mime index in "range" mode. + // @todo how is order defined? use MimeAnalyzer::getMediaTypes? 'img_media_type' => [ MEDIATYPE_BITMAP, MEDIATYPE_DRAWING, diff --git a/includes/specials/SpecialNewimages.php b/includes/specials/SpecialNewimages.php index 583d4f9e7c..20f507ff2c 100644 --- a/includes/specials/SpecialNewimages.php +++ b/includes/specials/SpecialNewimages.php @@ -25,6 +25,9 @@ class SpecialNewFiles extends IncludableSpecialPage { /** @var FormOptions */ protected $opts; + /** @var string[] */ + protected $mediaTypes; + public function __construct() { parent::__construct( 'Newimages' ); } @@ -32,6 +35,8 @@ class SpecialNewFiles extends IncludableSpecialPage { public function execute( $par ) { $this->setHeaders(); $this->outputHeader(); + $mimeAnalyzer = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer(); + $this->mediaTypes = $mimeAnalyzer->getMediaTypes(); $out = $this->getOutput(); $out->addModules( 'mediawiki.special.newFiles' ); @@ -43,6 +48,7 @@ class SpecialNewFiles extends IncludableSpecialPage { $opts->add( 'user', '' ); $opts->add( 'showbots', false ); $opts->add( 'hidepatrolled', false ); + $opts->add( 'mediatype', $this->mediaTypes ); $opts->add( 'limit', 50 ); $opts->add( 'offset', '' ); $opts->add( 'start', '' ); @@ -67,6 +73,14 @@ class SpecialNewFiles extends IncludableSpecialPage { $opts->setValue( 'end', $end, true ); } + // if all media types have been selected, wipe out the array to prevent + // the pointless IN(...) query condition (which would have no effect + // because every possible type has been selected) + $missingMediaTypes = array_diff( $this->mediaTypes, $opts->getValue( 'mediatype' ) ); + if ( empty( $missingMediaTypes ) ) { + $opts->setValue( 'mediatype', [] ); + } + $opts->validateIntBounds( 'limit', 0, 500 ); $this->opts = $opts; @@ -85,6 +99,17 @@ class SpecialNewFiles extends IncludableSpecialPage { } protected function buildForm() { + $mediaTypesText = array_map( function ( $type ) { + // mediastatistics-header-unknown, mediastatistics-header-bitmap, + // mediastatistics-header-drawing, mediastatistics-header-audio, + // mediastatistics-header-video, mediastatistics-header-multimedia, + // mediastatistics-header-office, mediastatistics-header-text, + // mediastatistics-header-executable, mediastatistics-header-archive, + return $this->msg( 'mediastatistics-header-' . strtolower( $type ) )->text(); + }, $this->mediaTypes ); + $mediaTypesOptions = array_combine( $mediaTypesText, $this->mediaTypes ); + ksort( $mediaTypesOptions ); + $formDescriptor = [ 'like' => [ 'type' => 'text', @@ -110,6 +135,16 @@ class SpecialNewFiles extends IncludableSpecialPage { 'name' => 'hidepatrolled', ], + 'mediatype' => [ + 'type' => 'multiselect', + 'dropdown' => true, + 'flatlist' => true, + 'name' => 'mediatype', + 'label-message' => 'newimages-mediatype', + 'options' => $mediaTypesOptions, + 'default' => $this->mediaTypes, + ], + 'limit' => [ 'type' => 'hidden', 'default' => $this->opts->getValue( 'limit' ), @@ -144,6 +179,8 @@ class SpecialNewFiles extends IncludableSpecialPage { } HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() ) + // For the 'multiselect' field values to be preserved on submit + ->setFormIdentifier( 'specialnewimages' ) ->setWrapperLegendMsg( 'newimages-legend' ) ->setSubmitTextMsg( 'ilsubmit' ) ->setMethod( 'get' ) diff --git a/includes/specials/pagers/NewFilesPager.php b/includes/specials/pagers/NewFilesPager.php index cce0323198..3aeebeac52 100644 --- a/includes/specials/pagers/NewFilesPager.php +++ b/includes/specials/pagers/NewFilesPager.php @@ -112,6 +112,10 @@ class NewFilesPager extends RangeChronologicalPager { $options[] = 'STRAIGHT_JOIN'; } + if ( $opts->getValue( 'mediatype' ) ) { + $conds['img_media_type'] = $opts->getValue( 'mediatype' ); + } + $likeVal = $opts->getValue( 'like' ); if ( !$this->getConfig()->get( 'MiserMode' ) && $likeVal !== '' ) { $dbr = wfGetDB( DB_REPLICA ); diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 9fe0e3cfc5..a8d90d16a2 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -3044,6 +3044,7 @@ "newimages-user": "IP address or username", "newimages-showbots": "Show uploads by bots", "newimages-hidepatrolled": "Hide patrolled uploads", + "newimages-mediatype": "Media type:", "noimages": "Nothing to see.", "gallery-slideshow-toggle": "Toggle thumbnails", "ilsubmit": "Search", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 4d46e6fb2c..1498f99411 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -3234,6 +3234,7 @@ "newimages-user": "Caption of the username/IP address editbox on [[Special:NewImages]]", "newimages-showbots": "Used as label for a checkbox. When checked, [[Special:NewImages]] will also display uploads by users in the bots group.", "newimages-hidepatrolled": "Used as label for a checkbox. When checked, [[Special:NewImages]] will not display patrolled uploads.\n\nCf. {{msg-mw|tog-hidepatrolled}} and {{msg-mw|apihelp-feedrecentchanges-param-hidepatrolled}}.", + "newimages-mediatype": "Used as label for a multiselect where users can select the media types to display.", "noimages": "This is shown on the special page [[Special:NewImages]], when there aren't any recently uploaded files.", "gallery-slideshow-toggle": "Tooltip for the icon that toggles thumbnails on a slideshow gallery.", "ilsubmit": "Search button in [[Special:MIMESearch]].\n\nStrings on the page:\n* {{msg-mw|Mimesearch|page title, legend of input form, link in special pages}}\n* {{msg-mw|Mimesearch-summary|page summary}}\n* {{msg-mw|Mimetype|label for input box}}\n* {{msg-mw|Ilsubmit|search button}}\n\nCheck [[mw:Manual:MIME_type_detection]] for MIME types.\n\n{{Identical|Search}}", -- 2.20.1