protected function openShowImage() { global $wgImageLimits, $wgEnableUploads, $wgSend404Code; $this->loadFile(); $out = $this->getContext()->getOutput(); $user = $this->getContext()->getUser(); $lang = $this->getContext()->getLanguage(); $dirmark = $lang->getDirMarkEntity(); $request = $this->getContext()->getRequest(); $max = $this->getImageLimitsFromOption($user, 'imagesize'); $maxWidth = $max[0]; $maxHeight = $max[1]; if ($this->displayImg->exists()) { # image $page = $request->getIntOrNull('page'); if (is_null($page)) { $params = array(); $page = 1; } else { $params = array('page' => $page); } $renderLang = $request->getVal('lang'); if (!is_null($renderLang)) { $handler = $this->displayImg->getHandler(); if ($handler && $handler->validateParam('lang', $renderLang)) { $params['lang'] = $renderLang; } else { $renderLang = null; } } $width_orig = $this->displayImg->getWidth($page); $width = $width_orig; $height_orig = $this->displayImg->getHeight($page); $height = $height_orig; $filename = wfEscapeWikiText($this->displayImg->getName()); $linktext = $filename; wfRunHooks('ImageOpenShowImageInlineBefore', array(&$this, &$out)); if ($this->displayImg->allowInlineDisplay()) { # image # "Download high res version" link below the image # $msgsize = wfMessage( 'file-info-size', $width_orig, $height_orig, Linker::formatSize( $this->displayImg->getSize() ), $mime )->escaped(); # We'll show a thumbnail of this image if ($width > $maxWidth || $height > $maxHeight) { # Calculate the thumbnail size. # First case, the limiting factor is the width, not the height. if ($width / $height >= $maxWidth / $maxHeight) { // FIXME: Possible division by 0. bug 36911 $height = round($height * $maxWidth / $width); // FIXME: Possible division by 0. bug 36911 $width = $maxWidth; # Note that $height <= $maxHeight now. } else { $newwidth = floor($width * $maxHeight / $height); // FIXME: Possible division by 0. bug 36911 $height = round($height * $newwidth / $width); // FIXME: Possible division by 0. bug 36911 $width = $newwidth; # Note that $height <= $maxHeight now, but might not be identical # because of rounding. } $linktext = wfMessage('show-big-image')->escaped(); if ($this->displayImg->getRepo()->canTransformVia404()) { $thumbSizes = $wgImageLimits; // Also include the full sized resolution in the list, so // that users know they can get it. This will link to the // original file asset if mustRender() === false. In the case // that we mustRender, some users have indicated that they would // find it useful to have the full size image in the rendered // image format. $thumbSizes[] = array($width_orig, $height_orig); } else { # Creating thumb links triggers thumbnail generation. # Just generate the thumb for the current users prefs. $thumbSizes = array($this->getImageLimitsFromOption($user, 'thumbsize')); if (!$this->displayImg->mustRender()) { // We can safely include a link to the "full-size" preview, // without actually rendering. $thumbSizes[] = array($width_orig, $height_orig); } } # Generate thumbnails or thumbnail links as needed... $otherSizes = array(); foreach ($thumbSizes as $size) { // We include a thumbnail size in the list, if it is // less than or equal to the original size of the image // asset ($width_orig/$height_orig). We also exclude // the current thumbnail's size ($width/$height) // since that is added to the message separately, so // it can be denoted as the current size being shown. if ($size[0] <= $width_orig && $size[1] <= $height_orig && $size[0] != $width && $size[1] != $height) { $sizeLink = $this->makeSizeLink($params, $size[0], $size[1]); if ($sizeLink) { $otherSizes[] = $sizeLink; } } } $otherSizes = array_unique($otherSizes); $msgsmall = ''; $sizeLinkBigImagePreview = $this->makeSizeLink($params, $width, $height); if ($sizeLinkBigImagePreview) { $msgsmall .= wfMessage('show-big-image-preview')->rawParams($sizeLinkBigImagePreview)->parse(); } if (count($otherSizes)) { $msgsmall .= ' ' . Html::rawElement('span', array('class' => 'mw-filepage-other-resolutions'), wfMessage('show-big-image-other')->rawParams($lang->pipeList($otherSizes))->params(count($otherSizes))->parse()); } } elseif ($width == 0 && $height == 0) { # Some sort of audio file that doesn't have dimensions # Don't output a no hi res message for such a file $msgsmall = ''; } elseif ($this->displayImg->isVectorized()) { # For vectorized images, full size is just the frame size $msgsmall = ''; } else { # Image is small enough to show full size on image page $msgsmall = wfMessage('file-nohires')->parse(); } $params['width'] = $width; $params['height'] = $height; $thumbnail = $this->displayImg->transform($params); Linker::processResponsiveImages($this->displayImg, $thumbnail, $params); $anchorclose = Html::rawElement('div', array('class' => 'mw-filepage-resolutioninfo'), $msgsmall); $isMulti = $this->displayImg->isMultipage() && $this->displayImg->pageCount() > 1; if ($isMulti) { $out->addModules('mediawiki.page.image.pagination'); $out->addHTML('<table class="multipageimage"><tr><td>'); } if ($thumbnail) { $options = array('alt' => $this->displayImg->getTitle()->getPrefixedText(), 'file-link' => true); $out->addHTML('<div class="fullImageLink" id="file">' . $thumbnail->toHtml($options) . $anchorclose . "</div>\n"); } if ($isMulti) { $count = $this->displayImg->pageCount(); if ($page > 1) { $label = $out->parse(wfMessage('imgmultipageprev')->text(), false); // on the client side, this link is generated in ajaxifyPageNavigation() // in the mediawiki.page.image.pagination module $link = Linker::linkKnown($this->getTitle(), $label, array(), array('page' => $page - 1)); $thumb1 = Linker::makeThumbLinkObj($this->getTitle(), $this->displayImg, $link, $label, 'none', array('page' => $page - 1)); } else { $thumb1 = ''; } if ($page < $count) { $label = wfMessage('imgmultipagenext')->text(); $link = Linker::linkKnown($this->getTitle(), $label, array(), array('page' => $page + 1)); $thumb2 = Linker::makeThumbLinkObj($this->getTitle(), $this->displayImg, $link, $label, 'none', array('page' => $page + 1)); } else { $thumb2 = ''; } global $wgScript; $formParams = array('name' => 'pageselector', 'action' => $wgScript); $options = array(); for ($i = 1; $i <= $count; $i++) { $options[] = Xml::option($lang->formatNum($i), $i, $i == $page); } $select = Xml::tags('select', array('id' => 'pageselector', 'name' => 'page'), implode("\n", $options)); $out->addHTML('</td><td><div class="multipageimagenavbox">' . Xml::openElement('form', $formParams) . Html::hidden('title', $this->getTitle()->getPrefixedDBkey()) . wfMessage('imgmultigoto')->rawParams($select)->parse() . Xml::submitButton(wfMessage('imgmultigo')->text()) . Xml::closeElement('form') . "<hr />{$thumb1}\n{$thumb2}<br style=\"clear: both\" /></div></td></tr></table>"); } } elseif ($this->displayImg->isSafeFile()) { # if direct link is allowed but it's not a renderable image, show an icon. $icon = $this->displayImg->iconThumb(); $out->addHTML('<div class="fullImageLink" id="file">' . $icon->toHtml(array('file-link' => true)) . "</div>\n"); } $longDesc = wfMessage('parentheses', $this->displayImg->getLongDesc())->text(); $medialink = "[[Media:{$filename}|{$linktext}]]"; if (!$this->displayImg->isSafeFile()) { $warning = wfMessage('mediawarning')->plain(); // dirmark is needed here to separate the file name, which // most likely ends in Latin characters, from the description, // which may begin with the file type. In RTL environment // this will get messy. // The dirmark, however, must not be immediately adjacent // to the filename, because it can get copied with it. // See bug 25277. $out->addWikiText(<<<EOT <div class="fullMedia"><span class="dangerousLink">{$medialink}</span> {$dirmark}<span class="fileInfo">{$longDesc}</span></div> <div class="mediaWarning">{$warning}</div> EOT ); } else { $out->addWikiText(<<<EOT <div class="fullMedia">{$medialink} {$dirmark}<span class="fileInfo">{$longDesc}</span> </div> EOT ); } $renderLangOptions = $this->displayImg->getAvailableLanguages(); if (count($renderLangOptions) >= 1) { $currentLanguage = $renderLang; $defaultLang = $this->displayImg->getDefaultRenderLanguage(); if (is_null($currentLanguage)) { $currentLanguage = $defaultLang; } $out->addHtml($this->doRenderLangOpt($renderLangOptions, $currentLanguage, $defaultLang)); } // Add cannot animate thumbnail warning if (!$this->displayImg->canAnimateThumbIfAppropriate()) { // Include the extension so wiki admins can // customize it on a per file-type basis // (aka say things like use format X instead). // additionally have a specific message for // file-no-thumb-animation-gif $ext = $this->displayImg->getExtension(); $noAnimMesg = wfMessageFallback('file-no-thumb-animation-' . $ext, 'file-no-thumb-animation')->plain(); $out->addWikiText(<<<EOT <div class="mw-noanimatethumb">{$noAnimMesg}</div> EOT ); } if (!$this->displayImg->isLocal()) { $this->printSharedImageText(); } } else { # Image does not exist if (!$this->getID()) { # No article exists either # Show deletion log to be consistent with normal articles LogEventsList::showLogExtract($out, array('delete', 'move'), $this->getTitle()->getPrefixedText(), '', array('lim' => 10, 'conds' => array("log_action != 'revision'"), 'showIfEmpty' => false, 'msgKey' => array('moveddeleted-notice'))); } if ($wgEnableUploads && $user->isAllowed('upload')) { // Only show an upload link if the user can upload $uploadTitle = SpecialPage::getTitleFor('Upload'); $nofile = array('filepage-nofile-link', $uploadTitle->getFullURL(array('wpDestFile' => $this->mPage->getFile()->getName()))); } else { $nofile = 'filepage-nofile'; } // Note, if there is an image description page, but // no image, then this setRobotPolicy is overridden // by Article::View(). $out->setRobotPolicy('noindex,nofollow'); $out->wrapWikiMsg("<div id='mw-imagepage-nofile' class='plainlinks'>\n\$1\n</div>", $nofile); if (!$this->getID() && $wgSend404Code) { // If there is no image, no shared image, and no description page, // output a 404, to be consistent with articles. $request->response()->header('HTTP/1.1 404 Not Found'); } } $out->setFileVersion($this->displayImg); }
/** * Get the human-readable name of the repo * * @return string */ public function getDisplayName() { // We don't name our own repo, return nothing if ($this->isLocal()) { return null; } // 'shared-repo-name-wikimediacommons' is used when $wgUseInstantCommons = true return wfMessageFallback('shared-repo-name-' . $this->name, 'shared-repo')->text(); }
/** * Get the human-readable name of the repo * * @return string */ public function getDisplayName() { global $wgSitename; if ($this->isLocal()) { return $wgSitename; } // 'shared-repo-name-wikimediacommons' is used when $wgUseInstantCommons = true return wfMessageFallback('shared-repo-name-' . $this->name, 'shared-repo')->text(); }
/** * a structured array of links usually used for the tabs in a skin * * There are 4 standard sections * namespaces: Used for namespace tabs like special, page, and talk namespaces * views: Used for primary page views like read, edit, history * actions: Used for most extra page actions like deletion, protection, etc... * 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 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 * - rel: An optional rel= for the tab's link * - redundant: If true the tab will be dropped in skins using content_actions * this is useful for tabs like "Read" which only have meaning in skins that * take special meaning from the grouped structure of content_navigation * * Views also have an extra key which can be used: * - primary: If this is not true skins like vector may try to hide the tab * when the user has limited space in their browser window * * content_navigation using code also expects these ids to be present on the * links, however these are usually automatically generated by SkinTemplate * itself and are not necessary when using a hook. The only things these may * matter to are people modifying content_navigation after it's initial creation: * - id: A "preferred" id, most skins are best off outputting this preferred * id for best compatibility. * - tooltiponly: This is set to true for some tabs in cases where the system * believes that the accesskey should not be added to the tab. * * @return array */ protected function buildContentNavigationUrls() { global $wgDisableLangConversion; // Display tabs for the relevant title rather than always the title itself $title = $this->getRelevantTitle(); $onPage = $title->equals($this->getTitle()); $out = $this->getOutput(); $request = $this->getRequest(); $user = $this->getUser(); $content_navigation = array('namespaces' => array(), 'views' => array(), 'actions' => array(), 'variants' => array()); // parameters $action = $request->getVal('action', 'view'); $userCanRead = $title->quickUserCan('read', $user); $preventActiveTabs = false; Hooks::run('SkinTemplatePreventOtherActiveTabs', array(&$this, &$preventActiveTabs)); // Checks if page is some kind of content if ($title->canExist()) { // Gets page objects for the related namespaces $subjectPage = $title->getSubjectPage(); $talkPage = $title->getTalkPage(); // Determines if this is a talk page $isTalk = $title->isTalkPage(); // Generates XML IDs from namespace names $subjectId = $title->getNamespaceKey(''); if ($subjectId == 'main') { $talkId = 'talk'; } else { $talkId = "{$subjectId}_talk"; } $skname = $this->skinname; // Adds namespace links $subjectMsg = array("nstab-{$subjectId}"); if ($subjectPage->isMainPage()) { array_unshift($subjectMsg, 'mainpage-nstab'); } $content_navigation['namespaces'][$subjectId] = $this->tabAction($subjectPage, $subjectMsg, !$isTalk && !$preventActiveTabs, '', $userCanRead); $content_navigation['namespaces'][$subjectId]['context'] = 'subject'; $content_navigation['namespaces'][$talkId] = $this->tabAction($talkPage, array("nstab-{$talkId}", 'talk'), $isTalk && !$preventActiveTabs, '', $userCanRead); $content_navigation['namespaces'][$talkId]['context'] = 'talk'; if ($userCanRead) { $isForeignFile = $title->inNamespace(NS_FILE) && $this->canUseWikiPage() && $this->getWikiPage() instanceof WikiFilePage && !$this->getWikiPage()->isLocal(); // Adds view view link if ($title->exists() || $isForeignFile) { $content_navigation['views']['view'] = $this->tabAction($isTalk ? $talkPage : $subjectPage, array("{$skname}-view-view", 'view'), $onPage && ($action == 'view' || $action == 'purge'), '', true); // signal to hide this from simple content_actions $content_navigation['views']['view']['redundant'] = true; } // If it is a non-local file, show a link to the file in its own repository if ($isForeignFile) { $file = $this->getWikiPage()->getFile(); $content_navigation['views']['view-foreign'] = array('class' => '', 'text' => wfMessageFallback("{$skname}-view-foreign", 'view-foreign')->setContext($this->getContext())->params($file->getRepo()->getDisplayName())->text(), 'href' => $file->getDescriptionUrl(), 'primary' => false); } // Checks if user can edit the current page if it exists or create it otherwise if ($title->quickUserCan('edit', $user) && ($title->exists() || $title->quickUserCan('create', $user))) { // Builds CSS class for talk page links $isTalkClass = $isTalk ? ' istalk' : ''; // Whether the user is editing the page $isEditing = $onPage && ($action == 'edit' || $action == 'submit'); // Whether to show the "Add a new section" tab // Checks if this is a current rev of talk page and is not forced to be hidden $showNewSection = !$out->forceHideNewSectionLink() && ($isTalk && $this->isRevisionCurrent() || $out->showNewSectionLink()); $section = $request->getVal('section'); if ($title->exists() || $title->getNamespace() == NS_MEDIAWIKI && $title->getDefaultMessageText() !== false) { $msgKey = $isForeignFile ? 'edit-local' : 'edit'; } else { $msgKey = $isForeignFile ? 'create-local' : 'create'; } $content_navigation['views']['edit'] = array('class' => ($isEditing && ($section !== 'new' || !$showNewSection) ? 'selected' : '') . $isTalkClass, 'text' => wfMessageFallback("{$skname}-view-{$msgKey}", $msgKey)->setContext($this->getContext())->text(), 'href' => $title->getLocalURL($this->editUrlOptions()), 'primary' => !$isForeignFile); // section link if ($showNewSection) { // Adds new section link //$content_navigation['actions']['addsection'] $content_navigation['views']['addsection'] = array('class' => $isEditing && $section == 'new' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-addsection", 'addsection')->setContext($this->getContext())->text(), 'href' => $title->getLocalURL('action=edit§ion=new')); } // Checks if the page has some kind of viewable content } elseif ($title->hasSourceText()) { // Adds view source view link $content_navigation['views']['viewsource'] = array('class' => $onPage && $action == 'edit' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-viewsource", 'viewsource')->setContext($this->getContext())->text(), 'href' => $title->getLocalURL($this->editUrlOptions()), 'primary' => true); } // Checks if the page exists if ($title->exists()) { // Adds history view link $content_navigation['views']['history'] = array('class' => $onPage && $action == 'history' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-view-history", 'history_short')->setContext($this->getContext())->text(), 'href' => $title->getLocalURL('action=history')); if ($title->quickUserCan('delete', $user)) { $content_navigation['actions']['delete'] = array('class' => $onPage && $action == 'delete' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-delete", 'delete')->setContext($this->getContext())->text(), 'href' => $title->getLocalURL('action=delete')); } if ($title->quickUserCan('move', $user)) { $moveTitle = SpecialPage::getTitleFor('Movepage', $title->getPrefixedDBkey()); $content_navigation['actions']['move'] = array('class' => $this->getTitle()->isSpecial('Movepage') ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-move", 'move')->setContext($this->getContext())->text(), 'href' => $moveTitle->getLocalURL()); } } else { // article doesn't exist or is deleted if ($user->isAllowed('deletedhistory')) { $n = $title->isDeleted(); if ($n) { $undelTitle = SpecialPage::getTitleFor('Undelete', $title->getPrefixedDBkey()); // If the user can't undelete but can view deleted // history show them a "View .. deleted" tab instead. $msgKey = $user->isAllowed('undelete') ? 'undelete' : 'viewdeleted'; $content_navigation['actions']['undelete'] = array('class' => $this->getTitle()->isSpecial('Undelete') ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-{$msgKey}", "{$msgKey}_short")->setContext($this->getContext())->numParams($n)->text(), 'href' => $undelTitle->getLocalURL()); } } } if ($title->quickUserCan('protect', $user) && $title->getRestrictionTypes() && MWNamespace::getRestrictionLevels($title->getNamespace(), $user) !== array('')) { $mode = $title->isProtected() ? 'unprotect' : 'protect'; $content_navigation['actions'][$mode] = array('class' => $onPage && $action == $mode ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-{$mode}", $mode)->setContext($this->getContext())->text(), 'href' => $title->getLocalURL("action={$mode}")); } // Checks if the user is logged in 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 * action happen entirely inline. OutputPage::getJSVars * defines a set of messages in a javascript object - and these * messages are assumed to be global for all skins. Without making * a change to that procedure these messages will have to remain as * the global versions. */ $mode = $user->isWatched($title) ? 'unwatch' : 'watch'; $token = WatchAction::getWatchToken($title, $user, $mode); $content_navigation['actions'][$mode] = array('class' => $onPage && ($action == 'watch' || $action == 'unwatch') ? 'selected' : false, 'text' => $this->msg($mode)->text(), 'href' => $title->getLocalURL(array('action' => $mode, 'token' => $token))); } } Hooks::run('SkinTemplateNavigation', array(&$this, &$content_navigation)); if ($userCanRead && !$wgDisableLangConversion) { $pageLang = $title->getPageLanguage(); // Gets list of language variants $variants = $pageLang->getVariants(); // Checks that language conversion is enabled and variants exist // And if it is not in the special namespace if (count($variants) > 1) { // 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) { // Gets variant name from language code $varname = $pageLang->getVariantname($code); // Appends variant link $content_navigation['variants'][] = array('class' => $code == $preferred ? 'selected' : false, 'text' => $varname, 'href' => $title->getLocalURL(array('variant' => $code) + $params), 'lang' => wfBCP47($code), 'hreflang' => wfBCP47($code)); } } } } else { // If it's not content, it's got to be a special page $content_navigation['namespaces']['special'] = array('class' => 'selected', 'text' => $this->msg('nstab-special')->text(), 'href' => $request->getRequestURL(), 'context' => 'subject'); Hooks::run('SkinTemplateNavigation::SpecialPage', array(&$this, &$content_navigation)); } // Equiv to SkinTemplateContentActions Hooks::run('SkinTemplateNavigation::Universal', array(&$this, &$content_navigation)); // Setup xml ids and tooltip info foreach ($content_navigation as $section => &$links) { foreach ($links as $key => &$link) { $xmlID = $key; if (isset($link['context']) && $link['context'] == 'subject') { $xmlID = 'ca-nstab-' . $xmlID; } elseif (isset($link['context']) && $link['context'] == 'talk') { $xmlID = 'ca-talk'; } elseif ($section == 'variants') { $xmlID = 'ca-varlang-' . $xmlID; } else { $xmlID = 'ca-' . $xmlID; } $link['id'] = $xmlID; } } # 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 # 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'])) { $content_navigation['views']['edit']['tooltiponly'] = true; } if (isset($content_navigation['actions']['watch'])) { $content_navigation['actions']['watch']['tooltiponly'] = true; } if (isset($content_navigation['actions']['unwatch'])) { $content_navigation['actions']['unwatch']['tooltiponly'] = true; } } return $content_navigation; }
/** * a structured array of links usually used for the tabs in a skin * * There are 4 standard sections * namespaces: Used for namespace tabs like special, page, and talk namespaces * views: Used for primary page views like read, edit, history * actions: Used for most extra page actions like deletion, protection, etc... * 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: * - 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 * - rel: An optional rel= for the tab's link * - redundant: If true the tab will be dropped in skins using content_actions * this is useful for tabs like "Read" which only have meaning in skins that * take special meaning from the grouped structure of content_navigation * * Views also have an extra key which can be used: * - primary: If this is not true skins like vector may try to hide the tab * when the user has limited space in their browser window * * content_navigation using code also expects these ids to be present on the * links, however these are usually automatically generated by SkinTemplate * itself and are not necessary when using a hook. The only things these may * matter to are people modifying content_navigation after it's initial creation: * - id: A "preferred" id, most skins are best off outputting this preferred id for best compatibility * - tooltiponly: This is set to true for some tabs in cases where the system * believes that the accesskey should not be added to the tab. * * @return array */ protected function buildContentNavigationUrls(OutputPage $out) { global $wgContLang, $wgLang, $wgUser, $wgRequest; global $wgDisableLangConversion; wfProfileIn(__METHOD__); $title = $this->getRelevantTitle(); // Display tabs for the relevant title rather than always the title itself $onPage = $title->equals($this->getTitle()); $content_navigation = array('namespaces' => array(), 'views' => array(), 'actions' => array(), 'variants' => array()); // parameters $action = $wgRequest->getVal('action', 'view'); $section = $wgRequest->getVal('section'); $userCanRead = $title->userCanRead(); $skname = $this->skinname; $preventActiveTabs = false; wfRunHooks('SkinTemplatePreventOtherActiveTabs', array(&$this, &$preventActiveTabs)); // Checks if page is some kind of content if ($title->canExist()) { // Gets page objects for the related namespaces $subjectPage = $title->getSubjectPage(); $talkPage = $title->getTalkPage(); // Determines if this is a talk page $isTalk = $title->isTalkPage(); // Generates XML IDs from namespace names $subjectId = $title->getNamespaceKey(''); if ($subjectId == 'main') { $talkId = 'talk'; } else { $talkId = "{$subjectId}_talk"; } // Adds namespace links $subjectMsg = array("nstab-{$subjectId}"); if ($subjectPage->isMainPage()) { array_unshift($subjectMsg, 'mainpage-nstab'); } $content_navigation['namespaces'][$subjectId] = $this->tabAction($subjectPage, $subjectMsg, !$isTalk && !$preventActiveTabs, '', $userCanRead); $content_navigation['namespaces'][$subjectId]['context'] = 'subject'; $content_navigation['namespaces'][$talkId] = $this->tabAction($talkPage, array("nstab-{$talkId}", 'talk'), $isTalk && !$preventActiveTabs, '', $userCanRead); $content_navigation['namespaces'][$talkId]['context'] = 'talk'; // Adds view view link if ($title->exists() && $userCanRead) { $content_navigation['views']['view'] = $this->tabAction($isTalk ? $talkPage : $subjectPage, array("{$skname}-view-view", 'view'), $onPage && ($action == 'view' || $action == 'purge'), '', true); $content_navigation['views']['view']['redundant'] = true; // signal to hide this from simple content_actions } wfProfileIn(__METHOD__ . '-edit'); // Checks if user can... if ($userCanRead && $title->quickUserCan('edit') && ($title->exists() || $title->quickUserCan('create'))) { // Builds CSS class for talk page links $isTalkClass = $isTalk ? ' istalk' : ''; // Determines if we're in edit mode $selected = $onPage && ($action == 'edit' || $action == 'submit') && $section != 'new'; $msgKey = $title->exists() || $title->getNamespace() == NS_MEDIAWIKI && $title->getDefaultMessageText() !== false ? "edit" : "create"; $content_navigation['views']['edit'] = array('class' => ($selected ? 'selected' : '') . $isTalkClass, 'text' => wfMessageFallback("{$skname}-view-{$msgKey}", $msgKey)->text(), 'href' => $title->getLocalURL($this->editUrlOptions()), 'primary' => true); // Checks if this is a current rev of talk page and we should show a new // section link if ($isTalk && $this->isRevisionCurrent() || $out->showNewSectionLink()) { // Checks if we should ever show a new section link if (!$out->forceHideNewSectionLink()) { // Adds new section link //$content_navigation['actions']['addsection'] $content_navigation['views']['addsection'] = array('class' => $section == 'new' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-addsection", 'addsection')->text(), 'href' => $title->getLocalURL('action=edit§ion=new')); } } // Checks if the page has some kind of viewable content } elseif ($title->hasSourceText() && $userCanRead) { // Adds view source view link $content_navigation['views']['viewsource'] = array('class' => $onPage && $action == 'edit' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-viewsource", 'viewsource')->text(), 'href' => $title->getLocalURL($this->editUrlOptions()), 'primary' => true); } wfProfileOut(__METHOD__ . '-edit'); wfProfileIn(__METHOD__ . '-live'); // Checks if the page exists if ($title->exists() && $userCanRead) { // Adds history view link $content_navigation['views']['history'] = array('class' => $onPage && $action == 'history' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-view-history", 'history_short')->text(), 'href' => $title->getLocalURL('action=history'), 'rel' => 'archives'); if ($wgUser->isAllowed('delete')) { $content_navigation['actions']['delete'] = array('class' => $onPage && $action == 'delete' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-delete", 'delete')->text(), 'href' => $title->getLocalURL('action=delete')); } if ($title->quickUserCan('move')) { $moveTitle = SpecialPage::getTitleFor('Movepage', $title->getPrefixedDBkey()); $content_navigation['actions']['move'] = array('class' => $this->getTitle()->isSpecial('Movepage') ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-move", 'move')->text(), 'href' => $moveTitle->getLocalURL()); } if ($title->getNamespace() !== NS_MEDIAWIKI && $wgUser->isAllowed('protect')) { $mode = !$title->isProtected() ? 'protect' : 'unprotect'; $content_navigation['actions'][$mode] = array('class' => $onPage && $action == $mode ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-{$mode}", $mode)->text(), 'href' => $title->getLocalURL("action={$mode}")); } } else { // article doesn't exist or is deleted if ($wgUser->isAllowed('deletedhistory')) { $n = $title->isDeleted(); if ($n) { $undelTitle = SpecialPage::getTitleFor('Undelete'); // If the user can't undelete but can view deleted history show them a "View .. deleted" tab instead $msgKey = $wgUser->isAllowed('undelete') ? 'undelete' : 'viewdeleted'; $content_navigation['actions']['undelete'] = array('class' => $this->getTitle()->isSpecial('Undelete') ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-{$msgKey}", "{$msgKey}_short")->params($wgLang->formatNum($n))->text(), 'href' => $undelTitle->getLocalURL(array('target' => $title->getPrefixedDBkey()))); } } if ($title->getNamespace() !== NS_MEDIAWIKI && $wgUser->isAllowed('protect')) { $mode = !$title->getRestrictions('create') ? 'protect' : 'unprotect'; $content_navigation['actions'][$mode] = array('class' => $onPage && $action == $mode ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-{$mode}", $mode)->text(), 'href' => $title->getLocalURL("action={$mode}")); } } wfProfileOut(__METHOD__ . '-live'); // Checks if the user is logged in if ($this->loggedin) { /** * The following actions use messages which, if made particular to * the any specific skins, would break the Ajax code which makes this * action happen entirely inline. Skin::makeGlobalVariablesScript * defines a set of messages in a javascript object - and these * messages are assumed to be global for all skins. Without making * a change to that procedure these messages will have to remain as * the global versions. */ $mode = $title->userIsWatching() ? 'unwatch' : 'watch'; $token = WatchAction::getWatchToken($title, $wgUser, $mode); $content_navigation['actions'][$mode] = array('class' => $onPage && ($action == 'watch' || $action == 'unwatch') ? 'selected' : false, 'text' => wfMsg($mode), 'href' => $title->getLocalURL(array('action' => $mode, 'token' => $token))); } wfRunHooks('SkinTemplateNavigation', array(&$this, &$content_navigation)); } else { // If it's not content, it's got to be a special page $content_navigation['namespaces']['special'] = array('class' => 'selected', 'text' => wfMsg('nstab-special'), 'href' => $wgRequest->getRequestURL(), 'context' => 'subject'); wfRunHooks('SkinTemplateNavigation::SpecialPage', array(&$this, &$content_navigation)); } // Gets list of language variants $variants = $wgContLang->getVariants(); // Checks that language conversion is enabled and variants exist if (!$wgDisableLangConversion && count($variants) > 1) { // Gets preferred variant $preferred = $wgContLang->getPreferredVariant(); // Loops over each variant foreach ($variants as $code) { // Gets variant name from language code $varname = $wgContLang->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('', $code)); } } // Equiv to SkinTemplateContentActions wfRunHooks('SkinTemplateNavigation::Universal', array(&$this, &$content_navigation)); // Setup xml ids and tooltip info foreach ($content_navigation as $section => &$links) { foreach ($links as $key => &$link) { $xmlID = $key; if (isset($link['context']) && $link['context'] == 'subject') { $xmlID = 'ca-nstab-' . $xmlID; } elseif (isset($link['context']) && $link['context'] == 'talk') { $xmlID = 'ca-talk'; } elseif ($section == "variants") { $xmlID = 'ca-varlang-' . $xmlID; } else { $xmlID = 'ca-' . $xmlID; } $link['id'] = $xmlID; } } # 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 # used for editing in Safari. if (in_array($action, array('edit', 'submit'))) { if (isset($content_navigation['views']['edit'])) { $content_navigation['views']['edit']['tooltiponly'] = true; } if (isset($content_navigation['actions']['watch'])) { $content_navigation['actions']['watch']['tooltiponly'] = true; } if (isset($content_navigation['actions']['unwatch'])) { $content_navigation['actions']['unwatch']['tooltiponly'] = true; } } wfProfileOut(__METHOD__); return $content_navigation; }