From ad50776eadac11cf21487f9140c0f6a24ef00104 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 7 Feb 2011 02:35:35 +0000 Subject: [PATCH] * (bug 18011) Special:FileDuplicateSearch UI fixes and remote file repo support Fixes: - now accepts file titles with or without File: prefix instead of demanding you must remove it - moved result summary line from bottom to top - added a line telling you no file was found if it wasn't found - now pulls the reference file's SHA-1 via FileRepo, so can give it a remote file (eg from Commons) - now pulls duplicate files via the main RepoGroup instead of querying image table manually, so turns up remote duplicates - dropped the QueryPage standard paging header/footer; file dupe lists are usually very short and it's not worth copying the infrastructure To make this work, I switched the special page class from using the standard QueryPage paths to doing the query and list itself; QueryPage is currently very tightly tied in to database queries, and doesn't provide a very clean way to drop in an alternative way of looking stuff up (say an API query or just getting a big array you've gotten from somewhere). If that gets improved, this page should be cleaned up to use more of the QueryPage infrastructure again so it's pretty and doesn't scare people coming in to maintain it. Localization changes: - added fileduplicatesearch-noresults message - changed fileduplicatesearch-summary in English master to remove the supplementary line about taking out the 'File:' prefix --- .../specials/SpecialFileDuplicateSearch.php | 81 +++++++++++++++---- languages/messages/MessagesEn.php | 5 +- 2 files changed, 69 insertions(+), 17 deletions(-) diff --git a/includes/specials/SpecialFileDuplicateSearch.php b/includes/specials/SpecialFileDuplicateSearch.php index e95a0ca665..6b282c603e 100644 --- a/includes/specials/SpecialFileDuplicateSearch.php +++ b/includes/specials/SpecialFileDuplicateSearch.php @@ -29,7 +29,12 @@ * @ingroup SpecialPage */ class FileDuplicateSearchPage extends QueryPage { - protected $hash, $filename; + protected $hash = '', $filename = ''; + + /** + * @var File $file selected reference file, if present + */ + protected $file = null; function __construct( $name = 'FileDuplicateSearch' ) { parent::__construct( $name ); @@ -43,6 +48,35 @@ class FileDuplicateSearchPage extends QueryPage { return array( 'filename' => $this->filename ); } + /** + * Fetch dupes from all connected file repositories. + * + * @return Array of File objects + */ + function getDupes() { + return RepoGroup::singleton()->findBySha1( $this->hash ); + } + + /** + * + * @param Array of File objects $dupes + */ + function showList( $dupes ) { + global $wgUser, $wgOut; + $skin = $wgUser->getSkin(); + + $html = array(); + $html[] = $this->openList( 0 ); + + foreach ( $dupes as $key => $dupe ) { + $line = $this->formatResult( $skin, $dupe ); + $html[] = "
  • " . $line . "
  • "; + } + $html[] = $this->closeList(); + + $wgOut->addHtml( implode( "\n", $html ) ); + } + function getQueryInfo() { return array( 'tables' => array( 'image' ), @@ -63,11 +97,11 @@ class FileDuplicateSearchPage extends QueryPage { $this->outputHeader(); $this->filename = isset( $par ) ? $par : $wgRequest->getText( 'filename' ); + $this->file = null; $this->hash = ''; - $title = Title::makeTitleSafe( NS_FILE, $this->filename ); + $title = Title::newFromText( $this->filename, NS_FILE ); if( $title && $title->getText() != '' ) { - $dbr = wfGetDB( DB_SLAVE ); - $this->hash = $dbr->selectField( 'image', 'img_sha1', array( 'img_name' => $title->getDBkey() ), __METHOD__ ); + $this->file = wfFindFile( $title ); } # Create the input form @@ -82,11 +116,20 @@ class FileDuplicateSearchPage extends QueryPage { Xml::closeElement( 'form' ) ); + if( $this->file ) { + $this->hash = $this->file->getSha1(); + } else { + $wgOut->wrapWikiMsg( + "

    \n$1\n

    ", + array( 'fileduplicatesearch-noresults', wfEscapeWikiText( $this->filename ) ) + ); + } + if( $this->hash != '' ) { $align = $wgContLang->alignEnd(); # Show a thumbnail of the file - $img = wfFindFile( $title ); + $img = $this->file; if ( $img ) { $thumb = $img->transform( array( 'width' => 120, 'height' => 120 ) ); if( $thumb ) { @@ -102,36 +145,46 @@ class FileDuplicateSearchPage extends QueryPage { } } - parent::execute( $par ); + $dupes = $this->getDupes(); + $numRows = count( $dupes ); # Show a short summary - if( $this->numRows == 1 ) { + if( $numRows == 1 ) { $wgOut->wrapWikiMsg( "

    \n$1\n

    ", - array( 'fileduplicatesearch-result-1', $this->filename ) + array( 'fileduplicatesearch-result-1', wfEscapeWikiText( $this->filename ) ) ); - } elseif ( $this->numRows > 1 ) { + } elseif ( $numRows ) { $wgOut->wrapWikiMsg( "

    \n$1\n

    ", - array( 'fileduplicatesearch-result-n', $this->filename, - $wgLang->formatNum( $this->numRows - 1 ) ) + array( 'fileduplicatesearch-result-n', wfEscapeWikiText( $this->filename ), + $wgLang->formatNum( $numRows - 1 ) ) ); } + + $this->showList( $dupes ); } } + /** + * + * @param Skin $skin + * @param File $result + * @return string + */ function formatResult( $skin, $result ) { global $wgContLang, $wgLang; - $nt = Title::makeTitle( NS_FILE, $result->title ); + $nt = $result->getTitle(); $text = $wgContLang->convert( $nt->getText() ); $plink = $skin->link( Title::newFromText( $nt->getPrefixedText() ), $text ); - $user = $skin->link( Title::makeTitle( NS_USER, $result->img_user_text ), $result->img_user_text ); - $time = $wgLang->timeanddate( $result->img_timestamp ); + $userText = $result->getUser( 'text' ); + $user = $skin->link( Title::makeTitle( NS_USER, $userText ), $userText ); + $time = $wgLang->timeanddate( $result->getTimestamp() ); return "$plink . . $user . . $time"; } diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index fd866759b0..adbe49d86f 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -4318,15 +4318,14 @@ Enter the file name without the "{{ns:file}}:" prefix.', # Special:FileDuplicateSearch 'fileduplicatesearch' => 'Search for duplicate files', -'fileduplicatesearch-summary' => 'Search for duplicate files based on hash values. - -Enter the filename without the "{{ns:file}}:" prefix.', +'fileduplicatesearch-summary' => 'Search for duplicate files based on hash values.', 'fileduplicatesearch-legend' => 'Search for a duplicate', 'fileduplicatesearch-filename' => 'Filename:', 'fileduplicatesearch-submit' => 'Search', 'fileduplicatesearch-info' => '$1 × $2 pixel
    File size: $3
    MIME type: $4', 'fileduplicatesearch-result-1' => 'The file "$1" has no identical duplication.', 'fileduplicatesearch-result-n' => 'The file "$1" has {{PLURAL:$2|1 identical duplication|$2 identical duplications}}.', +'fileduplicatesearch-noresults' => 'No file named "$1" found.', # Special:SpecialPages 'specialpages' => 'Special pages', -- 2.20.1