public function showDiffPage($diffOnly = false) { # Allow frames except in certain special cases $out = $this->getOutput(); $out->allowClickjacking(); $out->setRobotPolicy('noindex,nofollow'); if (!$this->loadRevisionData()) { $this->showMissingRevision(); return; } $user = $this->getUser(); $permErrors = $this->mNewPage->getUserPermissionsErrors('read', $user); if ($this->mOldPage) { # mOldPage might not be set, see below. $permErrors = wfMergeErrorArrays($permErrors, $this->mOldPage->getUserPermissionsErrors('read', $user)); } if (count($permErrors)) { throw new PermissionsError('read', $permErrors); } $rollback = ''; $query = array(); # Carry over 'diffonly' param via navigation links if ($diffOnly != $user->getBoolOption('diffonly')) { $query['diffonly'] = $diffOnly; } # Cascade unhide param in links for easy deletion browsing if ($this->unhide) { $query['unhide'] = 1; } # Check if one of the revisions is deleted/suppressed $deleted = $suppressed = false; $allowed = $this->mNewRev->userCan(Revision::DELETED_TEXT, $user); $revisionTools = array(); # mOldRev is false if the difference engine is called with a "vague" query for # a diff between a version V and its previous version V' AND the version V # is the first version of that article. In that case, V' does not exist. if ($this->mOldRev === false) { $out->setPageTitle($this->msg('difference-title', $this->mNewPage->getPrefixedText())); $samePage = true; $oldHeader = ''; } else { Hooks::run('DiffViewHeader', array($this, $this->mOldRev, $this->mNewRev)); if ($this->mNewPage->equals($this->mOldPage)) { $out->setPageTitle($this->msg('difference-title', $this->mNewPage->getPrefixedText())); $samePage = true; } else { $out->setPageTitle($this->msg('difference-title-multipage', $this->mOldPage->getPrefixedText(), $this->mNewPage->getPrefixedText())); $out->addSubtitle($this->msg('difference-multipage')); $samePage = false; } if ($samePage && $this->mNewPage->quickUserCan('edit', $user)) { if ($this->mNewRev->isCurrent() && $this->mNewPage->userCan('rollback', $user)) { $rollbackLink = Linker::generateRollback($this->mNewRev, $this->getContext()); if ($rollbackLink) { $out->preventClickjacking(); $rollback = '   ' . $rollbackLink; } } if (!$this->mOldRev->isDeleted(Revision::DELETED_TEXT) && !$this->mNewRev->isDeleted(Revision::DELETED_TEXT)) { $undoLink = Html::element('a', array('href' => $this->mNewPage->getLocalURL(array('action' => 'edit', 'undoafter' => $this->mOldid, 'undo' => $this->mNewid)), 'title' => Linker::titleAttrib('undo')), $this->msg('editundo')->text()); $revisionTools['mw-diff-undo'] = $undoLink; } } # Make "previous revision link" if ($samePage && $this->mOldRev->getPrevious()) { $prevlink = Linker::linkKnown($this->mOldPage, $this->msg('previousdiff')->escaped(), array('id' => 'differences-prevlink'), array('diff' => 'prev', 'oldid' => $this->mOldid) + $query); } else { $prevlink = ' '; } if ($this->mOldRev->isMinor()) { $oldminor = ChangesList::flag('minor'); } else { $oldminor = ''; } $ldel = $this->revisionDeleteLink($this->mOldRev); $oldRevisionHeader = $this->getRevisionHeader($this->mOldRev, 'complete'); $oldChangeTags = ChangeTags::formatSummaryRow($this->mOldTags, 'diff'); $oldHeader = '<div id="mw-diff-otitle1"><strong>' . $oldRevisionHeader . '</strong></div>' . '<div id="mw-diff-otitle2">' . Linker::revUserTools($this->mOldRev, !$this->unhide) . '</div>' . '<div id="mw-diff-otitle3">' . $oldminor . Linker::revComment($this->mOldRev, !$diffOnly, !$this->unhide) . $ldel . '</div>' . '<div id="mw-diff-otitle5">' . $oldChangeTags[0] . '</div>' . '<div id="mw-diff-otitle4">' . $prevlink . '</div>'; if ($this->mOldRev->isDeleted(Revision::DELETED_TEXT)) { $deleted = true; // old revisions text is hidden if ($this->mOldRev->isDeleted(Revision::DELETED_RESTRICTED)) { $suppressed = true; // also suppressed } } # Check if this user can see the revisions if (!$this->mOldRev->userCan(Revision::DELETED_TEXT, $user)) { $allowed = false; } } # Make "next revision link" # Skip next link on the top revision if ($samePage && !$this->mNewRev->isCurrent()) { $nextlink = Linker::linkKnown($this->mNewPage, $this->msg('nextdiff')->escaped(), array('id' => 'differences-nextlink'), array('diff' => 'next', 'oldid' => $this->mNewid) + $query); } else { $nextlink = ' '; } if ($this->mNewRev->isMinor()) { $newminor = ChangesList::flag('minor'); } else { $newminor = ''; } # Handle RevisionDelete links... $rdel = $this->revisionDeleteLink($this->mNewRev); # Allow extensions to define their own revision tools Hooks::run('DiffRevisionTools', array($this->mNewRev, &$revisionTools, $this->mOldRev, $user)); $formattedRevisionTools = array(); // Put each one in parentheses (poor man's button) foreach ($revisionTools as $key => $tool) { $toolClass = is_string($key) ? $key : 'mw-diff-tool'; $element = Html::rawElement('span', array('class' => $toolClass), $this->msg('parentheses')->rawParams($tool)->escaped()); $formattedRevisionTools[] = $element; } $newRevisionHeader = $this->getRevisionHeader($this->mNewRev, 'complete') . ' ' . implode(' ', $formattedRevisionTools); $newChangeTags = ChangeTags::formatSummaryRow($this->mNewTags, 'diff'); $newHeader = '<div id="mw-diff-ntitle1"><strong>' . $newRevisionHeader . '</strong></div>' . '<div id="mw-diff-ntitle2">' . Linker::revUserTools($this->mNewRev, !$this->unhide) . " {$rollback}</div>" . '<div id="mw-diff-ntitle3">' . $newminor . Linker::revComment($this->mNewRev, !$diffOnly, !$this->unhide) . $rdel . '</div>' . '<div id="mw-diff-ntitle5">' . $newChangeTags[0] . '</div>' . '<div id="mw-diff-ntitle4">' . $nextlink . $this->markPatrolledLink() . '</div>'; if ($this->mNewRev->isDeleted(Revision::DELETED_TEXT)) { $deleted = true; // new revisions text is hidden if ($this->mNewRev->isDeleted(Revision::DELETED_RESTRICTED)) { $suppressed = true; // also suppressed } } # If the diff cannot be shown due to a deleted revision, then output # the diff header and links to unhide (if available)... if ($deleted && (!$this->unhide || !$allowed)) { $this->showDiffStyle(); $multi = $this->getMultiNotice(); $out->addHTML($this->addHeader('', $oldHeader, $newHeader, $multi)); if (!$allowed) { $msg = $suppressed ? 'rev-suppressed-no-diff' : 'rev-deleted-no-diff'; # Give explanation for why revision is not visible $out->wrapWikiMsg("<div id='mw-{$msg}' class='mw-warning plainlinks'>\n\$1\n</div>\n", array($msg)); } else { # Give explanation and add a link to view the diff... $query = $this->getRequest()->appendQueryValue('unhide', '1'); $link = $this->getTitle()->getFullURL($query); $msg = $suppressed ? 'rev-suppressed-unhide-diff' : 'rev-deleted-unhide-diff'; $out->wrapWikiMsg("<div id='mw-{$msg}' class='mw-warning plainlinks'>\n\$1\n</div>\n", array($msg, $link)); } # Otherwise, output a regular diff... } else { # Add deletion notice if the user is viewing deleted content $notice = ''; if ($deleted) { $msg = $suppressed ? 'rev-suppressed-diff-view' : 'rev-deleted-diff-view'; $notice = "<div id='mw-{$msg}' class='mw-warning plainlinks'>\n" . $this->msg($msg)->parse() . "</div>\n"; } $this->showDiff($oldHeader, $newHeader, $notice); if (!$diffOnly) { $this->renderNewRevision(); } } }
function showDiffPage($diffOnly = false) { wfProfileIn(__METHOD__); # Allow frames except in certain special cases $out = $this->getOutput(); $out->allowClickjacking(); $out->setRobotPolicy('noindex,nofollow'); if (!$this->loadRevisionData()) { $this->showMissingRevision(); wfProfileOut(__METHOD__); return; } $user = $this->getUser(); $permErrors = $this->mNewPage->getUserPermissionsErrors('read', $user); if ($this->mOldPage) { # mOldPage might not be set, see below. $permErrors = wfMergeErrorArrays($permErrors, $this->mOldPage->getUserPermissionsErrors('read', $user)); } if (count($permErrors)) { wfProfileOut(__METHOD__); throw new PermissionsError('read', $permErrors); } # If external diffs are enabled both globally and for the user, # we'll use the application/x-external-editor interface to call # an external diff tool like kompare, kdiff3, etc. if (ExternalEdit::useExternalEngine($this->getContext(), 'diff')) { //TODO: come up with a good solution for non-text content here. // at least, the content format needs to be passed to the client somehow. // Currently, action=raw will just fail for non-text content. $urls = array('File' => array('Extension' => 'wiki', 'URL' => $this->mNewPage->getCanonicalURL(array('action' => 'raw', 'oldid' => $this->mOldid))), 'File2' => array('Extension' => 'wiki', 'URL' => $this->mNewPage->getCanonicalURL(array('action' => 'raw', 'oldid' => $this->mNewid)))); $externalEditor = new ExternalEdit($this->getContext(), $urls); $externalEditor->execute(); wfProfileOut(__METHOD__); return; } $rollback = ''; $undoLink = ''; $query = array(); # Carry over 'diffonly' param via navigation links if ($diffOnly != $user->getBoolOption('diffonly')) { $query['diffonly'] = $diffOnly; } # Cascade unhide param in links for easy deletion browsing if ($this->unhide) { $query['unhide'] = 1; } # Check if one of the revisions is deleted/suppressed $deleted = $suppressed = false; $allowed = $this->mNewRev->userCan(Revision::DELETED_TEXT, $user); # mOldRev is false if the difference engine is called with a "vague" query for # a diff between a version V and its previous version V' AND the version V # is the first version of that article. In that case, V' does not exist. if ($this->mOldRev === false) { $out->setPageTitle($this->msg('difference-title', $this->mNewPage->getPrefixedText())); $samePage = true; $oldHeader = ''; } else { wfRunHooks('DiffViewHeader', array($this, $this->mOldRev, $this->mNewRev)); $sk = $this->getSkin(); if (method_exists($sk, 'suppressQuickbar')) { $sk->suppressQuickbar(); } if ($this->mNewPage->equals($this->mOldPage)) { $out->setPageTitle($this->msg('difference-title', $this->mNewPage->getPrefixedText())); $samePage = true; } else { $out->setPageTitle($this->msg('difference-title-multipage', $this->mOldPage->getPrefixedText(), $this->mNewPage->getPrefixedText())); $out->addSubtitle($this->msg('difference-multipage')); $samePage = false; } if ($samePage && $this->mNewPage->quickUserCan('edit', $user)) { if ($this->mNewRev->isCurrent() && $this->mNewPage->userCan('rollback', $user)) { $out->preventClickjacking(); $rollback = '   ' . Linker::generateRollback($this->mNewRev, $this->getContext()); } if (!$this->mOldRev->isDeleted(Revision::DELETED_TEXT) && !$this->mNewRev->isDeleted(Revision::DELETED_TEXT)) { $undoLink = ' ' . $this->msg('parentheses')->rawParams(Html::element('a', array('href' => $this->mNewPage->getLocalUrl(array('action' => 'edit', 'undoafter' => $this->mOldid, 'undo' => $this->mNewid)), 'title' => Linker::titleAttrib('undo')), $this->msg('editundo')->text()))->escaped(); } } # Make "previous revision link" if ($samePage && $this->mOldRev->getPrevious()) { $prevlink = Linker::linkKnown($this->mOldPage, $this->msg('previousdiff')->escaped(), array('id' => 'differences-prevlink'), array('diff' => 'prev', 'oldid' => $this->mOldid) + $query); } else { $prevlink = ' '; } if ($this->mOldRev->isMinor()) { $oldminor = ChangesList::flag('minor'); } else { $oldminor = ''; } $ldel = $this->revisionDeleteLink($this->mOldRev); $oldRevisionHeader = $this->getRevisionHeader($this->mOldRev, 'complete'); $oldHeader = '<div id="mw-diff-otitle1"><strong>' . $oldRevisionHeader . '</strong></div>' . '<div id="mw-diff-otitle2">' . Linker::revUserTools($this->mOldRev, !$this->unhide) . '</div>' . '<div id="mw-diff-otitle3">' . $oldminor . Linker::revComment($this->mOldRev, !$diffOnly, !$this->unhide) . $ldel . '</div>' . '<div id="mw-diff-otitle4">' . $prevlink . '</div>'; if ($this->mOldRev->isDeleted(Revision::DELETED_TEXT)) { $deleted = true; // old revisions text is hidden if ($this->mOldRev->isDeleted(Revision::DELETED_RESTRICTED)) { $suppressed = true; // also suppressed } } # Check if this user can see the revisions if (!$this->mOldRev->userCan(Revision::DELETED_TEXT, $user)) { $allowed = false; } } # Make "next revision link" # Skip next link on the top revision if ($samePage && !$this->mNewRev->isCurrent()) { $nextlink = Linker::linkKnown($this->mNewPage, $this->msg('nextdiff')->escaped(), array('id' => 'differences-nextlink'), array('diff' => 'next', 'oldid' => $this->mNewid) + $query); } else { $nextlink = ' '; } if ($this->mNewRev->isMinor()) { $newminor = ChangesList::flag('minor'); } else { $newminor = ''; } # Handle RevisionDelete links... $rdel = $this->revisionDeleteLink($this->mNewRev); $newRevisionHeader = $this->getRevisionHeader($this->mNewRev, 'complete') . $undoLink; $newHeader = '<div id="mw-diff-ntitle1"><strong>' . $newRevisionHeader . '</strong></div>' . '<div id="mw-diff-ntitle2">' . Linker::revUserTools($this->mNewRev, !$this->unhide) . " {$rollback}</div>" . '<div id="mw-diff-ntitle3">' . $newminor . Linker::revComment($this->mNewRev, !$diffOnly, !$this->unhide) . $rdel . '</div>' . '<div id="mw-diff-ntitle4">' . $nextlink . $this->markPatrolledLink() . '</div>'; if ($this->mNewRev->isDeleted(Revision::DELETED_TEXT)) { $deleted = true; // new revisions text is hidden if ($this->mNewRev->isDeleted(Revision::DELETED_RESTRICTED)) { $suppressed = true; } // also suppressed } # If the diff cannot be shown due to a deleted revision, then output # the diff header and links to unhide (if available)... if ($deleted && (!$this->unhide || !$allowed)) { $this->showDiffStyle(); $multi = $this->getMultiNotice(); $out->addHTML($this->addHeader('', $oldHeader, $newHeader, $multi)); if (!$allowed) { $msg = $suppressed ? 'rev-suppressed-no-diff' : 'rev-deleted-no-diff'; # Give explanation for why revision is not visible $out->wrapWikiMsg("<div id='mw-{$msg}' class='mw-warning plainlinks'>\n\$1\n</div>\n", array($msg)); } else { # Give explanation and add a link to view the diff... $link = $this->getTitle()->getFullUrl($this->getRequest()->appendQueryValue('unhide', '1', true)); $msg = $suppressed ? 'rev-suppressed-unhide-diff' : 'rev-deleted-unhide-diff'; $out->wrapWikiMsg("<div id='mw-{$msg}' class='mw-warning plainlinks'>\n\$1\n</div>\n", array($msg, $link)); } # Otherwise, output a regular diff... } else { # Add deletion notice if the user is viewing deleted content $notice = ''; if ($deleted) { $msg = $suppressed ? 'rev-suppressed-diff-view' : 'rev-deleted-diff-view'; $notice = "<div id='mw-{$msg}' class='mw-warning plainlinks'>\n" . $this->msg($msg)->parse() . "</div>\n"; } $this->showDiff($oldHeader, $newHeader, $notice); if (!$diffOnly) { $this->renderNewRevision(); } } wfProfileOut(__METHOD__); }
/** * 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 string $key Usually a key from the list you are generating this * link from. * @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 * that name will be used, and if neither of those are set the $key will be * used as a message name. * * If a "href" key is not present makeLink will just output htmlescaped text. * The "href", "id", "class", "rel", and "type" keys are used as attributes * for the link if present. * * If an "id" or "single-id" (if you don't want the actual id to be output * 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 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 * optionally an 'attributes' key. If you only have one element you don't * need to wrap it in another array. eg: To use <a><span>...</span></a> * in all links use array( 'text-wrapper' => array( 'tag' => 'span' ) ) * for your options. * - 'link-class' key can be used to specify additional classes to apply * to all links. * - 'link-fallback' can be used to specify a tag to use instead of "<a>" * if there is no link. eg: If you specify 'link-fallback' => 'span' than * any non-link will output a "<span>" instead of just text. * * @return string */ function makeLink($key, $item, $options = []) { if (isset($item['text'])) { $text = $item['text']; } else { $text = $this->translator->translate(isset($item['msg']) ? $item['msg'] : $key); } $html = htmlspecialchars($text); if (isset($options['text-wrapper'])) { $wrapper = $options['text-wrapper']; if (isset($wrapper['tag'])) { $wrapper = [$wrapper]; } while (count($wrapper) > 0) { $element = array_pop($wrapper); $html = Html::rawElement($element['tag'], isset($element['attributes']) ? $element['attributes'] : null, $html); } } if (isset($item['href']) || isset($options['link-fallback'])) { $attrs = $item; foreach (['single-id', 'text', 'msg', 'tooltiponly', 'context', 'primary', 'tooltip-params'] as $k) { unset($attrs[$k]); } if (isset($item['id']) && !isset($item['single-id'])) { $item['single-id'] = $item['id']; } $tooltipParams = []; if (isset($item['tooltip-params'])) { $tooltipParams = $item['tooltip-params']; } if (isset($item['single-id'])) { if (isset($item['tooltiponly']) && $item['tooltiponly']) { $title = Linker::titleAttrib($item['single-id'], null, $tooltipParams); if ($title !== false) { $attrs['title'] = $title; } } else { $tip = Linker::tooltipAndAccesskeyAttribs($item['single-id'], $tooltipParams); if (isset($tip['title']) && $tip['title'] !== false) { $attrs['title'] = $tip['title']; } if (isset($tip['accesskey']) && $tip['accesskey'] !== false) { $attrs['accesskey'] = $tip['accesskey']; } } } if (isset($options['link-class'])) { if (isset($attrs['class'])) { $attrs['class'] .= " {$options['link-class']}"; } else { $attrs['class'] = $options['link-class']; } } $html = Html::rawElement(isset($attrs['href']) ? 'a' : $options['link-fallback'], $attrs, $html); } return $html; }
public function titleAttrib($name, $options = null, array $msgParams = []) { return Linker::titleAttrib($name, $options, $msgParams); }
function customBox($bar, $cont) { $portletAttribs = array('class' => 'generated-sidebar portlet', 'id' => Sanitizer::escapeId("p-{$bar}")); $tooltip = Linker::titleAttrib("p-{$bar}"); if ($tooltip !== false) { $portletAttribs['title'] = $tooltip; } echo ' ' . Html::openElement('div', $portletAttribs); ?> <h2><?php $msg = wfMessage($bar); echo htmlspecialchars($msg->exists() ? $msg->text() : $bar); ?> </h2> <div class='pBody'> <?php if (is_array($cont)) { ?> <ul> <?php foreach ($cont as $key => $val) { ?> <?php echo $this->makeListItem($key, $val); ?> <?php } ?> </ul> <?php } else { # allow raw HTML block to be defined by extensions print $cont; } ?> </div> </div> <?php }
/** * Returns an array of html code of the following checkboxes: * minor and watch * * @param $tabindex Current tabindex * @param $checked Array of checkbox => bool, where bool indicates the checked * status of the checkbox * * @return array */ public function getCheckboxes(&$tabindex, $checked) { global $wgUser; $checkboxes = array(); // don't show the minor edit checkbox if it's a new page or section if (!$this->isNew) { $checkboxes['minor'] = ''; $minorLabel = wfMsgExt('minoredit', array('parseinline')); if ($wgUser->isAllowed('minoredit')) { $attribs = array('tabindex' => ++$tabindex, 'accesskey' => wfMsg('accesskey-minoredit'), 'id' => 'wpMinoredit'); $checkboxes['minor'] = Xml::check('wpMinoredit', $checked['minor'], $attribs) . " <label for='wpMinoredit' id='mw-editpage-minoredit'" . Xml::expandAttributes(array('title' => Linker::titleAttrib('minoredit', 'withaccess'))) . ">{$minorLabel}</label>"; } } $watchLabel = wfMsgExt('watchthis', array('parseinline')); $checkboxes['watch'] = ''; if ($wgUser->isLoggedIn()) { $attribs = array('tabindex' => ++$tabindex, 'accesskey' => wfMsg('accesskey-watch'), 'id' => 'wpWatchthis'); $checkboxes['watch'] = Xml::check('wpWatchthis', $checked['watch'], $attribs) . " <label for='wpWatchthis' id='mw-editpage-watch'" . Xml::expandAttributes(array('title' => Linker::titleAttrib('watch', 'withaccess'))) . ">{$watchLabel}</label>"; } wfRunHooks('EditPageBeforeEditChecks', array(&$this, &$checkboxes, &$tabindex)); return $checkboxes; }
/** * Returns an array of html code of the following checkboxes: * minor and watch * * @param int $tabindex Current tabindex * @param array $checked Array of checkbox => bool, where bool indicates the checked * status of the checkbox * * @return array */ public function getCheckboxes(&$tabindex, $checked) { global $wgUser, $wgUseMediaWikiUIEverywhere; $checkboxes = array(); // don't show the minor edit checkbox if it's a new page or section if (!$this->isNew) { $checkboxes['minor'] = ''; $minorLabel = wfMessage('minoredit')->parse(); if ($wgUser->isAllowed('minoredit')) { $attribs = array('tabindex' => ++$tabindex, 'accesskey' => wfMessage('accesskey-minoredit')->text(), 'id' => 'wpMinoredit'); $minorEditHtml = Xml::check('wpMinoredit', $checked['minor'], $attribs) . " <label for='wpMinoredit' id='mw-editpage-minoredit'" . Xml::expandAttributes(array('title' => Linker::titleAttrib('minoredit', 'withaccess'))) . ">{$minorLabel}</label>"; if ($wgUseMediaWikiUIEverywhere) { $checkboxes['minor'] = Html::openElement('div', array('class' => 'mw-ui-checkbox')) . $minorEditHtml . Html::closeElement('div'); } else { $checkboxes['minor'] = $minorEditHtml; } } } $watchLabel = wfMessage('watchthis')->parse(); $checkboxes['watch'] = ''; if ($wgUser->isLoggedIn()) { $attribs = array('tabindex' => ++$tabindex, 'accesskey' => wfMessage('accesskey-watch')->text(), 'id' => 'wpWatchthis'); $watchThisHtml = Xml::check('wpWatchthis', $checked['watch'], $attribs) . " <label for='wpWatchthis' id='mw-editpage-watch'" . Xml::expandAttributes(array('title' => Linker::titleAttrib('watch', 'withaccess'))) . ">{$watchLabel}</label>"; if ($wgUseMediaWikiUIEverywhere) { $checkboxes['watch'] = Html::openElement('div', array('class' => 'mw-ui-checkbox')) . $watchThisHtml . Html::closeElement('div'); } else { $checkboxes['watch'] = $watchThisHtml; } } wfRunHooks('EditPageBeforeEditChecks', array(&$this, &$checkboxes, &$tabindex)); return $checkboxes; }
/** * Produce HTML for a link * * This is a slightly adapted copy of the makeLink function in SkinTemplate.php * -> some of the changed parts are marked by comments // * * @param $item array * @param $options array */ static function makeLink($item, $options = array()) { // nested links? if (isset($item['links'])) { $item = $item['links'][0]; } if (isset($item['text'])) { $text = $item['text']; } else { // $text = $this->translator->translate( isset( $item['msg'] ) ? $item['msg'] : $key ); $text = ''; } $html = htmlspecialchars($text); // set raw html if (isset($item['html'])) { $html = $item['html']; } // set icons for individual buttons (used by some navigational elements) if (isset($item['icon'])) { $html = '<span class="glyphicon glyphicon-' . $item['icon'] . '"></span> ' . $html; } if (isset($options['text-wrapper'])) { $wrapper = $options['text-wrapper']; if (isset($wrapper['tag'])) { $wrapper = array($wrapper); } while (count($wrapper) > 0) { $element = array_pop($wrapper); $html = Html::rawElement($element['tag'], isset($element['attributes']) ? $element['attributes'] : null, $html); } } 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', 'href_implicit', 'items', 'icon', 'html') as $k) { unset($attrs[$k]); } if (isset($item['id']) && !isset($item['single-id'])) { $item['single-id'] = $item['id']; } if (isset($item['single-id'])) { if (isset($item['tooltiponly']) && $item['tooltiponly']) { $title = Linker::titleAttrib($item['single-id']); if ($title !== false) { $attrs['title'] = $title; } } else { $tip = Linker::tooltipAndAccesskeyAttribs($item['single-id']); if (isset($tip['title']) && $tip['title'] !== false) { $attrs['title'] = $tip['title']; } if (isset($tip['accesskey']) && $tip['accesskey'] !== false) { $attrs['accesskey'] = $tip['accesskey']; } } } if (isset($options['link-class'])) { if (isset($attrs['class'])) { $attrs['class'] .= " {$options['link-class']}"; } else { $attrs['class'] = $options['link-class']; } } $html = Html::rawElement(isset($attrs['href']) ? 'a' : $options['link-fallback'], $attrs, $html); } return $html; }
public function showForm($err = null) { $out = $this->getOutput(); $form = $this->form; // convenience $title = $this->form->getPage(); $oldConfig = $form->getOldConfig(); $s = ''; // form HTML string # Add any error messages if ("" != $err) { $out->setSubtitle(wfMsgHtml('formerror')); $out->addHTML("<p class='error'>{$err}</p>\n"); } # Add header text if (!$form->isAllowed()) { $s .= wfMsgExt('stabilization-perm', 'parse', $title->getPrefixedText()); } else { $s .= wfMsgExt('stabilization-text', 'parse', $title->getPrefixedText()); } # Borrow some protection messages for dropdowns $reasonDropDown = Xml::listDropDown('wpReasonSelection', wfMsgForContent('protect-dropdown'), wfMsgForContent('protect-otherreason-op'), $form->getReasonSelection(), 'mwStabilize-reason', 4); $scExpiryOptions = wfMsgForContent('protect-expiry-options'); $showProtectOptions = $scExpiryOptions !== '-' && $form->isAllowed(); $dropdownOptions = array(); // array of <label,value> # Add the current expiry as a dropdown option if ($oldConfig['expiry'] && $oldConfig['expiry'] != Block::infinity()) { $timestamp = $this->getLang()->timeanddate($oldConfig['expiry']); $d = $this->getLang()->date($oldConfig['expiry']); $t = $this->getLang()->time($oldConfig['expiry']); $dropdownOptions[] = array(wfMsg('protect-existing-expiry', $timestamp, $d, $t), 'existing'); } # Add "other time" expiry dropdown option $dropdownOptions[] = array(wfMsg('protect-othertime-op'), 'othertime'); # Add custom expiry dropdown options (from MediaWiki message) foreach (explode(',', $scExpiryOptions) as $option) { if (strpos($option, ":") === false) { $show = $value = $option; } else { list($show, $value) = explode(":", $option); } $dropdownOptions[] = array($show, $value); } # Actually build the options HTML... $expiryFormOptions = ''; foreach ($dropdownOptions as $option) { $show = htmlspecialchars($option[0]); $value = htmlspecialchars($option[1]); $expiryFormOptions .= Xml::option($show, $value, $form->getExpirySelection() === $value) . "\n"; } # Build up the form... $s .= Xml::openElement('form', array('name' => 'stabilization', 'action' => $this->getTitle()->getLocalUrl(), 'method' => 'post')); # Add stable version override and selection options $s .= Xml::fieldset(wfMsg('stabilization-def'), false) . "\n" . Xml::radioLabel(wfMsg('stabilization-def1'), 'wpStableconfig-override', 1, 'default-stable', 1 == $form->getOverride(), $this->disabledAttr()) . '<br />' . "\n" . Xml::radioLabel(wfMsg('stabilization-def2'), 'wpStableconfig-override', 0, 'default-current', 0 == $form->getOverride(), $this->disabledAttr()) . "\n" . Xml::closeElement('fieldset'); # Add autoreview restriction select $s .= Xml::fieldset(wfMsg('stabilization-restrict'), false) . $this->buildSelector($form->getAutoreview()) . Xml::closeElement('fieldset') . Xml::fieldset(wfMsg('stabilization-leg'), false) . Xml::openElement('table'); # Add expiry dropdown to form... if ($showProtectOptions && $form->isAllowed()) { $s .= "\n\t\t\t\t<tr>\n\t\t\t\t\t<td class='mw-label'>" . Xml::label(wfMsg('stabilization-expiry'), 'mwStabilizeExpirySelection') . "</td>\n\t\t\t\t\t<td class='mw-input'>" . Xml::tags('select', array('id' => 'mwStabilizeExpirySelection', 'name' => 'wpExpirySelection', 'onchange' => 'onFRChangeExpiryDropdown()') + $this->disabledAttr(), $expiryFormOptions) . "</td>\n\t\t\t\t</tr>"; } # Add custom expiry field to form... $attribs = array('id' => "mwStabilizeExpiryOther", 'onkeyup' => 'onFRChangeExpiryField()') + $this->disabledAttr(); $s .= "\n\t\t\t<tr>\n\t\t\t\t<td class='mw-label'>" . Xml::label(wfMsg('stabilization-othertime'), 'mwStabilizeExpiryOther') . '</td> <td class="mw-input">' . Xml::input("mwStabilize-expiry", 50, $form->getExpiryCustom(), $attribs) . '</td> </tr>'; # Add comment input and submit button if ($form->isAllowed()) { $watchLabel = wfMsgExt('watchthis', 'parseinline'); $watchAttribs = array('accesskey' => wfMsg('accesskey-watch'), 'id' => 'wpWatchthis'); $watchChecked = $this->getUser()->getOption('watchdefault') || $title->userIsWatching(); $reviewLabel = wfMsgExt('stabilization-review', 'parseinline'); $s .= ' <tr> <td class="mw-label">' . xml::label(wfMsg('stabilization-comment'), 'wpReasonSelection') . '</td> <td class="mw-input">' . $reasonDropDown . '</td> </tr> <tr> <td class="mw-label">' . Xml::label(wfMsg('stabilization-otherreason'), 'wpReason') . '</td> <td class="mw-input">' . Xml::input('wpReason', 70, $form->getReasonExtra(), array('id' => 'wpReason', 'maxlength' => 255)) . '</td> </tr> <tr> <td></td> <td class="mw-input">' . Xml::check('wpReviewthis', $form->getReviewThis(), array('id' => 'wpReviewthis')) . "<label for='wpReviewthis'>{$reviewLabel}</label>" . '     ' . Xml::check('wpWatchthis', $watchChecked, $watchAttribs) . " <label for='wpWatchthis' " . Xml::expandAttributes(array('title' => Linker::titleAttrib('watch', 'withaccess'))) . ">{$watchLabel}</label>" . '</td> </tr> <tr> <td></td> <td class="mw-submit">' . Xml::submitButton(wfMsg('stabilization-submit')) . '</td> </tr>' . Xml::closeElement('table') . Html::hidden('title', $this->getTitle()->getPrefixedDBKey()) . Html::hidden('page', $title->getPrefixedText()) . Html::hidden('wpEditToken', $this->getUser()->editToken()); } else { $s .= Xml::closeElement('table'); } $s .= Xml::closeElement('fieldset') . Xml::closeElement('form'); $out->addHTML($s); $out->addHTML(Xml::element('h2', null, htmlspecialchars(LogPage::logName('stable')))); LogEventsList::showLogExtract($out, 'stable', $title->getPrefixedText(), '', array('lim' => 25)); # Add some javascript for expiry dropdowns $out->addScript("<script type=\"text/javascript\">\n\t\t\t\tfunction onFRChangeExpiryDropdown() {\n\t\t\t\t\tdocument.getElementById('mwStabilizeExpiryOther').value = '';\n\t\t\t\t}\n\t\t\t\tfunction onFRChangeExpiryField() {\n\t\t\t\t\tdocument.getElementById('mwStabilizeExpirySelection').value = 'othertime';\n\t\t\t\t}\n\t\t\t</script>"); }
/** * Makes links for navigation lists. * * Modified to add a <span> around <a> content in navigation lists; everything else is * basically the same as in BaseTemplate, just with extra stuff removed. * * Can't just use the original's options['wrapper'] because it's a piece of crap and spews * infinite errors on the page. */ function makeLink($key, $item, $options = array()) { if (isset($item['text'])) { $text = $item['text']; } else { $text = $this->translator->translate(isset($item['msg']) ? $item['msg'] : $key); } $html = htmlspecialchars($text); $html = '<span>' . $html . '</span>'; if (isset($item['href'])) { $attrs = $item; foreach (array('single-id', 'text', 'msg', 'tooltiponly', 'context', 'primary') as $k) { unset($attrs[$k]); } if (isset($item['id']) && !isset($item['single-id'])) { $item['single-id'] = $item['id']; } if (isset($item['single-id'])) { if (isset($item['tooltiponly']) && $item['tooltiponly']) { $title = Linker::titleAttrib($item['single-id']); if ($title !== false) { $attrs['title'] = $title; } } else { $tip = Linker::tooltipAndAccesskeyAttribs($item['single-id']); if (isset($tip['title']) && $tip['title'] !== false) { $attrs['title'] = $tip['title']; } if (isset($tip['accesskey']) && $tip['accesskey'] !== false) { $attrs['accesskey'] = $tip['accesskey']; } } } $html = Html::rawElement('a', $attrs, $html); } return $html; }