From d5460bce86a8dc6e2365860df8bed64155d8e486 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Wed, 23 Mar 2011 03:13:37 +0000 Subject: [PATCH] * Made BeforeParserMakeImageLinkObj/BeforeGalleryFindFile let hooks set sha1 parameter * Made FlaggedRevs specify files by sha1,timestamp to handle renames with no redirects. This makes them handled as well as templates in this regard. (bug 27836) * Moved BeforeGalleryFindFile hook to proper place (don't trigger for non-NS_FILE titles) * Removed unused mRevisionId field from ImageGallery * Removed old hotfix from makeMediaLinkObj(); all the current callers would crash beforehand if the title was null anyway * Updated hook docs (some prior params were missing) * Broke some long lines and cleaned up some whitespace * TODO: track file info in core rather than fr_fileSHA1Keys and ugly, duplicated, queries. This should be easy to do now. --- docs/hooks.txt | 6 ++- includes/ImageGallery.php | 15 +++++--- includes/Linker.php | 46 +++++++++++++---------- includes/parser/Parser.php | 76 +++++++++++++++++++++++++------------- 4 files changed, 91 insertions(+), 52 deletions(-) diff --git a/docs/hooks.txt b/docs/hooks.txt index 07648a4300..bed562e11c 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -553,7 +553,9 @@ rendered inline in wiki pages or galleries in category pages. 'BeforeGalleryFindFile': before an image is fetched for a gallery &$gallery,: the gallery object &$nt: the image title -&$time: image timestamp +&$time: image timestamp (used to specify the file) +&$descQuery: query string to add to thumbnail URL +&$sha1: image base 36 sha1 (used to specify the file, $nt will be ignored if this is set) 'BeforeInitialize': before anything is initialized in performRequestForTitle() &$title: Title being used for request @@ -578,6 +580,8 @@ $mediaWiki: Mediawiki object &$nt: the image title &$skip: skip this image and link it? &$time: the image timestamp +&$descQuery: query string to add to thumbnail URL +&$sha1: image base 36 sha1 (used to specify the file, $nt will be ignored if this is set) 'BeforeParserrenderImageGallery': before an image gallery is rendered by Parser &$parser: Parser object diff --git a/includes/ImageGallery.php b/includes/ImageGallery.php index 3220c391cb..8c13d255f2 100644 --- a/includes/ImageGallery.php +++ b/includes/ImageGallery.php @@ -14,7 +14,6 @@ class ImageGallery var $mImages, $mShowBytes, $mShowFilename; var $mCaption = false; var $mSkin = false; - var $mRevisionId = 0; /** * Hide blacklisted images? @@ -253,12 +252,16 @@ class ImageGallery $nt = $pair[0]; $text = $pair[1]; # "text" means "caption" here - # Give extensions a chance to select the file revision for us - $time = $descQuery = false; - wfRunHooks( 'BeforeGalleryFindFile', array( &$this, &$nt, &$time, &$descQuery ) ); - if ( $nt->getNamespace() == NS_FILE ) { - $img = wfFindFile( $nt, array( 'time' => $time ) ); + # Give extensions a chance to select the file revision for us + $time = $sha1 = $descQuery = false; + wfRunHooks( 'BeforeGalleryFindFile', + array( &$this, &$nt, &$time, &$descQuery, &$sha1 ) ); + # Get the file and register it + $img = $this->mParser->fetchFile( $nt, $time, $sha1 ); + if ( $img ) { + $nt = $img->getTitle(); // file title may be different (via hooks) + } } else { $img = false; } diff --git a/includes/Linker.php b/includes/Linker.php index 02f5704034..7352bf26f3 100644 --- a/includes/Linker.php +++ b/includes/Linker.php @@ -794,31 +794,39 @@ class Linker { * * @param $title Title object. * @param $text String: pre-sanitized HTML - * @param $time string: time image was created + * @param $time string: MW timestamp of file creation time + * @return String: HTML + */ + public function makeMediaLinkObj( $title, $text = '', $time = false ) { + $img = wfFindFile( $title, array( 'time' => $time ) ); + return $this->makeMediaLinkFile( $title, $img, $text ); + } + + /** + * Create a direct link to a given uploaded file. + * This will make a broken link if $file is false. + * + * @param $title Title object. + * @param $file mixed File object or false + * @param $text String: pre-sanitized HTML * @return String: HTML * * @todo Handle invalid or missing images better. */ - public function makeMediaLinkObj( $title, $text = '', $time = false ) { - if ( is_null( $title ) ) { - # # # HOTFIX. Instead of breaking, return empty string. - return $text; + public function makeMediaLinkFile( Title $title, $file, $text = '' ) { + if ( $file && $file->exists() ) { + $url = $file->getURL(); + $class = 'internal'; } else { - $img = wfFindFile( $title, array( 'time' => $time ) ); - if ( $img ) { - $url = $img->getURL(); - $class = 'internal'; - } else { - $url = $this->getUploadUrl( $title ); - $class = 'new'; - } - $alt = htmlspecialchars( $title->getText(), ENT_QUOTES ); - if ( $text == '' ) { - $text = $alt; - } - $u = htmlspecialchars( $url ); - return "{$text}"; + $url = $this->getUploadUrl( $title ); + $class = 'new'; + } + $alt = htmlspecialchars( $title->getText(), ENT_QUOTES ); + if ( $text == '' ) { + $text = $alt; } + $u = htmlspecialchars( $url ); + return "{$text}"; } /** diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 944dddebd0..4ed633763a 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -1862,11 +1862,11 @@ class Parser { $holders->merge( $this->replaceInternalLinks2( $text ) ); } # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them - $s .= $prefix . $this->armorLinks( $this->makeImage( $nt, $text, $holders ) ) . $trail; + $s .= $prefix . $this->armorLinks( + $this->makeImage( $nt, $text, $holders ) ) . $trail; } else { $s .= $prefix . $trail; } - $this->mOutput->addImage( $nt->getDBkey() ); wfProfileOut( __METHOD__."-image" ); continue; @@ -1910,16 +1910,22 @@ class Parser { if ( $ns == NS_MEDIA ) { wfProfileIn( __METHOD__."-media" ); # Give extensions a chance to select the file revision for us - $skip = $time = false; - wfRunHooks( 'BeforeParserMakeImageLinkObj', array( &$this, &$nt, &$skip, &$time ) ); + $skip = $time = $sha1 = $descQuery = false; + wfRunHooks( 'BeforeParserMakeImageLinkObj', + array( &$this, &$nt, &$skip, &$time, &$descQuery, &$sha1 ) ); if ( $skip ) { + $this->mOutput->addImage( $nt->getDBkey() ); // register $link = $sk->link( $nt ); } else { - $link = $sk->makeMediaLinkObj( $nt, $text, $time ); + # Fetch and register the file + $file = $this->fetchFile( $nt, $time, $sha1 ); + if ( $file ) { + $nt = $file->getTitle(); // file title may be different (via hooks) + } + $link = $sk->makeMediaLinkFile( $nt, $file, $text ); } # Cloak with NOPARSE to avoid replacement in replaceExternalLinks $s .= $prefix . $this->armorLinks( $link ) . $trail; - $this->mOutput->addImage( $nt->getDBkey() ); wfProfileOut( __METHOD__."-media" ); continue; } @@ -3340,14 +3346,16 @@ class Parser { for ( $i = 0; $i < 2 && is_object( $title ); $i++ ) { # Give extensions a chance to select the revision instead $id = false; # Assume current - wfRunHooks( 'BeforeParserFetchTemplateAndtitle', array( $parser, &$title, &$skip, &$id ) ); + wfRunHooks( 'BeforeParserFetchTemplateAndtitle', + array( $parser, &$title, &$skip, &$id ) ); if ( $skip ) { $text = false; $deps[] = array( - 'title' => $title, - 'page_id' => $title->getArticleID(), - 'rev_id' => null ); + 'title' => $title, + 'page_id' => $title->getArticleID(), + 'rev_id' => null + ); break; } $rev = $id ? Revision::newFromId( $id ) : Revision::newFromTitle( $title ); @@ -3359,9 +3367,9 @@ class Parser { } $deps[] = array( - 'title' => $title, - 'page_id' => $title->getArticleID(), - 'rev_id' => $rev_id ); + 'title' => $title, + 'page_id' => $title->getArticleID(), + 'rev_id' => $rev_id ); if ( $rev ) { $text = $rev->getText(); @@ -3389,6 +3397,23 @@ class Parser { 'deps' => $deps ); } + /** + * Fetch a file and register a reference to it. + * @TODO: register and track file version info too + */ + function fetchFile( $title, $time = false, $sha1 = false ) { + if ( $sha1 ) { // get by (sha1,timestamp) + $file = RepoGroup::singleton()->findFileFromKey( $sha1, array( 'time' => $time ) ); + if ( $file ) { + $title = $file->getTitle(); // file title may not match $title + } + } else { // get by (name,timestamp) + $file = wfFindFile( $title, array( 'time' => $time ) ); + } + $this->mOutput->addImage( $title->getDBkey() ); + return $file; + } + /** * Transclude an interwiki link. */ @@ -4506,7 +4531,6 @@ class Parser { $ig->setHideBadImages(); $ig->setAttributes( Sanitizer::validateTagAttributes( $params, 'table' ) ); $ig->useSkin( $this->mOptions->getSkin( $this->mTitle ) ); - $ig->mRevisionId = $this->mRevisionId; if ( isset( $params['showfilename'] ) ) { $ig->setShowFilename( true ); @@ -4560,11 +4584,6 @@ class Parser { $html = $this->recursiveTagParse( trim( $label ) ); $ig->add( $nt, $html ); - - # Only add real images (bug #5586) - if ( $nt->getNamespace() == NS_FILE ) { - $this->mOutput->addImage( $nt->getDBkey() ); - } } return $ig->toHTML(); } @@ -4615,6 +4634,7 @@ class Parser { * @param $title Title * @param $options String * @param $holders LinkHolderArray + * @return string HTML */ function makeImage( $title, $options, $holders = false ) { # Check if the options text is of the form "options|alt text" @@ -4646,15 +4666,18 @@ class Parser { $sk = $this->mOptions->getSkin( $this->mTitle ); # Give extensions a chance to select the file revision for us - $skip = $time = $descQuery = false; - wfRunHooks( 'BeforeParserMakeImageLinkObj', array( &$this, &$title, &$skip, &$time, &$descQuery ) ); - + $skip = $time = $sha1 = $descQuery = false; + wfRunHooks( 'BeforeParserMakeImageLinkObj', + array( &$this, &$title, &$skip, &$time, &$descQuery, &$sha1 ) ); if ( $skip ) { + $this->mOutput->addImage( $title->getDBkey() ); // register return $sk->link( $title ); } - - # Get the file - $file = wfFindFile( $title, array( 'time' => $time ) ); + # Fetch and register the file + $file = $this->fetchFile( $title, $time, $sha1 ); + if ( $file ) { + $title = $file->getTitle(); // file title may be different (via hooks) + } # Get parameter map $handler = $file ? $file->getHandler() : false; @@ -4809,7 +4832,8 @@ class Parser { wfRunHooks( 'ParserMakeImageParams', array( $title, $file, &$params ) ); # Linker does the rest - $ret = $sk->makeImageLink2( $title, $file, $params['frame'], $params['handler'], $time, $descQuery, $this->mOptions->getThumbSize() ); + $ret = $sk->makeImageLink2( $title, $file, $params['frame'], $params['handler'], + $time, $descQuery, $this->mOptions->getThumbSize() ); # Give the handler a chance to modify the parser object if ( $handler ) { -- 2.20.1