diff options
Diffstat (limited to 'includes/SkinTemplate.php')
-rw-r--r-- | includes/SkinTemplate.php | 446 |
1 files changed, 284 insertions, 162 deletions
diff --git a/includes/SkinTemplate.php b/includes/SkinTemplate.php index bda43957..53f11998 100644 --- a/includes/SkinTemplate.php +++ b/includes/SkinTemplate.php @@ -43,7 +43,7 @@ class MediaWiki_I18N { $value = wfMessage( $value )->text(); // interpolate variables $m = array(); - while( preg_match( '/\$([0-9]*?)/sm', $value, $m ) ) { + while ( preg_match( '/\$([0-9]*?)/sm', $value, $m ) ) { list( $src, $var ) = $m; wfSuppressWarnings(); $varValue = $this->_context[$var]; @@ -113,7 +113,7 @@ class SkinTemplate extends Skin { * roughly equivalent to PHPTAL 0.7. * * @param $classname String - * @param $repository string: subdirectory where we keep template files + * @param string $repository subdirectory where we keep template files * @param $cache_dir string * @return QuickTemplate * @private @@ -123,38 +123,61 @@ class SkinTemplate extends Skin { } /** - * initialize various variables and generate the template + * Generates array of language links for the current page * - * @param $out OutputPage + * @return array + * @public */ - function outputPage( OutputPage $out=null ) { - global $wgContLang; - global $wgScript, $wgStylePath; - global $wgMimeType, $wgJsMimeType; - global $wgXhtmlDefaultNamespace, $wgXhtmlNamespaces, $wgHtml5Version; - global $wgDisableCounters, $wgSitename, $wgLogo, $wgHideInterlanguageLinks; - global $wgMaxCredits, $wgShowCreditsIfMax; - global $wgPageShowWatchingUsers; - global $wgArticlePath, $wgScriptPath, $wgServer; + public function getLanguages() { + global $wgHideInterlanguageLinks; + $out = $this->getOutput(); + $userLang = $this->getLanguage(); - wfProfileIn( __METHOD__ ); - Profiler::instance()->setTemplated( true ); + # Language links + $language_urls = array(); - $oldContext = null; - if ( $out !== null ) { - // @todo Add wfDeprecated in 1.20 - $oldContext = $this->getContext(); - $this->setContext( $out->getContext() ); + if ( !$wgHideInterlanguageLinks ) { + foreach ( $out->getLanguageLinks() as $languageLinkText ) { + $languageLinkParts = explode( ':', $languageLinkText, 2 ); + $class = 'interwiki-' . $languageLinkParts[0]; + unset( $languageLinkParts ); + $languageLinkTitle = Title::newFromText( $languageLinkText ); + if ( $languageLinkTitle ) { + $ilInterwikiCode = $languageLinkTitle->getInterwiki(); + $ilLangName = Language::fetchLanguageName( $ilInterwikiCode ); + + if ( strval( $ilLangName ) === '' ) { + $ilLangName = $languageLinkText; + } else { + $ilLangName = $this->formatLanguageName( $ilLangName ); + } + + // CLDR extension or similar is required to localize the language name; + // otherwise we'll end up with the autonym again. + $ilLangLocalName = Language::fetchLanguageName( $ilInterwikiCode, $userLang->getCode() ); + + $language_urls[] = array( + 'href' => $languageLinkTitle->getFullURL(), + 'text' => $ilLangName, + 'title' => wfMessage( 'interlanguage-link-title', $languageLinkTitle->getText(), $ilLangLocalName )->text(), + 'class' => $class, + 'lang' => wfBCP47( $ilInterwikiCode ), + 'hreflang' => wfBCP47( $ilInterwikiCode ), + ); + } + } } + return $language_urls; + } + + protected function setupTemplateForOutput() { + wfProfileIn( __METHOD__ ); - $out = $this->getOutput(); $request = $this->getRequest(); $user = $this->getUser(); $title = $this->getTitle(); wfProfileIn( __METHOD__ . '-init' ); - $this->initPage( $out ); - $tpl = $this->setupTemplate( $this->template, 'skins' ); wfProfileOut( __METHOD__ . '-init' ); @@ -169,7 +192,7 @@ class SkinTemplate extends Skin { unset( $query['returnto'] ); unset( $query['returntoquery'] ); } - $this->thisquery = wfArrayToCGI( $query ); + $this->thisquery = wfArrayToCgi( $query ); $this->loggedin = $user->isLoggedIn(); $this->username = $user->getName(); @@ -183,6 +206,47 @@ class SkinTemplate extends Skin { wfProfileOut( __METHOD__ . '-stuff' ); + wfProfileOut( __METHOD__ ); + + return $tpl; + } + + /** + * initialize various variables and generate the template + * + * @param $out OutputPage + */ + function outputPage( OutputPage $out = null ) { + global $wgContLang; + global $wgScript, $wgStylePath; + global $wgMimeType, $wgJsMimeType; + global $wgXhtmlNamespaces, $wgHtml5Version; + global $wgDisableCounters, $wgSitename, $wgLogo; + global $wgMaxCredits, $wgShowCreditsIfMax; + global $wgPageShowWatchingUsers; + global $wgArticlePath, $wgScriptPath, $wgServer; + + wfProfileIn( __METHOD__ ); + Profiler::instance()->setTemplated( true ); + + $oldContext = null; + if ( $out !== null ) { + // @todo Add wfDeprecated in 1.20 + $oldContext = $this->getContext(); + $this->setContext( $out->getContext() ); + } + + $out = $this->getOutput(); + $request = $this->getRequest(); + $user = $this->getUser(); + $title = $this->getTitle(); + + wfProfileIn( __METHOD__ . '-init' ); + $this->initPage( $out ); + wfProfileOut( __METHOD__ . '-init' ); + + $tpl = $this->setupTemplateForOutput(); + wfProfileIn( __METHOD__ . '-stuff-head' ); if ( !$this->useHeadElement ) { $tpl->set( 'pagecss', false ); @@ -193,7 +257,7 @@ class SkinTemplate extends Skin { $tpl->set( 'jsvarurl', false ); - $tpl->setRef( 'xhtmldefaultnamespace', $wgXhtmlDefaultNamespace ); + $tpl->set( 'xhtmldefaultnamespace', 'http://www.w3.org/1999/xhtml' ); $tpl->set( 'xhtmlnamespaces', $wgXhtmlNamespaces ); $tpl->set( 'html5version', $wgHtml5Version ); $tpl->set( 'headlinks', $out->getHeadLinks() ); @@ -219,7 +283,7 @@ class SkinTemplate extends Skin { if ( $subpagestr !== '' ) { $subpagestr = '<span class="subpages">' . $subpagestr . '</span>'; } - $tpl->set( 'subtitle', $subpagestr . $out->getSubtitle() ); + $tpl->set( 'subtitle', $subpagestr . $out->getSubtitle() ); $undelete = $this->getUndeleteLink(); if ( $undelete === '' ) { @@ -229,10 +293,11 @@ class SkinTemplate extends Skin { } $tpl->set( 'catlinks', $this->getCategories() ); - if( $out->isSyndicated() ) { + if ( $out->isSyndicated() ) { $feeds = array(); - foreach( $out->getSyndicationLinks() as $format => $link ) { + foreach ( $out->getSyndicationLinks() as $format => $link ) { $feeds[$format] = array( + // Messages: feed-atom, feed-rss 'text' => $this->msg( "feed-$format" )->text(), 'href' => $link ); @@ -262,7 +327,7 @@ class SkinTemplate extends Skin { $tpl->set( 'helppage', $this->msg( 'helppage' )->text() ); */ $tpl->set( 'searchaction', $this->escapeSearchLink() ); - $tpl->set( 'searchtitle', SpecialPage::getTitleFor( 'Search' )->getPrefixedDBKey() ); + $tpl->set( 'searchtitle', SpecialPage::getTitleFor( 'Search' )->getPrefixedDBkey() ); $tpl->set( 'search', trim( $request->getVal( 'search' ) ) ); $tpl->setRef( 'stylepath', $wgStylePath ); $tpl->setRef( 'articlepath', $wgArticlePath ); @@ -273,14 +338,14 @@ class SkinTemplate extends Skin { $userLang = $this->getLanguage(); $userLangCode = $userLang->getHtmlCode(); - $userLangDir = $userLang->getDir(); + $userLangDir = $userLang->getDir(); $tpl->set( 'lang', $userLangCode ); $tpl->set( 'dir', $userLangDir ); $tpl->set( 'rtl', $userLang->isRTL() ); $tpl->set( 'capitalizeallnouns', $userLang->capitalizeAllNouns() ? ' capitalize-all-nouns' : '' ); - $tpl->set( 'showjumplinks', $user->getOption( 'showjumplinks' ) ); + $tpl->set( 'showjumplinks', true ); // showjumplinks preference has been removed $tpl->set( 'username', $this->loggedin ? $this->username : null ); $tpl->setRef( 'userpage', $this->userpage ); $tpl->setRef( 'userpageurl', $this->userpageUrlDetails['href'] ); @@ -398,44 +463,18 @@ class SkinTemplate extends Skin { # not for special pages or file pages AND only when viewing AND if the page exists # (or is in MW namespace, because that has default content) if ( !in_array( $title->getNamespace(), array( NS_SPECIAL, NS_FILE ) ) && - in_array( $request->getVal( 'action', 'view' ), array( 'view', 'historysubmit' ) ) && + Action::getActionName( $this ) === 'view' && ( $title->exists() || $title->getNamespace() == NS_MEDIAWIKI ) ) { $pageLang = $title->getPageViewLanguage(); $realBodyAttribs['lang'] = $pageLang->getHtmlCode(); $realBodyAttribs['dir'] = $pageLang->getDir(); - $realBodyAttribs['class'] = 'mw-content-'.$pageLang->getDir(); + $realBodyAttribs['class'] = 'mw-content-' . $pageLang->getDir(); } $out->mBodytext = Html::rawElement( 'div', $realBodyAttribs, $out->mBodytext ); $tpl->setRef( 'bodytext', $out->mBodytext ); - # Language links - $language_urls = array(); - - if ( !$wgHideInterlanguageLinks ) { - foreach( $out->getLanguageLinks() as $l ) { - $tmp = explode( ':', $l, 2 ); - $class = 'interwiki-' . $tmp[0]; - unset( $tmp ); - $nt = Title::newFromText( $l ); - if ( $nt ) { - $ilLangName = Language::fetchLanguageName( $nt->getInterwiki() ); - if ( strval( $ilLangName ) === '' ) { - $ilLangName = $l; - } else { - $ilLangName = $this->getLanguage()->ucfirst( $ilLangName ); - } - $language_urls[] = array( - 'href' => $nt->getFullURL(), - 'text' => $ilLangName, - 'title' => $nt->getText(), - 'class' => $class, - 'lang' => $nt->getInterwiki(), - 'hreflang' => $nt->getInterwiki(), - ); - } - } - } + $language_urls = $this->getLanguages(); if ( count( $language_urls ) ) { $tpl->setRef( 'language_urls', $language_urls ); } else { @@ -466,7 +505,7 @@ class SkinTemplate extends Skin { $tpl->set( 'reporttime', wfReportTime() ); // original version by hansm - if( !wfRunHooks( 'SkinTemplateOutputPageBeforeExec', array( &$this, &$tpl ) ) ) { + if ( !wfRunHooks( 'SkinTemplateOutputPageBeforeExec', array( &$this, &$tpl ) ) ) { wfDebug( __METHOD__ . ": Hook SkinTemplateOutputPageBeforeExec broke outputPage execution!\n" ); } @@ -499,6 +538,32 @@ class SkinTemplate extends Skin { } /** + * Get the HTML for the p-personal list + * @return string + */ + public function getPersonalToolsList() { + $tpl = $this->setupTemplateForOutput(); + $tpl->set( 'personal_urls', $this->buildPersonalUrls() ); + $html = ''; + foreach ( $tpl->getPersonalTools() as $key => $item ) { + $html .= $tpl->makeListItem( $key, $item ); + } + return $html; + } + + /** + * Format language name for use in sidebar interlanguage links list. + * By default it is capitalized. + * + * @param string $name Language name, e.g. "English" or "espaƱol" + * @return string + * @private + */ + function formatLanguageName( $name ) { + return $this->getLanguage()->ucfirst( $name ); + } + + /** * Output the string, or print error message if it's * an error object of the appropriate type. * For the base class, assume strings all around. @@ -511,7 +576,7 @@ class SkinTemplate extends Skin { } /** - * Output a boolean indiciating if buildPersonalUrls should output separate + * Output a boolean indicating if buildPersonalUrls should output separate * login and create account links or output a combined link * By default we simply return a global config setting that affects most skins * This is setup as a method so that like with $wgLogo and getLogo() a skin @@ -541,18 +606,23 @@ class SkinTemplate extends Skin { # $this->getTitle() will just give Special:Badtitle, which is # not especially useful as a returnto parameter. Use the title # from the request instead, if there was one. - $page = Title::newFromURL( $request->getVal( 'title', '' ) ); + if ( $this->getUser()->isAllowed( 'read' ) ) { + $page = $this->getTitle(); + } else { + $page = Title::newFromText( $request->getVal( 'title', '' ) ); + } $page = $request->getVal( 'returnto', $page ); $a = array(); if ( strval( $page ) !== '' ) { $a['returnto'] = $page; $query = $request->getVal( 'returntoquery', $this->thisquery ); - if( $query != '' ) { + if ( $query != '' ) { $a['returntoquery'] = $query; } } - $returnto = wfArrayToCGI( $a ); - if( $this->loggedin ) { + + $returnto = wfArrayToCgi( $a ); + if ( $this->loggedin ) { $personal_urls['userpage'] = array( 'text' => $this->username, 'href' => &$this->userpageUrlDetails['href'], @@ -573,12 +643,15 @@ class SkinTemplate extends Skin { 'href' => $href, 'active' => ( $href == $pageurl ) ); - $href = self::makeSpecialUrl( 'Watchlist' ); - $personal_urls['watchlist'] = array( - 'text' => $this->msg( 'mywatchlist' )->text(), - 'href' => $href, - 'active' => ( $href == $pageurl ) - ); + + if ( $this->getUser()->isAllowed( 'viewmywatchlist' ) ) { + $href = self::makeSpecialUrl( 'Watchlist' ); + $personal_urls['watchlist'] = array( + 'text' => $this->msg( 'mywatchlist' )->text(), + 'href' => $href, + 'active' => ( $href == $pageurl ) + ); + } # We need to do an explicit check for Special:Contributions, as we # have to match both the title, and the target, which could come @@ -588,7 +661,7 @@ class SkinTemplate extends Skin { # thickens, because the Title object is altered for special pages, # so it doesn't contain the original alias-with-subpage. $origTitle = Title::newFromText( $request->getText( 'title' ) ); - if( $origTitle instanceof Title && $origTitle->isSpecialPage() ) { + if ( $origTitle instanceof Title && $origTitle->isSpecialPage() ) { list( $spName, $spPar ) = SpecialPageFactory::resolveAlias( $origTitle->getText() ); $active = $spName == 'Contributions' && ( ( $spPar && $spPar == $this->username ) @@ -619,25 +692,19 @@ class SkinTemplate extends Skin { : 'login'; $is_signup = $request->getText( 'type' ) == 'signup'; - # anonlogin & login are the same - global $wgSecureLogin; - $proto = $wgSecureLogin ? PROTO_HTTPS : null; - $login_id = $this->showIPinHeader() ? 'anonlogin' : 'login'; $login_url = array( 'text' => $this->msg( $loginlink )->text(), - 'href' => self::makeSpecialUrl( 'Userlogin', $returnto, $proto ), + 'href' => self::makeSpecialUrl( 'Userlogin', $returnto ), 'active' => $title->isSpecial( 'Userlogin' ) && ( $loginlink == 'nav-login-createaccount' || !$is_signup ), - 'class' => $wgSecureLogin ? 'link-https' : '' ); $createaccount_url = array( 'text' => $this->msg( 'createaccount' )->text(), - 'href' => self::makeSpecialUrl( 'Userlogin', "$returnto&type=signup", $proto ), + 'href' => self::makeSpecialUrl( 'Userlogin', "$returnto&type=signup" ), 'active' => $title->isSpecial( 'Userlogin' ) && $is_signup, - 'class' => $wgSecureLogin ? 'link-https' : '' ); - if( $this->showIPinHeader() ) { + if ( $this->showIPinHeader() ) { $href = &$this->userpageUrlDetails['href']; $personal_urls['anonuserpage'] = array( 'text' => $this->username, @@ -668,22 +735,28 @@ class SkinTemplate extends Skin { } /** - * TODO document - * @param $title Title - * @param $message String message key - * @param $selected Bool - * @param $query String - * @param $checkEdit Bool + * Builds an array with tab definition + * + * @param Title $title page where the tab links to + * @param string|array $message message key or an array of message keys (will fall back) + * @param boolean $selected display the tab as selected + * @param string $query query string attached to tab URL + * @param boolean $checkEdit check if $title exists and mark with .new if one doesn't + * * @return array */ function tabAction( $title, $message, $selected, $query = '', $checkEdit = false ) { $classes = array(); - if( $selected ) { + if ( $selected ) { $classes[] = 'selected'; } - if( $checkEdit && !$title->isKnown() ) { + if ( $checkEdit && !$title->isKnown() ) { $classes[] = 'new'; - $query = 'action=edit&redlink=1'; + if ( $query !== '' ) { + $query = 'action=edit&redlink=1&' . $query; + } else { + $query = 'action=edit&redlink=1'; + } } // wfMessageFallback will nicely accept $message as an array of fallbacks @@ -702,7 +775,7 @@ class SkinTemplate extends Skin { } $result = array(); - if( !wfRunHooks( 'SkinTemplateTabAction', array( &$this, + if ( !wfRunHooks( 'SkinTemplateTabAction', array( &$this, $title, $message, $selected, $checkEdit, &$classes, &$query, &$text, &$result ) ) ) { return $result; @@ -711,13 +784,13 @@ class SkinTemplate extends Skin { return array( 'class' => implode( ' ', $classes ), 'text' => $text, - 'href' => $title->getLocalUrl( $query ), + 'href' => $title->getLocalURL( $query ), 'primary' => true ); } function makeTalkUrlDetails( $name, $urlaction = '' ) { $title = Title::newFromText( $name ); - if( !is_object( $title ) ) { + if ( !is_object( $title ) ) { throw new MWException( __METHOD__ . " given invalid pagename $name" ); } $title = $title->getTalkPage(); @@ -730,7 +803,7 @@ class SkinTemplate extends Skin { function makeArticleUrlDetails( $name, $urlaction = '' ) { $title = Title::newFromText( $name ); - $title= $title->getSubjectPage(); + $title = $title->getSubjectPage(); self::checkTitle( $title, $name ); return array( 'href' => $title->getLocalURL( $urlaction ), @@ -748,7 +821,7 @@ class SkinTemplate extends Skin { * variants: Used to list the language variants for the page * * Each section's value is a key/value array of links for that section. - * The links themseves have these common keys: + * The links themselves have these common keys: * - class: The css classes to apply to the tab * - text: The text to display on the tab * - href: The href for the tab to point to @@ -800,7 +873,7 @@ class SkinTemplate extends Skin { wfRunHooks( 'SkinTemplatePreventOtherActiveTabs', array( &$this, &$preventActiveTabs ) ); // Checks if page is some kind of content - if( $title->canExist() ) { + if ( $title->canExist() ) { // Gets page objects for the related namespaces $subjectPage = $title->getSubjectPage(); $talkPage = $title->getTalkPage(); @@ -935,7 +1008,7 @@ class SkinTemplate extends Skin { } } - if ( $title->getNamespace() !== NS_MEDIAWIKI && $title->quickUserCan( 'protect', $user ) ) { + if ( $title->getNamespace() !== NS_MEDIAWIKI && $title->quickUserCan( 'protect', $user ) && $title->getRestrictionTypes() ) { $mode = $title->isProtected() ? 'unprotect' : 'protect'; $content_navigation['actions'][$mode] = array( 'class' => ( $onPage && $action == $mode ) ? 'selected' : false, @@ -947,7 +1020,7 @@ class SkinTemplate extends Skin { wfProfileOut( __METHOD__ . '-live' ); // Checks if the user is logged in - if ( $this->loggedin ) { + if ( $this->loggedin && $user->isAllowedAll( 'viewmywatchlist', 'editmywatchlist' ) ) { /** * The following actions use messages which, if made particular to * the any specific skins, would break the Ajax code which makes this @@ -980,22 +1053,23 @@ class SkinTemplate extends Skin { // Gets preferred variant (note that user preference is // only possible for wiki content language variant) $preferred = $pageLang->getPreferredVariant(); + if ( Action::getActionName( $this ) === 'view' ) { + $params = $request->getQueryValues(); + unset( $params['title'] ); + } else { + $params = array(); + } // Loops over each variant - foreach( $variants as $code ) { + foreach ( $variants as $code ) { // Gets variant name from language code $varname = $pageLang->getVariantname( $code ); - // Checks if the variant is marked as disabled - if( $varname == 'disable' ) { - // Skips this variant - continue; - } // Appends variant link $content_navigation['variants'][] = array( 'class' => ( $code == $preferred ) ? 'selected' : false, 'text' => $varname, - 'href' => $title->getLocalURL( array( 'variant' => $code ) ), - 'lang' => $code, - 'hreflang' => $code + 'href' => $title->getLocalURL( array( 'variant' => $code ) + $params ), + 'lang' => wfBCP47( $code ), + 'hreflang' => wfBCP47( $code ), ); } } @@ -1014,7 +1088,7 @@ class SkinTemplate extends Skin { } // Equiv to SkinTemplateContentActions - wfRunHooks( 'SkinTemplateNavigation::Universal', array( &$this, &$content_navigation ) ); + wfRunHooks( 'SkinTemplateNavigation::Universal', array( &$this, &$content_navigation ) ); // Setup xml ids and tooltip info foreach ( $content_navigation as $section => &$links ) { @@ -1036,8 +1110,8 @@ class SkinTemplate extends Skin { # We don't want to give the watch tab an accesskey if the # page is being edited, because that conflicts with the # accesskey on the watch checkbox. We also don't want to - # give the edit tab an accesskey, because that's fairly su- - # perfluous and conflicts with an accesskey (Ctrl-E) often + # give the edit tab an accesskey, because that's fairly + # superfluous and conflicts with an accesskey (Ctrl-E) often # used for editing in Safari. if ( in_array( $action, array( 'edit', 'submit' ) ) ) { if ( isset( $content_navigation['views']['edit'] ) ) { @@ -1119,9 +1193,9 @@ class SkinTemplate extends Skin { $nav_urls = array(); $nav_urls['mainpage'] = array( 'href' => self::makeMainPageUrl() ); - if( $wgUploadNavigationUrl ) { + if ( $wgUploadNavigationUrl ) { $nav_urls['upload'] = array( 'href' => $wgUploadNavigationUrl ); - } elseif( UploadBase::isEnabled() && UploadBase::isAllowed( $this->getUser() ) === true ) { + } elseif ( UploadBase::isEnabled() && UploadBase::isAllowed( $this->getUser() ) === true ) { $nav_urls['upload'] = array( 'href' => self::makeSpecialUrl( 'Upload' ) ); } else { $nav_urls['upload'] = false; @@ -1130,24 +1204,26 @@ class SkinTemplate extends Skin { $nav_urls['print'] = false; $nav_urls['permalink'] = false; + $nav_urls['info'] = false; $nav_urls['whatlinkshere'] = false; $nav_urls['recentchangeslinked'] = false; $nav_urls['contributions'] = false; $nav_urls['log'] = false; $nav_urls['blockip'] = false; $nav_urls['emailuser'] = false; + $nav_urls['userrights'] = false; // A print stylesheet is attached to all pages, but nobody ever // figures that out. :) Add a link... - if ( $out->isArticle() ) { - if ( !$out->isPrintable() ) { - $nav_urls['print'] = array( - 'text' => $this->msg( 'printableversion' )->text(), - 'href' => $this->getTitle()->getLocalURL( - $request->appendQueryValue( 'printable', 'yes', true ) ) - ); - } + if ( !$out->isPrintable() && ( $out->isArticle() || $this->getTitle()->isSpecialPage() ) ) { + $nav_urls['print'] = array( + 'text' => $this->msg( 'printableversion' )->text(), + 'href' => $this->getTitle()->getLocalURL( + $request->appendQueryValue( 'printable', 'yes', true ) ) + ); + } + if ( $out->isArticle() ) { // Also add a "permalink" while we're at it $revid = $this->getRevisionId(); if ( $revid ) { @@ -1164,11 +1240,17 @@ class SkinTemplate extends Skin { if ( $out->isArticleRelated() ) { $nav_urls['whatlinkshere'] = array( - 'href' => SpecialPage::getTitleFor( 'Whatlinkshere', $this->thispage )->getLocalUrl() + 'href' => SpecialPage::getTitleFor( 'Whatlinkshere', $this->thispage )->getLocalURL() + ); + + $nav_urls['info'] = array( + 'text' => $this->msg( 'pageinfo-toolboxlink' )->text(), + 'href' => $this->getTitle()->getLocalURL( "action=info" ) ); + if ( $this->getTitle()->getArticleID() ) { $nav_urls['recentchangeslinked'] = array( - 'href' => SpecialPage::getTitleFor( 'Recentchangeslinked', $this->thispage )->getLocalUrl() + 'href' => SpecialPage::getTitleFor( 'Recentchangeslinked', $this->thispage )->getLocalURL() ); } } @@ -1178,6 +1260,7 @@ class SkinTemplate extends Skin { $rootUser = $user->getName(); $nav_urls['contributions'] = array( + 'text' => $this->msg( 'contributions', $rootUser )->text(), 'href' => self::makeSpecialUrlSubpage( 'Contributions', $rootUser ) ); @@ -1196,6 +1279,16 @@ class SkinTemplate extends Skin { 'href' => self::makeSpecialUrlSubpage( 'Emailuser', $rootUser ) ); } + + if ( !$user->isAnon() ) { + $sur = new UserrightsPage; + $sur->setContext( $this->getContext() ); + if ( $sur->userCanExecute( $this->getUser() ) ) { + $nav_urls['userrights'] = array( + 'href' => self::makeSpecialUrlSubpage( 'Userrights', $rootUser ) + ); + } + } } wfProfileOut( __METHOD__ ); @@ -1210,10 +1303,6 @@ class SkinTemplate extends Skin { function getNameSpaceKey() { return $this->getTitle()->getNamespaceKey(); } - - public function commonPrintStylesheet() { - return false; - } } /** @@ -1225,7 +1314,7 @@ abstract class QuickTemplate { /** * Constructor */ - public function QuickTemplate() { + function __construct() { $this->data = array(); $this->translator = new MediaWiki_I18N(); } @@ -1240,6 +1329,21 @@ abstract class QuickTemplate { } /** + * Gets the template data requested + * @since 1.22 + * @param string $name Key for the data + * @param mixed $default Optional default (or null) + * @return mixed The value of the data requested or the deafult + */ + public function get( $name, $default = null ) { + if ( isset( $this->data[$name] ) ) { + return $this->data[$name]; + } else { + return $default; + } + } + + /** * @param $name * @param $value */ @@ -1269,8 +1373,10 @@ abstract class QuickTemplate { /** * @private + * @deprecated since 1.21; use Xml::encodeJsVar() or Xml::encodeJsCall() instead */ function jstext( $str ) { + wfDeprecated( __METHOD__, '1.21' ); echo Xml::escapeJsString( $this->data[$str] ); } @@ -1344,7 +1450,7 @@ abstract class BaseTemplate extends QuickTemplate { /** * Get a Message object with its context set * - * @param $name string message name + * @param string $name message name * @return Message */ public function getMsg( $name ) { @@ -1366,7 +1472,7 @@ abstract class BaseTemplate extends QuickTemplate { /** * Create an array of common toolbox items from the data in the quicktemplate * stored by SkinTemplate. - * The resulting array is built acording to a format intended to be passed + * The resulting array is built according to a format intended to be passed * through makeListItem to generate the html. * @return array */ @@ -1394,7 +1500,7 @@ abstract class BaseTemplate extends QuickTemplate { $toolbox['feeds']['links'][$key]['class'] = 'feedlink'; } } - foreach ( array( 'contributions', 'log', 'blockip', 'emailuser', 'upload', 'specialpages' ) as $special ) { + foreach ( array( 'contributions', 'log', 'blockip', 'emailuser', 'userrights', 'upload', 'specialpages' ) as $special ) { if ( isset( $this->data['nav_urls'][$special] ) && $this->data['nav_urls'][$special] ) { $toolbox[$special] = $this->data['nav_urls'][$special]; $toolbox[$special]['id'] = "t-$special"; @@ -1417,6 +1523,11 @@ abstract class BaseTemplate extends QuickTemplate { $toolbox['permalink']['id'] = 't-permalink'; } } + if ( isset( $this->data['nav_urls']['info'] ) && $this->data['nav_urls']['info'] ) { + $toolbox['info'] = $this->data['nav_urls']['info']; + $toolbox['info']['id'] = 't-info'; + } + wfRunHooks( 'BaseTemplateToolbox', array( &$this, &$toolbox ) ); wfProfileOut( __METHOD__ ); return $toolbox; @@ -1425,7 +1536,7 @@ abstract class BaseTemplate extends QuickTemplate { /** * Create an array of personal tools items from the data in the quicktemplate * stored by SkinTemplate. - * The resulting array is built acording to a format intended to be passed + * The resulting array is built according to a format intended to be passed * through makeListItem to generate the html. * This is in reality the same list as already stored in personal_urls * however it is reformatted so that you can just pass the individual items @@ -1434,7 +1545,7 @@ abstract class BaseTemplate extends QuickTemplate { */ function getPersonalTools() { $personal_tools = array(); - foreach ( $this->data['personal_urls'] as $key => $plink ) { + foreach ( $this->get( 'personal_urls' ) as $key => $plink ) { # The class on a personal_urls item is meant to go on the <a> instead # of the <li> so we have to use a single item "links" array instead # of using most of the personal_url's keys directly. @@ -1448,8 +1559,9 @@ abstract class BaseTemplate extends QuickTemplate { $ptool['active'] = $plink['active']; } foreach ( array( 'href', 'class', 'text' ) as $k ) { - if ( isset( $plink[$k] ) ) + if ( isset( $plink[$k] ) ) { $ptool['links'][0][$k] = $plink[$k]; + } } $personal_tools[$key] = $ptool; } @@ -1488,39 +1600,39 @@ abstract class BaseTemplate extends QuickTemplate { case 'SEARCH': // Search is a special case, skins should custom implement this $boxes[$boxName] = array( - 'id' => 'p-search', - 'header' => $this->getMsg( 'search' )->text(), + 'id' => 'p-search', + 'header' => $this->getMsg( 'search' )->text(), 'generated' => false, - 'content' => true, + 'content' => true, ); break; case 'TOOLBOX': $msgObj = $this->getMsg( 'toolbox' ); $boxes[$boxName] = array( - 'id' => 'p-tb', - 'header' => $msgObj->exists() ? $msgObj->text() : 'toolbox', + 'id' => 'p-tb', + 'header' => $msgObj->exists() ? $msgObj->text() : 'toolbox', 'generated' => false, - 'content' => $this->getToolbox(), + 'content' => $this->getToolbox(), ); break; case 'LANGUAGES': if ( $this->data['language_urls'] ) { $msgObj = $this->getMsg( 'otherlanguages' ); $boxes[$boxName] = array( - 'id' => 'p-lang', - 'header' => $msgObj->exists() ? $msgObj->text() : 'otherlanguages', + 'id' => 'p-lang', + 'header' => $msgObj->exists() ? $msgObj->text() : 'otherlanguages', 'generated' => false, - 'content' => $this->data['language_urls'], + 'content' => $this->data['language_urls'], ); } break; default: $msgObj = $this->getMsg( $boxName ); $boxes[$boxName] = array( - 'id' => "p-$boxName", - 'header' => $msgObj->exists() ? $msgObj->text() : $boxName, + 'id' => "p-$boxName", + 'header' => $msgObj->exists() ? $msgObj->text() : $boxName, 'generated' => true, - 'content' => $content, + 'content' => $content, ); break; } @@ -1560,10 +1672,10 @@ abstract class BaseTemplate extends QuickTemplate { } else { if ( $hookContents ) { $boxes['TOOLBOXEND'] = array( - 'id' => 'p-toolboxend', - 'header' => $boxes['TOOLBOX']['header'], + 'id' => 'p-toolboxend', + 'header' => $boxes['TOOLBOX']['header'], 'generated' => false, - 'content' => "<ul>{$hookContents}</ul>", + 'content' => "<ul>{$hookContents}</ul>", ); // HACK: Make sure that TOOLBOXEND is sorted next to TOOLBOX $boxes2 = array(); @@ -1588,9 +1700,9 @@ abstract class BaseTemplate extends QuickTemplate { * Makes a link, usually used by makeListItem to generate a link for an item * in a list used in navigation lists, portlets, portals, sidebars, etc... * - * @param $key string usually a key from the list you are generating this + * @param string $key usually a key from the list you are generating this * link from. - * @param $item array contains some of a specific set of keys. + * @param array $item contains some of a specific set of keys. * * The text of the link will be generated either from the contents of the * "text" key in the $item array, if a "msg" key is present a message by @@ -1605,9 +1717,13 @@ abstract class BaseTemplate extends QuickTemplate { * on the link) is present it will be used to generate a tooltip and * accesskey for the link. * + * The keys "context" and "primary" are ignored; these keys are used + * internally by skins and are not supposed to be included in the HTML + * output. + * * If you don't want an accesskey, set $item['tooltiponly'] = true; * - * @param $options array can be used to affect the output of a link. + * @param array $options can be used to affect the output of a link. * Possible options are: * - 'text-wrapper' key to specify a list of elements to wrap the text of * a link in. This should be an array of arrays containing a 'tag' and @@ -1645,7 +1761,7 @@ abstract class BaseTemplate extends QuickTemplate { if ( isset( $item['href'] ) || isset( $options['link-fallback'] ) ) { $attrs = $item; - foreach ( array( 'single-id', 'text', 'msg', 'tooltiponly' ) as $k ) { + foreach ( array( 'single-id', 'text', 'msg', 'tooltiponly', 'context', 'primary' ) as $k ) { unset( $attrs[$k] ); } @@ -1720,7 +1836,7 @@ abstract class BaseTemplate extends QuickTemplate { foreach ( array( 'id', 'class', 'active', 'tag' ) as $k ) { unset( $link[$k] ); } - if ( isset( $item['id'] ) ) { + if ( isset( $item['id'] ) && !isset( $item['single-id'] ) ) { // The id goes on the <li> not on the <a> for single links // but makeSidebarLink still needs to know what id to use when // generating tooltips and accesskeys. @@ -1749,14 +1865,15 @@ abstract class BaseTemplate extends QuickTemplate { $realAttrs = array( 'type' => 'search', 'name' => 'search', - 'value' => isset( $this->data['search'] ) ? $this->data['search'] : '', + 'placeholder' => wfMessage( 'searchsuggest-search' )->text(), + 'value' => $this->get( 'search', '' ), ); $realAttrs = array_merge( $realAttrs, Linker::tooltipAndAccesskeyAttribs( 'search' ), $attrs ); return Html::element( 'input', $realAttrs ); } function makeSearchButton( $mode, $attrs = array() ) { - switch( $mode ) { + switch ( $mode ) { case 'go': case 'fulltext': $realAttrs = array( @@ -1783,11 +1900,15 @@ abstract class BaseTemplate extends QuickTemplate { ); unset( $buttonAttrs['src'] ); unset( $buttonAttrs['alt'] ); + unset( $buttonAttrs['width'] ); + unset( $buttonAttrs['height'] ); $imgAttrs = array( 'src' => $attrs['src'], 'alt' => isset( $attrs['alt'] ) ? $attrs['alt'] : $this->translator->translate( 'searchbutton' ), + 'width' => isset( $attrs['width'] ) ? $attrs['width'] : null, + 'height' => isset( $attrs['height'] ) ? $attrs['height'] : null, ); return Html::rawElement( 'button', $buttonAttrs, Html::element( 'img', $imgAttrs ) ); default: @@ -1804,14 +1925,14 @@ abstract class BaseTemplate extends QuickTemplate { * @return array|mixed */ function getFooterLinks( $option = null ) { - $footerlinks = $this->data['footerlinks']; + $footerlinks = $this->get( 'footerlinks' ); // Reduce footer links down to only those which are being used $validFooterLinks = array(); - foreach( $footerlinks as $category => $links ) { + foreach ( $footerlinks as $category => $links ) { $validFooterLinks[$category] = array(); - foreach( $links as $link ) { - if( isset( $this->data[$link] ) && $this->data[$link] ) { + foreach ( $links as $link ) { + if ( isset( $this->data[$link] ) && $this->data[$link] ) { $validFooterLinks[$category][] = $link; } } @@ -1844,7 +1965,7 @@ abstract class BaseTemplate extends QuickTemplate { */ function getFooterIcons( $option = null ) { // Generate additional footer icons - $footericons = $this->data['footericons']; + $footericons = $this->get( 'footericons' ); if ( $option == 'icononly' ) { // Unset any icons which don't have an image @@ -1877,9 +1998,10 @@ abstract class BaseTemplate extends QuickTemplate { * body and html tags. */ function printTrail() { ?> +<?php echo MWDebug::getDebugHTML( $this->getSkin()->getContext() ); ?> <?php $this->html( 'bottomscripts' ); /* JS call to runBodyOnloadHook */ ?> <?php $this->html( 'reporttime' ) ?> -<?php echo MWDebug::getDebugHTML( $this->getSkin()->getContext() ); +<?php } } |