Index: includes/Linker.php
===================================================================
--- includes/Linker.php (revision 17123)
+++ includes/Linker.php (working copy)
@@ -456,7 +456,7 @@
/** @todo document */
function makeImageLinkObj( $nt, $label, $alt, $align = '', $width = false, $height = false, $framed = false,
- $thumb = false, $manual_thumb = '', $page = null )
+ $thumb = false, $manual_thumb = '', $page = null, $link = '' )
{
global $wgContLang, $wgUser, $wgThumbLimits, $wgGenerateThumbnailOnParse;
@@ -506,7 +506,7 @@
$width = min( $img->getWidth(), $wgThumbLimits[$wopt] );
}
- return $prefix.$this->makeThumbLinkObj( $img, $label, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
+ return $prefix.$this->makeThumbLinkObj( $img, $label, $alt, $align, $width, $height, $framed, $manual_thumb, $link ).$postfix;
}
if ( $width && $img->exists() ) {
@@ -544,30 +544,117 @@
wfDebug( "makeImageLinkObj2: '$width'x'$height'\n" );
$u = $nt->escapeLocalURL();
+ $target = self::determineImageLinkTarget ( $link, $u );
if ( $error ) {
$s = $error;
} elseif ( $url == '' ) {
$s = $this->makeBrokenImageLinkObj( $img->getTitle() );
//$s .= "
{$alt}
{$url}
\n";
} else {
- $s = '' .
- '';
+ 'longdesc="'.$u.'" />';
+ if ($target) $s = '' . $s . '';
}
if ( '' != $align ) {
$s = "
{$s}
";
}
return str_replace("\n", ' ',$prefix.$s.$postfix);
}
+
+ /**
+ * @desc: There are 4 types of image links:
+ * 1) The image description page (default).
+ * 2) An internal image link (i.e. to another wiki page, not the image description page).
+ * 3) An external image link, off to some other site.
+ * 4) No link at all.
+ */
+ static private function determineImageLinkTarget ( $text, $fallback_url ) {
+ global $wgAllowNoImageTarget, $wgAllowInternalImageTarget, $wgAllowExternalImageTarget;
+ // no special linking allowed, so just return.
+ if ( !$wgAllowNoImageTarget && !$wgAllowInternalImageTarget && !$wgAllowExternalImageTarget) {
+ return $fallback_url;
+ }
+
+ // if there was no attempt to use special linking, then no point in doing any work.
+ if ( !$text ) {
+ return $fallback_url;
+ }
+
+ // Requested no image link.
+ $mwNone =& MagicWord::get( 'img_none' );
+ if ($wgAllowNoImageTarget && ! is_null( $mwNone->matchVariableStartToEnd($text) ) ) {
+ return null;
+ }
+
+ // Requested an internal link.
+ if ($wgAllowInternalImageTarget) {
+ // this is taken from excerpts of the replaceInternalLinks() function.
+ $m = array();
+ $tc = Title::legalChars() . '#%';
+ $el = "/^\[\[([{$tc}]+)]]$/sD";
+ if ( preg_match($el, trim($text), $m) ) {
+ # Don't allow internal links to pages containing
+ # PROTO: where PROTO is a valid URL protocol; these
+ # should probably be external links, with one square
+ # bracket. Just use the default description link instead.
+ if (preg_match('/^(\b(?:' . wfUrlProtocols() . '))/', $m[1])) {
+ return $fallback_url;
+ }
+ $link = $m[1];
+ $nt = Title::newFromText( $link );
+ if( !$nt ) {
+ return $fallback_url;
+ }
+ // otherwise use the internal URL.
+ return $nt->escapeLocalURL();
+ }
+ }
+
+ // Requested an external link.
+ if ($wgAllowExternalImageTarget) {
+ // this is taken from the replaceExternalLinks() function.
+ $bits = preg_split( EXT_LINK_BRACKETED, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
+ if ( empty ( $bits[1] ) ) {
+ return $fallback_url;
+ }
+
+ $external_url = $bits[1];
+
+ # The characters '<' and '>' (which were escaped by
+ # removeHTMLtags()) should not be included in
+ # URLs, per RFC 2396.
+ $m2 = array();
+ if (preg_match('/&(lt|gt);/', $external_url, $m2, PREG_OFFSET_CAPTURE)) {
+ $external_url = substr($external_url, 0, $m2[0][1]);
+ }
+
+ $external_url = Sanitizer::cleanUrl( $external_url );
+
+ # Register link in the output object.
+ # Replace unnecessary URL escape codes with the referenced character
+ # This prevents spammers from hiding links from the filters
+ $pasteurized = Parser::replaceUnusualEscapes( $external_url );
+
+ //### Q: How to call this?
+ //### $this->mOutput->addExternalLink( $pasteurized );
+ //### Is there some kind of global variable, or a function or something to get this?
+
+ return $external_url;
+ }
+
+ // The user gave us a link= parameter, but the link looks to be malformed. Use the standard image description linking as a fallback.
+ return $fallback_url;
+ }
+
/**
* Make HTML for a thumbnail including image, border and caption
* $img is an Image object
*/
- function makeThumbLinkObj( $img, $label = '', $alt, $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
+ function makeThumbLinkObj( $img, $label = '', $alt, $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "", $link = "" ) {
global $wgStylePath, $wgContLang, $wgGenerateThumbnailOnParse;
$thumbUrl = '';
$error = '';
@@ -622,6 +709,7 @@
}
$u = $img->getEscapeLocalURL();
+ $target = self::determineImageLinkTarget ( $link, $u );
$more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
$magnifyalign = $wgContLang->isRTL() ? 'left' : 'right';
@@ -639,10 +727,11 @@
$s .= $this->makeBrokenImageLinkObj( $img->getTitle() );
$zoomicon = '';
} else {
- $s .= ''.
- '';
+ $s .= '';
+ 'longdesc="'.$u.'" />';
+ if ($target) $s .= '';
if ( $framed ) {
$zoomicon="";
} else {
@@ -698,8 +787,6 @@
*
* @param $title Title object.
* @param $text String: pre-sanitized HTML
- * @param $nourl Boolean: Mask absolute URLs, so the parser doesn't
- * linkify them (it is currently not context-aware)
* @return string HTML
*
* @public
Index: includes/Parser.php
===================================================================
--- includes/Parser.php (revision 17123)
+++ includes/Parser.php (working copy)
@@ -436,7 +436,7 @@
/**
* Replaces all occurrences of HTML-style comments and the given tags
- * in the text with a random marker and returns teh next text. The output
+ * in the text with a random marker and returns the next text. The output
* parameter $matches will be an associative array filled with data in
* the form:
* 'UNIQ-xxxxx' => array(
@@ -1681,12 +1681,6 @@
if ( $ns == NS_IMAGE ) {
wfProfileIn( "$fname-image" );
if ( !wfIsBadImage( $nt->getDBkey(), $this->mTitle ) ) {
- # recursively parse links inside the image caption
- # actually, this will parse them in any other parameters, too,
- # but it might be hard to fix that, and it doesn't matter ATM
- $text = $this->replaceExternalLinks($text);
- $text = $this->replaceInternalLinks($text);
-
# cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them
$s .= $prefix . $this->armorLinks( $this->makeImage( $nt, $text ) ) . $trail;
$this->mOutput->addImage( $nt->getDBkey() );
@@ -4270,13 +4264,15 @@
# Check if the options text is of the form "options|alt text"
# Options are:
- # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
- # * left no resizing, just left align. label is used for alt= only
- # * right same, but right aligned
- # * none same, but not aligned
- # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
- # * center center the image
- # * framed Keep original image size, no magnify-button.
+ # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
+ # * left no resizing, just left align. label is used for alt= only
+ # * right same, but right aligned
+ # * none same, but not aligned
+ # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
+ # * center center the image
+ # * framed Keep original image size, no magnify-button.
+ # * thumb=___ use manually specified thumbnail.
+ # * link=___ Specify an image link target besides the image description page.
$part = explode( '|', $options);
@@ -4289,11 +4285,12 @@
$mwCenter =& MagicWord::get( 'img_center' );
$mwFramed =& MagicWord::get( 'img_framed' );
$mwPage =& MagicWord::get( 'img_page' );
+ $mwLink =& MagicWord::get( 'img_link' );
$caption = '';
$width = $height = $framed = $thumb = false;
$page = null;
- $manual_thumb = '' ;
+ $manual_thumb = $link = '' ;
foreach( $part as $val ) {
if ( $wgUseImageResize && ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
@@ -4330,10 +4327,18 @@
}
} elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
$framed=true;
+ } elseif ( ! is_null( $match = $mwLink->matchVariableStartToEnd($val) ) ) {
+ # use manually specified link target
+ $link = $match;
} else {
- $caption = $val;
+ $caption .= ($caption ? "|" : "") . $val;
}
}
+
+ # recursively parse links inside the image caption
+ $caption = $this->replaceExternalLinks($caption);
+ $caption = $this->replaceInternalLinks($caption);
+
# Strip bad stuff out of the alt text
$alt = $this->replaceLinkHoldersText( $caption );
@@ -4345,7 +4350,7 @@
# Linker does the rest
$sk =& $this->mOptions->getSkin();
- return $sk->makeImageLinkObj( $nt, $caption, $alt, $align, $width, $height, $framed, $thumb, $manual_thumb, $page );
+ return $sk->makeImageLinkObj( $nt, $caption, $alt, $align, $width, $height, $framed, $thumb, $manual_thumb, $page, $link );
}
/**
Index: includes/DefaultSettings.php
===================================================================
--- includes/DefaultSettings.php (revision 17123)
+++ includes/DefaultSettings.php (working copy)
@@ -2300,4 +2300,15 @@
$wgEnableAPI = true;
$wgEnableWriteAPI = false;
+/**
+ * Options for whether an image can link to things besides the standard image description page.
+ * First allows users to specify an External link target for an image.
+ * Second allows users to specify an Internal wiki link target for an image.
+ * Third allows users to specify no link target for an image.
+ * Default setting for all three is off.
+ */
+$wgAllowExternalImageTarget = false;
+$wgAllowInternalImageTarget = false;
+$wgAllowNoImageTarget = false;
+
?>
Index: languages/messages/MessagesEn.php
===================================================================
--- languages/messages/MessagesEn.php (revision 17123)
+++ languages/messages/MessagesEn.php (working copy)
@@ -247,6 +247,7 @@
'end' => array( 0, '__END__' ),
'img_thumbnail' => array( 1, 'thumbnail', 'thumb' ),
'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1'),
+ 'img_link' => array( 1, 'link=$1', 'target=$1' ),
'img_right' => array( 1, 'right' ),
'img_left' => array( 1, 'left' ),
'img_none' => array( 1, 'none' ),