Index: trunk/phase3/docs/hooks.txt |
— | — | @@ -553,7 +553,9 @@ |
554 | 554 | 'BeforeGalleryFindFile': before an image is fetched for a gallery |
555 | 555 | &$gallery,: the gallery object |
556 | 556 | &$nt: the image title |
557 | | -&$time: image timestamp |
| 557 | +&$time: image timestamp (used to specify the file) |
| 558 | +&$descQuery: query string to add to thumbnail URL |
| 559 | +&$sha1: image base 36 sha1 (used to specify the file, $nt will be ignored if this is set) |
558 | 560 | |
559 | 561 | 'BeforeInitialize': before anything is initialized in performRequestForTitle() |
560 | 562 | &$title: Title being used for request |
— | — | @@ -578,6 +580,8 @@ |
579 | 581 | &$nt: the image title |
580 | 582 | &$skip: skip this image and link it? |
581 | 583 | &$time: the image timestamp |
| 584 | +&$descQuery: query string to add to thumbnail URL |
| 585 | +&$sha1: image base 36 sha1 (used to specify the file, $nt will be ignored if this is set) |
582 | 586 | |
583 | 587 | 'BeforeParserrenderImageGallery': before an image gallery is rendered by Parser |
584 | 588 | &$parser: Parser object |
Index: trunk/phase3/includes/parser/Parser.php |
— | — | @@ -1862,11 +1862,11 @@ |
1863 | 1863 | $holders->merge( $this->replaceInternalLinks2( $text ) ); |
1864 | 1864 | } |
1865 | 1865 | # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them |
1866 | | - $s .= $prefix . $this->armorLinks( $this->makeImage( $nt, $text, $holders ) ) . $trail; |
| 1866 | + $s .= $prefix . $this->armorLinks( |
| 1867 | + $this->makeImage( $nt, $text, $holders ) ) . $trail; |
1867 | 1868 | } else { |
1868 | 1869 | $s .= $prefix . $trail; |
1869 | 1870 | } |
1870 | | - $this->mOutput->addImage( $nt->getDBkey() ); |
1871 | 1871 | wfProfileOut( __METHOD__."-image" ); |
1872 | 1872 | continue; |
1873 | 1873 | |
— | — | @@ -1910,16 +1910,22 @@ |
1911 | 1911 | if ( $ns == NS_MEDIA ) { |
1912 | 1912 | wfProfileIn( __METHOD__."-media" ); |
1913 | 1913 | # Give extensions a chance to select the file revision for us |
1914 | | - $skip = $time = false; |
1915 | | - wfRunHooks( 'BeforeParserMakeImageLinkObj', array( &$this, &$nt, &$skip, &$time ) ); |
| 1914 | + $skip = $time = $sha1 = $descQuery = false; |
| 1915 | + wfRunHooks( 'BeforeParserMakeImageLinkObj', |
| 1916 | + array( &$this, &$nt, &$skip, &$time, &$descQuery, &$sha1 ) ); |
1916 | 1917 | if ( $skip ) { |
| 1918 | + $this->mOutput->addImage( $nt->getDBkey() ); // register |
1917 | 1919 | $link = $sk->link( $nt ); |
1918 | 1920 | } else { |
1919 | | - $link = $sk->makeMediaLinkObj( $nt, $text, $time ); |
| 1921 | + # Fetch and register the file |
| 1922 | + $file = $this->fetchFile( $nt, $time, $sha1 ); |
| 1923 | + if ( $file ) { |
| 1924 | + $nt = $file->getTitle(); // file title may be different (via hooks) |
| 1925 | + } |
| 1926 | + $link = $sk->makeMediaLinkFile( $nt, $file, $text ); |
1920 | 1927 | } |
1921 | 1928 | # Cloak with NOPARSE to avoid replacement in replaceExternalLinks |
1922 | 1929 | $s .= $prefix . $this->armorLinks( $link ) . $trail; |
1923 | | - $this->mOutput->addImage( $nt->getDBkey() ); |
1924 | 1930 | wfProfileOut( __METHOD__."-media" ); |
1925 | 1931 | continue; |
1926 | 1932 | } |
— | — | @@ -3340,14 +3346,16 @@ |
3341 | 3347 | for ( $i = 0; $i < 2 && is_object( $title ); $i++ ) { |
3342 | 3348 | # Give extensions a chance to select the revision instead |
3343 | 3349 | $id = false; # Assume current |
3344 | | - wfRunHooks( 'BeforeParserFetchTemplateAndtitle', array( $parser, &$title, &$skip, &$id ) ); |
| 3350 | + wfRunHooks( 'BeforeParserFetchTemplateAndtitle', |
| 3351 | + array( $parser, &$title, &$skip, &$id ) ); |
3345 | 3352 | |
3346 | 3353 | if ( $skip ) { |
3347 | 3354 | $text = false; |
3348 | 3355 | $deps[] = array( |
3349 | | - 'title' => $title, |
3350 | | - 'page_id' => $title->getArticleID(), |
3351 | | - 'rev_id' => null ); |
| 3356 | + 'title' => $title, |
| 3357 | + 'page_id' => $title->getArticleID(), |
| 3358 | + 'rev_id' => null |
| 3359 | + ); |
3352 | 3360 | break; |
3353 | 3361 | } |
3354 | 3362 | $rev = $id ? Revision::newFromId( $id ) : Revision::newFromTitle( $title ); |
— | — | @@ -3359,9 +3367,9 @@ |
3360 | 3368 | } |
3361 | 3369 | |
3362 | 3370 | $deps[] = array( |
3363 | | - 'title' => $title, |
3364 | | - 'page_id' => $title->getArticleID(), |
3365 | | - 'rev_id' => $rev_id ); |
| 3371 | + 'title' => $title, |
| 3372 | + 'page_id' => $title->getArticleID(), |
| 3373 | + 'rev_id' => $rev_id ); |
3366 | 3374 | |
3367 | 3375 | if ( $rev ) { |
3368 | 3376 | $text = $rev->getText(); |
— | — | @@ -3390,6 +3398,23 @@ |
3391 | 3399 | } |
3392 | 3400 | |
3393 | 3401 | /** |
| 3402 | + * Fetch a file and register a reference to it. |
| 3403 | + * @TODO: register and track file version info too |
| 3404 | + */ |
| 3405 | + function fetchFile( $title, $time = false, $sha1 = false ) { |
| 3406 | + if ( $sha1 ) { // get by (sha1,timestamp) |
| 3407 | + $file = RepoGroup::singleton()->findFileFromKey( $sha1, array( 'time' => $time ) ); |
| 3408 | + if ( $file ) { |
| 3409 | + $title = $file->getTitle(); // file title may not match $title |
| 3410 | + } |
| 3411 | + } else { // get by (name,timestamp) |
| 3412 | + $file = wfFindFile( $title, array( 'time' => $time ) ); |
| 3413 | + } |
| 3414 | + $this->mOutput->addImage( $title->getDBkey() ); |
| 3415 | + return $file; |
| 3416 | + } |
| 3417 | + |
| 3418 | + /** |
3394 | 3419 | * Transclude an interwiki link. |
3395 | 3420 | */ |
3396 | 3421 | function interwikiTransclude( $title, $action ) { |
— | — | @@ -4506,7 +4531,6 @@ |
4507 | 4532 | $ig->setHideBadImages(); |
4508 | 4533 | $ig->setAttributes( Sanitizer::validateTagAttributes( $params, 'table' ) ); |
4509 | 4534 | $ig->useSkin( $this->mOptions->getSkin( $this->mTitle ) ); |
4510 | | - $ig->mRevisionId = $this->mRevisionId; |
4511 | 4535 | |
4512 | 4536 | if ( isset( $params['showfilename'] ) ) { |
4513 | 4537 | $ig->setShowFilename( true ); |
— | — | @@ -4560,11 +4584,6 @@ |
4561 | 4585 | $html = $this->recursiveTagParse( trim( $label ) ); |
4562 | 4586 | |
4563 | 4587 | $ig->add( $nt, $html ); |
4564 | | - |
4565 | | - # Only add real images (bug #5586) |
4566 | | - if ( $nt->getNamespace() == NS_FILE ) { |
4567 | | - $this->mOutput->addImage( $nt->getDBkey() ); |
4568 | | - } |
4569 | 4588 | } |
4570 | 4589 | return $ig->toHTML(); |
4571 | 4590 | } |
— | — | @@ -4615,6 +4634,7 @@ |
4616 | 4635 | * @param $title Title |
4617 | 4636 | * @param $options String |
4618 | 4637 | * @param $holders LinkHolderArray |
| 4638 | + * @return string HTML |
4619 | 4639 | */ |
4620 | 4640 | function makeImage( $title, $options, $holders = false ) { |
4621 | 4641 | # Check if the options text is of the form "options|alt text" |
— | — | @@ -4646,15 +4666,18 @@ |
4647 | 4667 | $sk = $this->mOptions->getSkin( $this->mTitle ); |
4648 | 4668 | |
4649 | 4669 | # Give extensions a chance to select the file revision for us |
4650 | | - $skip = $time = $descQuery = false; |
4651 | | - wfRunHooks( 'BeforeParserMakeImageLinkObj', array( &$this, &$title, &$skip, &$time, &$descQuery ) ); |
4652 | | - |
| 4670 | + $skip = $time = $sha1 = $descQuery = false; |
| 4671 | + wfRunHooks( 'BeforeParserMakeImageLinkObj', |
| 4672 | + array( &$this, &$title, &$skip, &$time, &$descQuery, &$sha1 ) ); |
4653 | 4673 | if ( $skip ) { |
| 4674 | + $this->mOutput->addImage( $title->getDBkey() ); // register |
4654 | 4675 | return $sk->link( $title ); |
4655 | 4676 | } |
4656 | | - |
4657 | | - # Get the file |
4658 | | - $file = wfFindFile( $title, array( 'time' => $time ) ); |
| 4677 | + # Fetch and register the file |
| 4678 | + $file = $this->fetchFile( $title, $time, $sha1 ); |
| 4679 | + if ( $file ) { |
| 4680 | + $title = $file->getTitle(); // file title may be different (via hooks) |
| 4681 | + } |
4659 | 4682 | # Get parameter map |
4660 | 4683 | $handler = $file ? $file->getHandler() : false; |
4661 | 4684 | |
— | — | @@ -4809,7 +4832,8 @@ |
4810 | 4833 | wfRunHooks( 'ParserMakeImageParams', array( $title, $file, &$params ) ); |
4811 | 4834 | |
4812 | 4835 | # Linker does the rest |
4813 | | - $ret = $sk->makeImageLink2( $title, $file, $params['frame'], $params['handler'], $time, $descQuery, $this->mOptions->getThumbSize() ); |
| 4836 | + $ret = $sk->makeImageLink2( $title, $file, $params['frame'], $params['handler'], |
| 4837 | + $time, $descQuery, $this->mOptions->getThumbSize() ); |
4814 | 4838 | |
4815 | 4839 | # Give the handler a chance to modify the parser object |
4816 | 4840 | if ( $handler ) { |
Index: trunk/phase3/includes/Linker.php |
— | — | @@ -794,31 +794,39 @@ |
795 | 795 | * |
796 | 796 | * @param $title Title object. |
797 | 797 | * @param $text String: pre-sanitized HTML |
798 | | - * @param $time string: time image was created |
| 798 | + * @param $time string: MW timestamp of file creation time |
799 | 799 | * @return String: HTML |
| 800 | + */ |
| 801 | + public function makeMediaLinkObj( $title, $text = '', $time = false ) { |
| 802 | + $img = wfFindFile( $title, array( 'time' => $time ) ); |
| 803 | + return $this->makeMediaLinkFile( $title, $img, $text ); |
| 804 | + } |
| 805 | + |
| 806 | + /** |
| 807 | + * Create a direct link to a given uploaded file. |
| 808 | + * This will make a broken link if $file is false. |
800 | 809 | * |
| 810 | + * @param $title Title object. |
| 811 | + * @param $file mixed File object or false |
| 812 | + * @param $text String: pre-sanitized HTML |
| 813 | + * @return String: HTML |
| 814 | + * |
801 | 815 | * @todo Handle invalid or missing images better. |
802 | 816 | */ |
803 | | - public function makeMediaLinkObj( $title, $text = '', $time = false ) { |
804 | | - if ( is_null( $title ) ) { |
805 | | - # # # HOTFIX. Instead of breaking, return empty string. |
806 | | - return $text; |
| 817 | + public function makeMediaLinkFile( Title $title, $file, $text = '' ) { |
| 818 | + if ( $file && $file->exists() ) { |
| 819 | + $url = $file->getURL(); |
| 820 | + $class = 'internal'; |
807 | 821 | } else { |
808 | | - $img = wfFindFile( $title, array( 'time' => $time ) ); |
809 | | - if ( $img ) { |
810 | | - $url = $img->getURL(); |
811 | | - $class = 'internal'; |
812 | | - } else { |
813 | | - $url = $this->getUploadUrl( $title ); |
814 | | - $class = 'new'; |
815 | | - } |
816 | | - $alt = htmlspecialchars( $title->getText(), ENT_QUOTES ); |
817 | | - if ( $text == '' ) { |
818 | | - $text = $alt; |
819 | | - } |
820 | | - $u = htmlspecialchars( $url ); |
821 | | - return "<a href=\"{$u}\" class=\"$class\" title=\"{$alt}\">{$text}</a>"; |
| 822 | + $url = $this->getUploadUrl( $title ); |
| 823 | + $class = 'new'; |
822 | 824 | } |
| 825 | + $alt = htmlspecialchars( $title->getText(), ENT_QUOTES ); |
| 826 | + if ( $text == '' ) { |
| 827 | + $text = $alt; |
| 828 | + } |
| 829 | + $u = htmlspecialchars( $url ); |
| 830 | + return "<a href=\"{$u}\" class=\"$class\" title=\"{$alt}\">{$text}</a>"; |
823 | 831 | } |
824 | 832 | |
825 | 833 | /** |
Index: trunk/phase3/includes/ImageGallery.php |
— | — | @@ -14,7 +14,6 @@ |
15 | 15 | var $mImages, $mShowBytes, $mShowFilename; |
16 | 16 | var $mCaption = false; |
17 | 17 | var $mSkin = false; |
18 | | - var $mRevisionId = 0; |
19 | 18 | |
20 | 19 | /** |
21 | 20 | * Hide blacklisted images? |
— | — | @@ -253,12 +252,16 @@ |
254 | 253 | $nt = $pair[0]; |
255 | 254 | $text = $pair[1]; # "text" means "caption" here |
256 | 255 | |
257 | | - # Give extensions a chance to select the file revision for us |
258 | | - $time = $descQuery = false; |
259 | | - wfRunHooks( 'BeforeGalleryFindFile', array( &$this, &$nt, &$time, &$descQuery ) ); |
260 | | - |
261 | 256 | if ( $nt->getNamespace() == NS_FILE ) { |
262 | | - $img = wfFindFile( $nt, array( 'time' => $time ) ); |
| 257 | + # Give extensions a chance to select the file revision for us |
| 258 | + $time = $sha1 = $descQuery = false; |
| 259 | + wfRunHooks( 'BeforeGalleryFindFile', |
| 260 | + array( &$this, &$nt, &$time, &$descQuery, &$sha1 ) ); |
| 261 | + # Get the file and register it |
| 262 | + $img = $this->mParser->fetchFile( $nt, $time, $sha1 ); |
| 263 | + if ( $img ) { |
| 264 | + $nt = $img->getTitle(); // file title may be different (via hooks) |
| 265 | + } |
263 | 266 | } else { |
264 | 267 | $img = false; |
265 | 268 | } |
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php |
— | — | @@ -334,7 +334,7 @@ |
335 | 335 | * (b) Set specified versions in fr_fileSHA1Keys |
336 | 336 | */ |
337 | 337 | public static function parserFetchStableFile( |
338 | | - $parser, Title $nt, &$skip, &$time, &$query = false |
| 338 | + $parser, Title $nt, &$skip, &$time, &$query, &$sha1 |
339 | 339 | ) { |
340 | 340 | if ( !( $parser instanceof Parser ) ) { |
341 | 341 | return true; // nothing to do |
— | — | @@ -363,7 +363,7 @@ |
364 | 364 | * (a) Select the desired images based on the selected stable version time/SHA-1 |
365 | 365 | * (b) Set specified versions in fr_fileSHA1Keys |
366 | 366 | */ |
367 | | - public static function galleryFetchStableFile( $ig, Title $nt, &$time, &$query = false ) { |
| 367 | + public static function galleryFetchStableFile( $ig, Title $nt, &$time, &$query, &$sha1 ) { |
368 | 368 | $parser =& $ig->mParser; // convenience |
369 | 369 | if ( !( $parser instanceof Parser ) || $nt->getNamespace() != NS_FILE ) { |
370 | 370 | return true; // nothing to do |
— | — | @@ -387,7 +387,7 @@ |
388 | 388 | */ |
389 | 389 | protected static function parserFindStableFile( Parser $parser, Title $title ) { |
390 | 390 | $time = false; // current version |
391 | | - $sha1 = null; // corresponds to $time |
| 391 | + $sha1 = false; // corresponds to $time |
392 | 392 | # Check for the version of this file used when reviewed. |
393 | 393 | $incManager = FRInclusionManager::singleton(); |
394 | 394 | list( $maybeTS, $maybeSha1 ) = $incManager->getReviewedFileVersion( $title ); |
— | — | @@ -430,15 +430,20 @@ |
431 | 431 | } |
432 | 432 | # Fetch the current timestamps of the images. |
433 | 433 | foreach ( $pOutput->mImages as $filename => $x ) { |
434 | | - # FIXME: it would be nice not to double fetch these! |
435 | | - $time = false; // current |
436 | 434 | # Stable output with versions specified |
437 | 435 | if ( isset( $pOutput->fr_fileSHA1Keys[$filename] ) ) { |
438 | 436 | // Fetch file with $time to confirm the specified version exists |
439 | 437 | $time = $pOutput->fr_fileSHA1Keys[$filename]['ts']; |
| 438 | + $sha1 = $pOutput->fr_fileSHA1Keys[$filename]['sha1']; |
| 439 | + # FIXME: don't double fetch these (Parser just did)!!! |
| 440 | + $file = RepoGroup::singleton()->findFileFromKey( |
| 441 | + $sha1, array( 'time' => $time ) ); |
| 442 | + } else { |
| 443 | + $title = Title::makeTitleSafe( NS_FILE, $filename ); |
| 444 | + # FIXME: don't double fetch these (Parser just did)!!! |
| 445 | + $file = wfFindFile( $title ); |
440 | 446 | } |
441 | | - $title = Title::makeTitleSafe( NS_FILE, $filename ); |
442 | | - $file = wfFindFile( $title, array( 'time' => $time ) ); |
| 447 | + # Update tracking vars... |
443 | 448 | $pOutput->fr_fileSHA1Keys[$filename] = array(); |
444 | 449 | if ( $file ) { |
445 | 450 | $pOutput->fr_fileSHA1Keys[$filename]['ts'] = $file->getTimestamp(); |