* change to support Images, literal URLs, etc.
* @param $text string The HTML contents of the <a> element, i.e.,
* the link text. This is raw HTML and will not be escaped. If null,
- * defaults to the page name of the Title.
+ * defaults to the prefixed text of the Title; or if the Title is just a
+ * fragment, the contents of the fragment.
* @param $query array The query string to append to the URL
* you're linking to, in key => value array form. Query keys and values
* will be URL-encoded.
* @param $options mixed String or array of strings:
* 'known': Page is known to exist, so don't check if it does.
* 'broken': Page is known not to exist, so don't check if it does.
- * 'noclasses': Don't add any classes automatically (includes "new", "stub", "mw-redirect"). Only use the class attribute provided, if any.
+ * 'noclasses': Don't add any classes automatically (includes "new",
+ * "stub", "mw-redirect", "extiw"). Only use the class attribute
+ * provided, if any, so you get a simple blue link with no funny i-
+ * cons.
* @return string HTML <a> attribute
*/
public function link( $target, $text = null, $customAttribs = array(), $query = array(), $options = array() ) {
wfProfileIn( __METHOD__ );
- if( !($target instanceof Title) ) {
+ if( !$target instanceof Title ) {
throw new MWException( 'Linker::link passed invalid target' );
}
$options = (array)$options;
# Normalize the Title if it's a special page
- if( $target->getNamespace() == NS_SPECIAL ) {
- list( $name, $subpage ) = SpecialPage::resolveAliasWithSubpage( $target->getDBkey() );
- if( $name ) {
- $target = SpecialPage::getTitleFor( $name, $subpage );
- }
- }
+ $target = $this->normaliseSpecialPage( $target );
# If we don't know whether the page exists, let's find out.
+ wfProfileIn( __METHOD__ . '-checkPageExistence' );
if( !in_array( 'known', $options ) and !in_array( 'broken', $options ) ) {
if( $target->getNamespace() == NS_SPECIAL ) {
if( SpecialPage::exists( $target->getDbKey() ) ) {
or $target->exists() ) {
$options []= 'known';
} else {
- # Either it exists
$options []= 'broken';
}
}
+ wfProfileOut( __METHOD__ . '-checkPageExistence' );
# Note: we want the href attribute first, for prettiness.
$attribs = array( 'href' => $this->linkUrl( $target, $query, $options ) );
$this->linkAttribs( $target, $customAttribs, $options )
);
if( is_null( $text ) ) {
- $text = $this->linkText( $target, $options );
+ $text = $this->linkText( $target );
}
- $ret = Xml::element( 'a', $attribs, $text, false );
+ $ret = Xml::openElement( 'a', $attribs )
+ . $text
+ . Xml::closeElement( 'a' );
wfProfileOut( __METHOD__ );
return $ret;
}
private function linkUrl( $target, $query, $options ) {
- # If it's a broken link, add the appropriate query pieces. This over-
- # writes the default action!
- if( in_array( 'broken', $options ) ) {
+ wfProfileIn( __METHOD__ );
+ # If it's a broken link, add the appropriate query pieces, unless
+ # there's already an action specified, or unless 'edit' makes no sense
+ # (i.e., for a nonexistent special page).
+ if( in_array( 'broken', $options ) and empty( $query['action'] )
+ and $target->getNamespace() != NS_SPECIAL ) {
$query['action'] = 'edit';
$query['redlink'] = '1';
}
-
- return $target->getLocalURL( wfArrayToCGI( $query ) );
+ $ret = $target->getLinkUrl( $query );
+ wfProfileOut( __METHOD__ );
+ return $ret;
}
private function linkAttribs( $target, $attribs, $options ) {
+ wfProfileIn( __METHOD__ );
global $wgUser;
$defaults = array();
- # First get a default title attribute.
- if( in_array( 'known', $options ) ) {
- $defaults['title'] = $target->getPrefixedText();
- } else {
- $defaults['title'] = wfMsg( 'red-link-title', $target->getPrefixedText() );
- }
-
if( !in_array( 'noclasses', $options ) ) {
- # Now build the classes. This is the bulk of what we're doing.
+ wfProfileIn( __METHOD__ . '-getClasses' );
+ # Build the classes.
$classes = array();
if( in_array( 'broken', $options ) ) {
- $classes []= 'new';
+ $classes[] = 'new';
+ }
+
+ if( $target->isExternal() ) {
+ $classes[] = 'extiw';
}
# Note that redirects never count as stubs here.
if ( $target->isRedirect() ) {
- $classes []= 'mw-redirect';
+ $classes[] = 'mw-redirect';
} elseif( $target->isContentPage() ) {
+ # Check for stub.
$threshold = $wgUser->getOption( 'stubthreshold' );
if( $threshold > 0 and $target->getLength() < $threshold ) {
- $classes []= 'stub';
+ $classes[] = 'stub';
}
}
if( $classes != array() ) {
$defaults['class'] = implode( ' ', $classes );
}
+ wfProfileOut( __METHOD__ . '-getClasses' );
+ }
+
+ # Get a default title attribute.
+ if( in_array( 'known', $options ) ) {
+ $defaults['title'] = $target->getPrefixedText();
+ } else {
+ $defaults['title'] = wfMsg( 'red-link-title', $target->getPrefixedText() );
}
# Finally, merge the custom attribs with the default ones, and iterate
$ret[$key] = $val;
}
}
+ wfProfileOut( __METHOD__ );
return $ret;
}
- private function linkText( $target, $options ) {
+ private function linkText( $target ) {
# If the target is just a fragment, with no title, we return the frag-
# ment text. Otherwise, we return the title text itself.
if( $target->getPrefixedText() === '' and $target->getFragment() !== '' ) {
if ( $title->getNamespace() == NS_SPECIAL ) {
list( $name, $subpage ) = SpecialPage::resolveAliasWithSubpage( $title->getDBkey() );
if ( !$name ) return $title;
- return SpecialPage::getTitleFor( $name, $subpage );
+ $ret = SpecialPage::getTitleFor( $name, $subpage );
+ $ret->mFragment = $title->getFragment();
+ return $ret;
} else {
return $title;
}
* @private
*/
function userLink( $userId, $userText ) {
- $encName = htmlspecialchars( $userText );
if( $userId == 0 ) {
$page = SpecialPage::getTitleFor( 'Contributions', $userText );
} else {
$page = Title::makeTitle( NS_USER, $userText );
}
- return $this->link( $page, $encName );
+ return $this->link( $page, htmlspecialchars( $userText ) );
}
/**
*
* @todo Document the $local parameter.
*/
- private function formatAutocomments( $comment, $title = NULL, $local = false ) {
+ private function formatAutocomments( $comment, $title = null, $local = false ) {
$match = array();
while (preg_match('!(.*)/\*\s*(.*?)\s*\*/(.*)!', $comment,$match)) {
$pre=$match[1];
$section = str_replace( '[[', '', $section );
$section = str_replace( ']]', '', $section );
if ( $local ) {
- $sectionTitle = Title::newFromText( '#' . $section);
+ $sectionTitle = Title::newFromText( '#' . $section );
} else {
- $sectionTitle = wfClone( $title );
+ $sectionTitle = clone( $title );
$sectionTitle->mFragment = $section;
}
- $link = $this->link( $sectionTitle, wfMsgForContent( 'sectionlink' ) );
+ $link = $this->link( $sectionTitle,
+ wfMsgForContent( 'sectionlink' ), array(), array(),
+ 'noclasses' );
}
$auto = $link . $auto;
if( $pre ) {
public function buildRollbackLink( $rev ) {
global $wgRequest, $wgUser;
$title = $rev->getTitle();
- $query = array( 'action' => 'rollback' );
+ $query = array(
+ 'action' => 'rollback',
+ 'from' => $rev->getUserText()
+ );
if( $wgRequest->getBool( 'bot' ) ) {
$query['bot'] = '1';
}
$query['token'] = $wgUser->editToken( array( $title->getPrefixedText(),
$rev->getUserText() ) );
return $this->link( $title, wfMsgHtml( 'rollbacklink' ), array(),
- $query, 'known' );
+ $query, array( 'known', 'noclasses' ) );
}
/**