break;
case 'gallery-internal-link':
$linkValue = strip_tags( $this->replaceLinkHoldersText( $match ) );
- $chars = self::EXT_LINK_URL_CLASS;
- $addr = self::EXT_LINK_ADDR;
- $prots = $this->mUrlProtocols;
- // check to see if link matches an absolute url, if not then it must be a wiki link.
if ( preg_match( '/^-{R|(.*)}-$/', $linkValue ) ) {
// Result of LanguageConverter::markNoConversion
// invoked on an external link.
$linkValue = substr( $linkValue, 4, -2 );
}
- if ( preg_match( "/^($prots)$addr$chars*$/u", $linkValue ) ) {
- $link = $linkValue;
- $this->mOutput->addExternalLink( $link );
- } else {
- $localLinkTitle = Title::newFromText( $linkValue );
- if ( $localLinkTitle !== null ) {
- $this->mOutput->addLink( $localLinkTitle );
- $link = $localLinkTitle->getLinkURL();
- }
+ list( $type, $target ) = $this->parseLinkParameter( $linkValue );
+ if ( $type === 'link-url' ) {
+ $link = $target;
+ $this->mOutput->addExternalLink( $target );
+ } elseif ( $type === 'link-title' ) {
+ $link = $target->getLinkURL();
+ $this->mOutput->addLink( $target );
}
break;
default:
$value = $this->stripAltText( $value, $holders );
break;
case 'link':
- $chars = self::EXT_LINK_URL_CLASS;
- $addr = self::EXT_LINK_ADDR;
- $prots = $this->mUrlProtocols;
- if ( $value === '' ) {
- $paramName = 'no-link';
- $value = true;
+ list( $paramName, $value ) = $this->parseLinkParameter( $value );
+ if ( $paramName ) {
$validated = true;
- } elseif ( preg_match( "/^((?i)$prots)/", $value ) ) {
- if ( preg_match( "/^((?i)$prots)$addr$chars*$/u", $value, $m ) ) {
- $paramName = 'link-url';
- $this->mOutput->addExternalLink( $value );
+ if ( $paramName === 'no-link' ) {
+ $value = true;
+ }
+ if ( $paramName === 'link-url' ) {
if ( $this->mOptions->getExternalLinkTarget() ) {
$params[$type]['link-target'] = $this->mOptions->getExternalLinkTarget();
}
- $validated = true;
- }
- } else {
- $linkTitle = Title::newFromText( $value );
- if ( $linkTitle ) {
- $paramName = 'link-title';
- $value = $linkTitle;
- $this->mOutput->addLink( $linkTitle );
- $validated = true;
}
}
break;
return $ret;
}
+ /**
+ * Parse the value of 'link' parameter in image syntax (`[[File:Foo.jpg|link=<value>]]`).
+ *
+ * Adds an entry to appropriate link tables.
+ *
+ * @since 1.32
+ * @return array of `[ type, target ]`, where:
+ * - `type` is one of:
+ * - `null`: Given value is not a valid link target, use default
+ * - `'no-link'`: Given value is empty, do not generate a link
+ * - `'link-url'`: Given value is a valid external link
+ * - `'link-title'`: Given value is a valid internal link
+ * - `target` is:
+ * - When `type` is `null` or `'no-link'`: `false`
+ * - When `type` is `'link-url'`: URL string corresponding to given value
+ * - When `type` is `'link-title'`: Title object corresponding to given value
+ */
+ public function parseLinkParameter( $value ) {
+ $chars = self::EXT_LINK_URL_CLASS;
+ $addr = self::EXT_LINK_ADDR;
+ $prots = $this->mUrlProtocols;
+ $type = null;
+ $target = false;
+ if ( $value === '' ) {
+ $type = 'no-link';
+ } elseif ( preg_match( "/^((?i)$prots)/", $value ) ) {
+ if ( preg_match( "/^((?i)$prots)$addr$chars*$/u", $value, $m ) ) {
+ $this->mOutput->addExternalLink( $value );
+ $type = 'link-url';
+ $target = $value;
+ }
+ } else {
+ $linkTitle = Title::newFromText( $value );
+ if ( $linkTitle ) {
+ $this->mOutput->addLink( $linkTitle );
+ $type = 'link-title';
+ $target = $linkTitle;
+ }
+ }
+ return [ $type, $target ];
+ }
+
/**
* @param string $caption
* @param LinkHolderArray|bool $holders
$result = $parserOutput->getCategoryLinks();
$this->assertEmpty( $result );
}
+
+ /**
+ * @covers Parser::parseLinkParameter
+ * @dataProvider provideParseLinkParameter
+ */
+ public function testParseLinkParameter( $input, $expected, $expectedLinks, $desc ) {
+ $this->parser->startExternalParse( Title::newFromText( __FUNCTION__ ),
+ $this->options, Parser::OT_HTML );
+ $output = $this->parser->parseLinkParameter( $input );
+
+ $this->assertEquals( $expected[0], $output[0], "$desc (type)" );
+
+ if ( $expected[0] === 'link-title' ) {
+ $this->assertTrue( $expected[1]->equals( $output[1] ), "$desc (target)" );
+ } else {
+ $this->assertEquals( $expected[1], $output[1], "$desc (target)" );
+ }
+
+ foreach ( $expectedLinks as $func => $expected ) {
+ $output = $this->parser->getOutput()->$func();
+ $this->assertEquals( $expected, $output, "$desc ($func)" );
+ }
+ }
+
+ public static function provideParseLinkParameter() {
+ return [
+ [
+ '',
+ [ 'no-link', false ],
+ [],
+ 'Return no link when requested',
+ ],
+ [
+ 'https://example.com/',
+ [ 'link-url', 'https://example.com/' ],
+ [ 'getExternalLinks' => [ 'https://example.com/' => 1 ] ],
+ 'External link',
+ ],
+ [
+ '//example.com/',
+ [ 'link-url', '//example.com/' ],
+ [ 'getExternalLinks' => [ '//example.com/' => 1 ] ],
+ 'External link',
+ ],
+ [
+ 'Test',
+ [ 'link-title', Title::newFromText( 'Test' ) ],
+ [ 'getLinks' => [ 0 => [ 'Test' => 0 ] ] ],
+ 'Internal link',
+ ],
+ [
+ 'mw:Test',
+ [ 'link-title', Title::newFromText( 'mw:Test' ) ],
+ [ 'getInterwikiLinks' => [ 'mw' => [ 'Test' => 1 ] ] ],
+ 'Internal link (interwiki)',
+ ],
+ [
+ 'https://',
+ [ null, false ],
+ [],
+ 'Invalid link target',
+ ],
+ [
+ '<>',
+ [ null, false ],
+ [],
+ 'Invalid link target',
+ ],
+ [
+ ' ',
+ [ null, false ],
+ [],
+ 'Invalid link target',
+ ],
+ ];
+ }
}