Brian Wolff has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/60858


Change subject: Allow handler specific parameters in <gallery> (page number, 
etc)
......................................................................

Allow handler specific parameters in <gallery> (page number, etc)

For multipage media, people really want to be able to specify
if the image gallery should display page 1 or page 10. This
also allows other handler specific parameters like thumbtime
for videos, "lossy" for tiff files, etc.

Note, this only allows the handler specific options
(typically things that would change an image). Other options in
the thumb syntax like class, border, upright, left, etc are
still not supported (and mostly probably should not be)

Bug: 8480

Change-Id: Ib831d89ed8676deb2f44238ff9a23ce58ad4d2df
---
M RELEASE-NOTES-1.22
M includes/ImageGallery.php
M includes/parser/Parser.php
3 files changed, 101 insertions(+), 32 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/58/60858/1

diff --git a/RELEASE-NOTES-1.22 b/RELEASE-NOTES-1.22
index eda1e7c..588f6b7 100644
--- a/RELEASE-NOTES-1.22
+++ b/RELEASE-NOTES-1.22
@@ -45,6 +45,7 @@
   another portlet will work as expected.
 * (bug 6747) {{ROOTPAGENAME}} introduced, contains the name of the topmost
   page without namespace.
+* (bug 8480) Allow handler specific parameters in galleries (like page number)
 
 === Bug fixes in 1.22 ===
 * Disable Special:PasswordReset when $wgEnableEmail. Previously one could still
diff --git a/includes/ImageGallery.php b/includes/ImageGallery.php
index 43cf7f6..2b0edda 100644
--- a/includes/ImageGallery.php
+++ b/includes/ImageGallery.php
@@ -160,13 +160,14 @@
         * @param $html  String: Additional HTML text to be shown. The name and 
size of the image are always shown.
         * @param $alt   String: Alt text for the image
         * @param $link  String: Override image link (optional)
+        * @param $handlerOpts Array: Array of options for image handler (aka 
page number)
         */
-       function add( $title, $html = '', $alt = '', $link = '' ) {
+       function add( $title, $html = '', $alt = '', $link = '', $handlerOpts = 
array() ) {
                if ( $title instanceof File ) {
                        // Old calling convention
                        $title = $title->getTitle();
                }
-               $this->mImages[] = array( $title, $html, $alt, $link );
+               $this->mImages[] = array( $title, $html, $alt, $link, 
$handlerOpts );
                wfDebug( 'ImageGallery::add ' . $title->getText() . "\n" );
        }
 
@@ -176,13 +177,15 @@
         * @param $title Title object of the image that is added to the gallery
         * @param $html  String: Additional HTML text to be shown. The name and 
size of the image are always shown.
         * @param $alt   String: Alt text for the image
+        * @param $link  String: Override image link (optional)
+        * @param $handlerOpts Array: Array of options for image handler (aka 
page number)
         */
-       function insert( $title, $html = '', $alt = '' ) {
+       function insert( $title, $html = '', $alt = '', $link = '', 
$handlerOpts = array() ) {
                if ( $title instanceof File ) {
                        // Old calling convention
                        $title = $title->getTitle();
                }
-               array_unshift( $this->mImages, array( &$title, $html, $alt ) );
+               array_unshift( $this->mImages, array( &$title, $html, $alt, 
$link, $handlerOpts ) );
        }
 
        /**
@@ -264,6 +267,8 @@
                        $text = $pair[1]; # "text" means "caption" here
                        $alt = $pair[2];
                        $link = $pair[3];
+                       // $pair[4] is per image handler options
+                       $transformOptions = $params + $pair[4];
 
                        $descQuery = false;
                        if ( $nt->getNamespace() == NS_FILE ) {
@@ -297,7 +302,7 @@
                                                array( 'known', 'noclasses' )
                                        ) .
                                        '</div>';
-                       } elseif ( !( $thumb = $img->transform( $params ) ) ) {
+                       } elseif ( !( $thumb = $img->transform( 
$transformOptions ) ) ) {
                                # Error generating thumbnail.
                                $thumbhtml = "\n\t\t\t" . '<div style="height: 
' . ( self::THUMB_PADDING + $this->mHeights ) . 'px;">'
                                        . htmlspecialchars( 
$img->getLastError() ) . '</div>';
diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php
index ab69256..47594a6 100644
--- a/includes/parser/Parser.php
+++ b/includes/parser/Parser.php
@@ -3766,13 +3766,8 @@
         * @return Array ( File or false, Title of file )
         */
        function fetchFileAndTitle( $title, $options = array() ) {
-               if ( isset( $options['broken'] ) ) {
-                       $file = false; // broken thumbnail forced by hook
-               } elseif ( isset( $options['sha1'] ) ) { // get by 
(sha1,timestamp)
-                       $file = RepoGroup::singleton()->findFileFromKey( 
$options['sha1'], $options );
-               } else { // get by (name,timestamp)
-                       $file = wfFindFile( $title, $options );
-               }
+               $file = $this->fetchFileNoRegister( $title, $options );
+
                $time = $file ? $file->getTimestamp() : false;
                $sha1 = $file ? $file->getSha1() : false;
                # Register the file as a dependency...
@@ -3788,6 +3783,26 @@
                        }
                }
                return array( $file, $title );
+       }
+       /**
+        * Helper function for fetchFileAndTitle.
+        *
+        * Also useful if you need to fetch a file but not use it yet,
+        * for example to get the file's handler.
+        *
+        * @param Title $title
+        * @param array $options Array of options to RepoGroup::findFile
+        * @return File or false
+        */
+       protected function fetchFileNoRegister( $title, $options = array() ) {
+               if ( isset( $options['broken'] ) ) {
+                       $file = false; // broken thumbnail forced by hook
+               } elseif ( isset( $options['sha1'] ) ) { // get by 
(sha1,timestamp)
+                       $file = RepoGroup::singleton()->findFileFromKey( 
$options['sha1'], $options );
+               } else { // get by (name,timestamp)
+                       $file = wfFindFile( $title, $options );
+               }
+               return $file;
        }
 
        /**
@@ -5007,6 +5022,7 @@
         * @return string HTML
         */
        function renderImageGallery( $text, $params ) {
+               wfProfileIn( __METHOD__ );
                $ig = new ImageGallery();
                $ig->setContextTitle( $this->mTitle );
                $ig->setShowBytes( false );
@@ -5058,38 +5074,83 @@
                                continue;
                        }
 
+                       # We need to get what handler the file uses, to figure 
out parameters.
+                       # Note, a hook can overide the file name, and chose an 
entirely different
+                       # file (which potentially could be of a different type 
and have different handler).
+                       $options = array();
+                       $descQuery = false;
+                       wfRunHooks( 'BeforeParserFetchFileAndTitle',
+                               array( $this, $title, &$options, &$descQuery ) 
);
+                       # Don't register it now, as ImageGallery does that 
later.
+                       $file = $this->fetchFileNoRegister( $title, $options );
+                       $handler = $file ? $file->getHandler() : false;
+
+                       wfProfileIn( __METHOD__ . '-getMagicWord' );
+                       $paramMap = array(
+                               'img_alt' => 'gallery-internal-alt',
+                               'img_link' => 'gallery-internal-link',
+                       );
+                       if ( $handler ) {
+                               $paramMap = $paramMap + $handler->getParamMap();
+                               if ( isset( $paramMap['img_width'] ) ) {
+                                       // We don't want people to specify 
per-image widths.
+                                       // Additionally the width parameter 
would need special casing anyhow.
+                                       unset( $paramMap['img_width'] );
+                               }
+                       }
+
+                       $mwArray = new MagicWordArray( array_keys( $paramMap ) 
);
+                       wfProfileOut( __METHOD__ . '-getMagicWord' );
+
                        $label = '';
                        $alt = '';
                        $link = '';
+                       $handlerOptions = array();
                        if ( isset( $matches[3] ) ) {
                                // look for an |alt= definition while trying 
not to break existing
                                // captions with multiple pipes (|) in it, 
until a more sensible grammar
                                // is defined for images in galleries
 
+                               // FIXME: Doing recursiveTagParse at this 
stage, and the trim before
+                               // splitting on '|' is a bit odd, and different 
from makeImage.
                                $matches[3] = $this->recursiveTagParse( trim( 
$matches[3] ) );
                                $parameterMatches = StringUtils::explode( '|', 
$matches[3] );
-                               $magicWordAlt = MagicWord::get( 'img_alt' );
-                               $magicWordLink = MagicWord::get( 'img_link' );
 
                                foreach ( $parameterMatches as $parameterMatch 
) {
-                                       if ( $match = 
$magicWordAlt->matchVariableStartToEnd( $parameterMatch ) ) {
-                                               $alt = $this->stripAltText( 
$match, false );
-                                       }
-                                       elseif ( $match = 
$magicWordLink->matchVariableStartToEnd( $parameterMatch ) ) {
-                                               $linkValue = strip_tags( 
$this->replaceLinkHoldersText( $match ) );
-                                               $chars = 
self::EXT_LINK_URL_CLASS;
-                                               $prots = $this->mUrlProtocols;
-                                               //check to see if link matches 
an absolute url, if not then it must be a wiki link.
-                                               if ( preg_match( 
"/^($prots)$chars+$/u", $linkValue ) ) {
-                                                       $link = $linkValue;
-                                               } else {
-                                                       $localLinkTitle = 
Title::newFromText( $linkValue );
-                                                       if ( $localLinkTitle 
!== null ) {
-                                                               $link = 
$localLinkTitle->getLocalURL();
+                                       list( $magicName, $match ) = 
$mwArray->matchVariableStartToEnd( $parameterMatch );
+                                       if ( $magicName ) {
+                                               $paramName = 
$paramMap[$magicName];
+
+                                               switch( $paramName ) {
+                                               case 'gallery-internal-alt':
+                                                       $alt = 
$this->stripAltText( $match, false );
+                                                       break;
+                                               case 'gallery-internal-link':
+                                                       $linkValue = 
strip_tags( $this->replaceLinkHoldersText( $match ) );
+                                                       $chars = 
self::EXT_LINK_URL_CLASS;
+                                                       $prots = 
$this->mUrlProtocols;
+                                                       //check to see if link 
matches an absolute url, if not then it must be a wiki link.
+                                                       if ( preg_match( 
"/^($prots)$chars+$/u", $linkValue ) ) {
+                                                               $link = 
$linkValue;
+                                                       } else {
+                                                               $localLinkTitle 
= Title::newFromText( $linkValue );
+                                                               if ( 
$localLinkTitle !== null ) {
+                                                                       $link = 
$localLinkTitle->getLocalURL();
+                                                               }
+                                                       }
+                                                       break;
+                                               default:
+                                                       // Must be a handler 
specific parameter.
+                                                       if ( 
$handler->validateParam( $paramName, $match ) ) {
+                                                               
$handlerOptions[$paramName] = $match;
+                                                       } else {
+                                                               // Guess not. 
Append it to the caption.
+                                                               wfDebug( 
"$parameterMatch failed parameter validation" );
+                                                               $label .= '|' . 
$parameterMatch;
                                                        }
                                                }
-                                       }
-                                       else {
+
+                                       } else {
                                                // concatenate all other pipes
                                                $label .= '|' . $parameterMatch;
                                        }
@@ -5098,9 +5159,11 @@
                                $label = substr( $label, 1 );
                        }
 
-                       $ig->add( $title, $label, $alt, $link );
+                       $ig->add( $title, $label, $alt, $link, $handlerOptions 
);
                }
-               return $ig->toHTML();
+               $html = $ig->toHTML();
+               wfProfileOut( __METHOD__ );
+               return $html;
        }
 
        /**

-- 
To view, visit https://gerrit.wikimedia.org/r/60858
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib831d89ed8676deb2f44238ff9a23ce58ad4d2df
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Brian Wolff <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to