* Made BeforeParserMakeImageLinkObj/BeforeGalleryFindFile let hooks set sha1 parameter
authorAaron Schulz <aaron@users.mediawiki.org>
Wed, 23 Mar 2011 03:13:37 +0000 (03:13 +0000)
committerAaron Schulz <aaron@users.mediawiki.org>
Wed, 23 Mar 2011 03:13:37 +0000 (03:13 +0000)
* 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
includes/ImageGallery.php
includes/Linker.php
includes/parser/Parser.php

index 07648a4..bed562e 100644 (file)
@@ -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
index 3220c39..8c13d25 100644 (file)
@@ -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;
                        }
index 02f5704..7352bf2 100644 (file)
@@ -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 "<a href=\"{$u}\" class=\"$class\" title=\"{$alt}\">{$text}</a>";
+                       $url = $this->getUploadUrl( $title );
+                       $class = 'new';
+               }
+               $alt = htmlspecialchars( $title->getText(), ENT_QUOTES );
+               if ( $text == '' ) {
+                       $text = $alt;
                }
+               $u = htmlspecialchars( $url );
+               return "<a href=\"{$u}\" class=\"$class\" title=\"{$alt}\">{$text}</a>";
        }
 
        /**
index 944ddde..4ed6337 100644 (file)
@@ -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 ) {