Add support for fragments to WikiMap

WikiMap::makeForeignUrl should support fragement IDs in the
generated URL.

Change-Id: I612d5f465822b56356a78b3e72fb441a888668f1
This commit is contained in:
daniel 2015-09-11 16:17:52 +02:00
parent 3cecad00c9
commit 5852451177
4 changed files with 48 additions and 22 deletions

View file

@ -1464,7 +1464,7 @@ class Linker {
if ( $wikiId !== null ) {
$thelink = Linker::makeExternalLink(
WikiMap::getForeignURL( $wikiId, $target->getFullText() ),
WikiMap::getForeignURL( $wikiId, $target->getPrefixedText(), $target->getFragment() ),
$linkText . $inside,
/* escape = */ false // Already escaped
) . $trail;

View file

@ -108,13 +108,15 @@ class WikiMap {
*
* @param string $wikiID Wiki'd id (generally database name)
* @param string $page Page name (must be normalised before calling this function!)
* @param string|null $fragmentId
*
* @return string|bool URL or false if the wiki was not found
*/
public static function getForeignURL( $wikiID, $page ) {
public static function getForeignURL( $wikiID, $page, $fragmentId = null ) {
$wiki = WikiMap::getWiki( $wikiID );
if ( $wiki ) {
return $wiki->getFullUrl( $page );
return $wiki->getFullUrl( $page, $fragmentId );
}
return false;
@ -181,21 +183,32 @@ class WikiReference {
* Helper function for getUrl()
*
* @todo FIXME: This may be generalized...
* @param string $page Page name (must be normalised before calling this function!)
* @return string Url fragment
*
* @param string $page Page name (must be normalised before calling this function! May contain a section part.)
* @param string|null $fragmentId
*
* @return string relative URL, without the server part.
*/
private function getLocalUrl( $page ) {
return str_replace( '$1', wfUrlEncode( str_replace( ' ', '_', $page ) ), $this->mPath );
private function getLocalUrl( $page, $fragmentId = null ) {
$page = wfUrlEncode( str_replace( ' ', '_', $page ) );
if ( is_string( $fragmentId ) && $fragmentId !== '' ) {
$page .= '#' . wfUrlEncode( $fragmentId );
}
return str_replace( '$1', $page, $this->mPath );
}
/**
* Get a canonical (i.e. based on $wgCanonicalServer) URL to a page on this foreign wiki
*
* @param string $page Page name (must be normalised before calling this function!)
* @param string|null $fragmentId
*
* @return string Url
*/
public function getCanonicalUrl( $page ) {
return $this->mCanonicalServer . $this->getLocalUrl( $page );
public function getCanonicalUrl( $page, $fragmentId = null ) {
return $this->mCanonicalServer . $this->getLocalUrl( $page, $fragmentId );
}
/**
@ -209,10 +222,12 @@ class WikiReference {
/**
* Alias for getCanonicalUrl(), for backwards compatibility.
* @param string $page
* @param string|null $fragmentId
*
* @return string
*/
public function getUrl( $page ) {
return $this->getCanonicalUrl( $page );
public function getUrl( $page, $fragmentId = null ) {
return $this->getCanonicalUrl( $page, $fragmentId );
}
/**
@ -220,10 +235,12 @@ class WikiReference {
* when called locally on the wiki.
*
* @param string $page Page name (must be normalized before calling this function!)
* @param string|null $fragmentId
*
* @return string URL
*/
public function getFullUrl( $page ) {
public function getFullUrl( $page, $fragmentId = null ) {
return $this->mServer .
$this->getLocalUrl( $page );
$this->getLocalUrl( $page, $fragmentId );
}
}

View file

@ -93,6 +93,7 @@ class WikiMapTest extends MediaWikiLangTestCase {
return array(
'unknown' => array( false, 'xyzzy', 'Foo' ),
'enwiki' => array( 'http://en.example.org/w/Foo', 'enwiki', 'Foo', ),
'ruwiki with fragement' => array( '//ru.example.org/wiki/%D0%A4%D1%83#%D0%B2%D0%B0%D1%80', 'ruwiki', 'Фу', 'вар' ),
);
}

View file

@ -48,30 +48,38 @@ class WikiReferenceTest extends PHPUnit_Framework_TestCase {
public function provideGetCanonicalUrl() {
return array(
'wiki path' => array( 'https://acme.com/wiki/Foo', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo' ),
'empty path' => array( 'https://acme.com/Foo', 'https://acme.com', '//acme.com', '/$1', 'Foo' ),
'no fragement' => array( 'https://acme.com/wiki/Foo', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', null ),
'empty fragement' => array( 'https://acme.com/wiki/Foo', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', '' ),
'fragment' => array( 'https://acme.com/wiki/Foo#Bar', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', 'Bar' ),
'double fragment' => array( 'https://acme.com/wiki/Foo#Bar%23Xus', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', 'Bar#Xus' ),
'escaped fragement' => array( 'https://acme.com/wiki/Foo%23Bar', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo#Bar', null ),
'empty path' => array( 'https://acme.com/Foo', 'https://acme.com', '//acme.com', '/$1', 'Foo', null ),
);
}
/**
* @dataProvider provideGetCanonicalUrl
*/
public function testGetCanonicalUrl( $expected, $canonicalServer, $server, $path, $page ) {
public function testGetCanonicalUrl( $expected, $canonicalServer, $server, $path, $page, $fragmentId ) {
$reference = new WikiReference( 'wiki', 'xx', $canonicalServer, $path, $server );
$this->assertEquals( $expected, $reference->getCanonicalUrl( $page ) );
$this->assertEquals( $expected, $reference->getCanonicalUrl( $page, $fragmentId ) );
}
/**
* @dataProvider provideGetCanonicalUrl
*/
public function testGetUrl( $expected, $canonicalServer, $server, $path, $page ) {
public function testGetUrl( $expected, $canonicalServer, $server, $path, $page, $fragmentId ) {
$reference = new WikiReference( 'wiki', 'xx', $canonicalServer, $path, $server );
$this->assertEquals( $expected, $reference->getUrl( $page ) );
$this->assertEquals( $expected, $reference->getUrl( $page, $fragmentId ) );
}
public function provideGetFullUrl() {
return array(
'wiki path' => array( '//acme.com/wiki/Foo', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', null ),
'no fragement' => array( '//acme.com/wiki/Foo', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', null ),
'empty fragement' => array( '//acme.com/wiki/Foo', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', '' ),
'fragment' => array( '//acme.com/wiki/Foo#Bar', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', 'Bar' ),
'double fragment' => array( '//acme.com/wiki/Foo#Bar%23Xus', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', 'Bar#Xus' ),
'escaped fragement' => array( '//acme.com/wiki/Foo%23Bar', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo#Bar', null ),
'empty path' => array( '//acme.com/Foo', 'https://acme.com', '//acme.com', '/$1', 'Foo', null ),
);
}
@ -79,9 +87,9 @@ class WikiReferenceTest extends PHPUnit_Framework_TestCase {
/**
* @dataProvider provideGetFullUrl
*/
public function testGetFullUrl( $expected, $canonicalServer, $server, $path, $page ) {
public function testGetFullUrl( $expected, $canonicalServer, $server, $path, $page, $fragmentId ) {
$reference = new WikiReference( 'wiki', 'xx', $canonicalServer, $path, $server );
$this->assertEquals( $expected, $reference->getFullUrl( $page ) );
$this->assertEquals( $expected, $reference->getFullUrl( $page, $fragmentId ) );
}
}