Ejemplo n.º 1
0
    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);
    }
Ejemplo n.º 2
0
 /**
  * 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();
 }
Ejemplo n.º 3
0
 /**
  * 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();
 }
Ejemplo n.º 4
0
 /**
  * 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&section=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;
 }
Ejemplo n.º 5
0
 /**
  * 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&section=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;
 }